Найденные решения, в том числе и на хабре(здесь и здесь), не подошли в основном по двум причинам: нет возможности сохранения в БД и медленная скорость работы. Пришлось собрать свой велосипед — grbackup, который
grbackup -e fake@gmail.com -p password -ba -o mongodb://localhost:27017 -w 20
за 20 минут сохранил 328250 записей из 102 подписок в локальную БД MongoDB.
Основные возможности:
- сохранение всех записей, которые можно получить при помощи Google Reader API
- сохранение записей в различные хранилища
- использование формата идентичного тому, что отдает Google Reader через API
- параллельное получение/сохранение записей
- расширяемость: возможность добавить новый вид хранилища
Доступные виды хранилищ определяются расширениями(плагинами) и задаются при помощи опции (-o, —output) вида type:uri.
На момент написания статьи доступны следующие расширения:
- simple: вывод в терминал (используется только в режиме просмотра)
- json: запись в json-файл (json:/path/to/file.json)
- mongodb: запись в MongoDB (mongodb://[username:password@]hostN[:portN]]][/[db][?opts]])
- redis: запись в Redis (redis://username:password@host[:port]/dbindex)
Работоспособность проверена на Ubuntu(64) и Win7(64).
Книгу предложений и замечаний можно найти здесь.
Ниже находится подробное описание утилиты.
Установка
pip install grbackup
или
easy_install grbackup
или
pip install git+git://github.com/wistful/grbackup.git
Опций командной строки
Авторизация
- -e, —email: почтовый адрес используемый для входа в Google Reader
- -p, —password: пароль
grbackup поддерживает два действия:
- просмотр:-l, —list
- сохранение: -b, —backup
Действие можно выполнить над одним из четырех типов данных:
- подписки; -s, —subscriptions
- записи: -t, —topics
- отмеченные записи: -x, —starred
- все предыдущие вместе взятые: -a, —all
Дополнительные опции:
- -w, —workers: максимальное количество одновременно обрабатываемых подписок (по умолчанию 1)
- -o, —output: URI показывающий куда сохранять записи
- -n, —count: количество записей получаемых от Google Reader за один запрос (по умолчанию 200). Слишком большое число может привести к получению данных более мелкими порциями (ох уж этот google).
Все опции, а также описание плагинов можно просмотреть используя опцию -h, —help:
grbackup -h
Usage: grbackup [options] [args] Examples: list subscriptions: grbackup -e email@gmail.com -p password -ls list topics: grbackup -e email@gmail.com -p password -lt http://feed.com list starred: grbackup -e email@gmail.com -p password -lx list all items: grbackup -e email@gmail.com -p password -la backup subscriptions: grbackup -e email@gmail.com -p password -bs -o json:/tmp/subscriptions.json backup topics: grbackup -e email@gmail.com -p password -bt http://myfeed.com -o json:/tmp/myfeed.json backup starred into MongoDB: grbackup -e email@gmail.com -p password -bx -o mongodb://localhost:27017 backup all items into Redis: grbackup -e email@gmail.com -p password -ba -o redis://localhost:6379/3 Available plugins: mongodb: save items into MongoDB output scheme: mongodb://[username:password@]hostN[:portN]]][/[db][?opts]] output examples: mongodb://localhost:27017 mongodb://user:pwd@localhost,localhost:27018/?replicaSet=grbackup json: save items into file output scheme: json:/path/to/file.json output examples: json:/home/grbackup/grbackup.json json:/tmp/grbackup/grbackup.json redis: save items into Redis output scheme: redis://username:password@host[:port]/dbindex output examples: redis://localhost:6379/3 redis://user:password@localhost:6379/0 Options: Auth Options: -e EMAIL, --email=EMAIL gmail account -p PWD, --password=PWD account password Command Options: -b, --backup backup items -l, --list list items Scope Options: -a, --all processing all items -s, --subscriptions processing subscriptions only -t, --topics processing topics only -x, --starred processing starred topics only MongoDB Options: --mongodb-db=MONGODB_DB the name of the database[default: greader] --mongodb-scol=MONGODB_SUBSCRIPTIONS collection name for subscriptions[default: subscriptions] --mongodb-tcol=MONGODB_TOPICS collection name for topics[default: topics] --mongodb-tstar=MONGODB_STARRED collection name for starred items[default: starred] --mongodb-w=MONGODB_W <int> Write operations will block until they have been replicated to the specified number [default: 1] --mongodb-j block until write operations have been committed to the journal [default: False] Redis Options: --redis-scol-prefix=REDIS_SUBS subscriptions key prefix[default: subscription] --redis-tcol-prefix=REDIS_TOPICS topics key prefix[default: topic] --redis-xcol-prefix=REDIS_STARRED starred key prefix[default: starred] Other Options: -w WORKERS, --workers=WORKERS number of workers [default: 1] -o OUTPUT, --output=OUTPUT output uri -n COUNT, --count=COUNT the number of topics that can be read at once [default: 200] -c CODING, --coding=CODING output coding [default: utf8] -v, --verbose verbose output -h, --help
Использование
список подписок:
grbackup -e email@gmail.com -p password -ls
список записей конкретной подписки:
grbackup -e email@gmail.com -p password -lt http://habrahabr.ru/rss/hub/python/
список всех отмеченных записей:
grbackup -e email@gmail.com -p password -lx
список всех записей:
grbackup -e email@gmail.com -p password -la
сохранение подписок в json-файл:
grbackup -e email@gmail.com -p password -bs -o json:/tmp/subscriptions.json
сохранение всех записей конкретной подписки в json-файл:
grbackup -e email@gmail.com -p password -bt http://habrahabr.ru/rss/hub/python/ -o json:/tmp/python.json
сохранение всех отмеченных записей в MongoDB:
grbackup -e email@gmail.com -p password -bx -o mongodb://localhost:27017
сохранение всех записей в Redis с использованием 20 потоков:
grbackup -e email@gmail.com -p password -ba -o redis://localhost:6379/3 -w 20
Плагины
JSON
Общий формат URI: json:/path/to/file.json
Поддержка многопоточности: да
Пример использования:
grbackup -e email@gmail.com -p password -ba -o json:/home/grbackup/grbackup.json
Записи сохраняются в отдельный файл в виде списка объектов.
Существует три типа объектов:
- подписки: {«type»: «subscription», «value»: subscription}
- отмеченные записи: {«type»: «starred», «value»: record}
- обычная запись: {«type»: «topic», «subscription»: subscription_url, «value»: record}
MongoDB
Общий формат URI: mongodb://[username:password@]hostN[:portN]]][/[db][?opts]]
Поддержка многопоточности: да
Пример использования:
grbackup -e email@gmail.com -p password -ba -o mongodb://localhost:27017 -w 20
Записи раскладываются по трем коллекциям: subscriptions, topics, starred.
Имена коллекций можно изменять.
Redis
Общий формат URI: redis://username:password@host[:port]/dbindex
Поддержка многопоточности: да
Пример использования:
grbackup -e email@gmail.com -p password -ba -o redis://user:password@localhost:6379/0 -w 20
Для хранения записей используется тип данных Hashes.
Ключи могут быть трех типов: «subscription:record_id», «starred:record_id», «topic:record_id», где record_id — уникальный идентификатор записи.
Префиксы ключей можно изменять.
Свой плагин
Модуль должен находится в пакете grb_plugins, имя модуля не имеет значения.
Структура модуля:
- plugin_type — строковый тип, содержит имя плагина
- support_threads — логический тип, указывает на возможность использования нескольких потоков
- descriptions — строковый тип, содержит описание плагина
- add_option_group — функция добавляющая дополнительные опции комадной строки
- writer — контекстный менеджер возвращающий объект с методами:
- put_subscription(subscription) — вызывается при сохранение подписки, subscription — словарь
- put_starred(topic) — вызывается при сохранении отмеченной записи, topic — словарь
- put_topic(self, subscription_url, topic) — вызывается при сохранении записи (опция ‘-t’, ‘—topics‘),
topic — словарь, subscription_url — строковый адрес подписки - put_all(subscription, topic) — вызывается при сохранении записи с использованием опции ‘-a’, ‘—all’,
subscription и topic — словари
#!/usr/bin/env python # coding=utf-8 from optparse import OptionGroup import logging plugin_type = "myplugin" support_threads = True description = """save items using logging output scheme: myplugin:/path/to/logfile.log output examples: myplugin:/tmp/storage.log """ def add_option_group(parser): # Plugin Options myplugin_group = OptionGroup(parser, "myplugin Options") myplugin_group.add_option("--myplugin-format", dest="format", type="str", default="%(asctime)s %(message)s", help="record format" "[default: %default]") myplugin_group.add_option("--myplugin-datefmt", dest="datefmt", type="str", default="%m/%d/%Y %I:%M:%S %p", help="date format" "[default: %default]") parser.add_option_group(myplugin_group) class WriteMyPlugin(object): def __init__(self, logger): self.logger = logger def put_subscription(self, subscription): subscription_url = subscription['id'][5:] self.logger.warning("write subscription: %s", subscription_url) def put_all(self, subscription, topic): subscription_url = subscription['id'][5:] self.put_subscription(subscription) self.put_topic(subscription_url, topic) def put_starred(self, topic): self.logger.warning("write starred: %s", topic.get('title', '')) def put_topic(self, subscription_url, topic): self.logger.warning("write topic: %s %s", subscription_url, topic.get('title', '')) class writer(object): def __init__(self, opt): path = opt.output[opt.output.index(":") + 1:] self._logger = logging.getLogger("myplugin") handler = logging.FileHandler(path) handler.setFormatter(logging.Formatter(opt.format, opt.datefmt)) self._logger.addHandler(handler) def __enter__(self): return WriteMyPlugin(self._logger) def __exit__(self, *exc_info): pass
ссылка на оригинал статьи http://habrahabr.ru/post/182712/
Добавить комментарий