Исходный код magnetto.ext.api_dispatcher

from grab import Grab

from magnetto.apis import BaseApi
from magnetto.errors import MagnettoCaptchaError
from magnetto.filters import Order, OrderBy


[документация]class ApiDispatcher(object): """Диспетчер, абстрагирующий от работы с множественными апи трекера. Умеет выполнять инициализацию переданных Api, в том числе проставляет соответствующие настройки :obj:`grab.Grab` объекту (пример: coockie файл, log файл). Делегирует вызовы одноименным вызовам апи. Examples: Пример инициализации с одним объектом >>> api = RutrackerApi("Roland", "1234") ... dispatcher = ApiDispatcher([api, ]) ... print(dispatcher.search("Начало")) """
[документация] def __init__(self, grab=Grab(), objs=[], log_dir=None, coockie_dir=None): """ Args: objs (List[BaseApi]): Массив Api объектов grab (grab.Grab, optional): Экземпляр Grab объекта. Используется для указания своих типов настроек (пример: настройки прокси). log_dir (str, optional): В данную директорию помещается результат выполнения запроса coockie_dir (str, optional): Директория, для сохранения coockie файлов """ self._grab = grab.clone() self._log_dir = log_dir self._coockie_dir = coockie_dir self._apis = objs self._fail_apis = {}
[документация] def add_obj(self, obj): """Добавляет api объект Args: obj (BaseApi): Api объект Return: ``True`` - объект добавлен ``False`` - такой объект уже существует """ if isinstance(obj, BaseApi) and obj not in self._apis: self._apis.append(obj) return True else: return False
[документация] def get_obj(self, cls): """Возвращает соответствующий экземпляр Api объекта Args: cls (BaseApi): Api класс Return: ``BaseApi`` Соответствущий классу объект ``None`` Соответствущего объекта не найдено """ for obj in self._apis: if isinstance(obj, cls): return obj return None
[документация] def del_cls(self, cls): """Удаляет объект данного типа из обработки (нужен например при изменении формы входа и невозможности повторной авторизации) Args: cls (BaseApi): Api класс """ for obj in self._apis: if isinstance(obj, cls): self._apis.remove(obj)
[документация] def del_obj(self, obj): """Удаляет переданный объект из обработки Args: obj (BaseApi): Api объект """ if obj in self._apis: self._apis.remove(obj)
[документация] def authorization(self, cls, login, password, captcha=None): """Выполняет процедуру авторизации для укзанного Api класса и сохраняет объект методом add_obj. Проставляет в grab объекте параметры log_file и cookiefile Args: cls (BaseApi): Инициализирует переданный cls и выполняет :obj:`BaseApi.authorization()` login (str): Логин для входа password (str): Пароль для входа captcha (str): Введенная капча (нужна только при ошибке предыдущей авторизации) Return: ``True``: успешная авторизация Raises: ``MagnettoIncorrectСredentials``: введены неверные данные для входа ``MagnettoCaptchaError``: на странице обнаружена капча """ if not (captcha and cls in self._fail_apis): # подстройка grab объекта под cls grab = self._grab.clone() grab.setup(log_file="{dir}/{cls}.html".format( dir=self._log_dir, cls=cls.__name__)) grab.setup(cookiefile="{dir}/{cls}.cookie".format( dir=self._coockie_dir, cls=cls.__name__)) obj = cls(grab) else: # берем уже проицициализированный объект, для ввода капчи # (отправки ранее используемой формы) obj = self._fail_apis[cls] try: obj.authorization(login, password, captcha) except MagnettoCaptchaError as e: # сохраняем экземпляр объекта, чтобы в дальнейшем иметь возможность # ввести капчу и отправить запрос повторно self._fail_apis[cls] = obj raise # сохранять объект больше нет необходимости if cls in self._fail_apis: del self._fail_apis[cls] # сохраняем объект в случае успешной авторизации self.add_obj(obj) return True
[документация] def search(self, value, categories=[], page=0, limit=0, order_by=OrderBy.DOWNLOADS, order=Order.DESC): """ Todo: * фильтры """ if not self._apis: raise Exception("ApiDispather has no Api objects") results = {} for obj in self._apis: results[obj.__class__] = obj.search( value, categories, page, limit, order_by, order) # TODO: всякие разные фильтры return results