Source code for flexget.plugins.input.betaseries_list

"""Input plugin for www.betaseries.com."""

from hashlib import md5

from loguru import logger

from flexget import plugin
from flexget.entry import Entry
from flexget.event import event
from flexget.utils import requests
from flexget.utils.cached_input import cached

logger = logger.bind(name='betaseries_list')

API_URL_PREFIX = 'https://api.betaseries.com/'


[docs] class BetaSeriesList: """Emit an entry for each series followed by one or more BetaSeries account. See https://www.betaseries.com/ Configuration examples:: # will get all series followed by the account identified by your_user_name betaseries_list: username: your_user_name password: your_password api_key: your_api_key :: # will get all series followed by the account identified by some_other_guy betaseries_list: username: your_user_name password: your_password api_key: your_api_key members: - some_other_guy :: # will get all series followed by the accounts identified by guy1 and guy2 betaseries_list: username: your_user_name password: your_password api_key: your_api_key members: - guy1 - guy2 Api key can be requested at https://www.betaseries.com/api. This plugin is meant to work with the import_series plugin as follow:: import_series: from: betaseries_list: username: xxxxx password: xxxxx api_key: xxxxx """ schema = { 'type': 'object', 'properties': { 'username': {'type': 'string'}, 'password': {'type': 'string'}, 'api_key': {'type': 'string'}, 'members': {'type': 'array', 'items': {'title': 'member name', 'type': 'string'}}, }, 'required': ['username', 'password', 'api_key'], 'additionalProperties': False, } @cached('betaseries_list', persist='2 hours') def on_task_input(self, task, config): username = config['username'] password = config['password'] api_key = config['api_key'] members = config.get('members', [username]) titles = set() try: user_token = create_token(api_key, username, password) for member in members: titles.update(query_series(api_key, user_token, member)) except (requests.RequestException, AssertionError) as err: logger.opt(exception=True).critical( 'Failed to get series at BetaSeries.com: {}', err.message ) logger.verbose('series: ' + ', '.join(titles)) entries = [] for t in titles: e = Entry() e['title'] = t entries.append(e) return entries
[docs] def create_token(api_key, login, password): """Login in and request an new API token. https://www.betaseries.com/wiki/Documentation#cat-members :param string api_key: Api key requested at https://www.betaseries.com/api :param string login: Login name :param string password: Password :return: User token """ r = requests.post( API_URL_PREFIX + 'members/auth', params={'login': login, 'password': md5(password.encode('utf-8')).hexdigest()}, headers={ 'Accept': 'application/json', 'X-BetaSeries-Version': '2.1', 'X-BetaSeries-Key': api_key, }, ) assert r.status_code == 200, f'Bad HTTP status code: {r.status_code}' j = r.json() error_list = j['errors'] for err in error_list: logger.error(str(err)) if not error_list: return j['token'] return None
[docs] def query_member_id(api_key, user_token, login_name): """Get the member id of a member identified by its login name. :param string api_key: Api key requested at https://www.betaseries.com/api :param string user_token: obtained with a call to create_token() :param string login_name: The login name of the member :return: Id of the member identified by its login name or `None` if not found """ r = requests.get( API_URL_PREFIX + 'members/search', params={'login': login_name}, headers={ 'Accept': 'application/json', 'X-BetaSeries-Version': '2.1', 'X-BetaSeries-Key': api_key, 'X-BetaSeries-Token': user_token, }, ) assert r.status_code == 200, f'Bad HTTP status code: {r.status_code}' j = r.json() error_list = j['errors'] for err in error_list: logger.error(str(err)) found_id = None if not error_list: for candidate in j['users']: if candidate['login'] == login_name: found_id = candidate['id'] break return found_id
[docs] def query_series(api_key, user_token, member_name=None): """Get the list of series followed by the authenticated user. :param string api_key: Api key requested at https://www.betaseries.com/api :param string user_token: Obtained with a call to create_token() :param string member_name: [optional] A member name to get the list of series from. If None, will query the member for whom the user_token was for :return: List of series titles or empty list """ params = {} if member_name: member_id = query_member_id(api_key, user_token, member_name) if member_id: params = {'id': member_id} else: logger.error('member {!r} not found', member_name) return [] r = requests.get( API_URL_PREFIX + 'shows/member', params=params, headers={ 'Accept': 'application/json', 'X-BetaSeries-Version': '2.1', 'X-BetaSeries-Key': api_key, 'X-BetaSeries-Token': user_token, }, ) assert r.status_code == 200, f'Bad HTTP status code: {r.status_code}' j = r.json() error_list = j['errors'] for err in error_list: logger.error(str(err)) if not error_list: return [x['title'] for x in j['shows'] if x['user']['archived'] is False] return []
[docs] @event('plugin.register') def register_plugin(): plugin.register(BetaSeriesList, 'betaseries_list', api_ver=2, interfaces=['task'])