def __init__(self, config): self.config = config if self.config.get('account') and not self.config.get('username'): self.config['username'] = '******' self.session = get_session(self.config.get('account')) # Lists may not have modified results if modified then accessed in quick succession. self.session.add_domain_limiter(TimedLimiter('trakt.tv', '2 seconds')) self._items = None
def on_task_input(self, task, config): if config.get('account') and not config.get('username'): config['username'] = '******' session = get_session(account=config.get('account')) endpoint = ['users', config['username']] if type(config['list']) is dict: endpoint += ('ratings', config['type'], config['list']['rating']) elif config['list'] in ['collection', 'watchlist', 'watched', 'ratings']: endpoint += (config['list'], config['type']) else: endpoint += ('lists', make_list_slug(config['list']), 'items') log.verbose('Retrieving `%s` list `%s`' % (config['type'], config['list'])) try: result = session.get(get_api_url(endpoint)) try: data = result.json() except ValueError: log.debug('Could not decode json from response: %s', result.text) raise plugin.PluginError('Error getting list from trakt.') except RequestException as e: raise plugin.PluginError('Could not retrieve list from trakt (%s)' % e.args[0]) if not data: log.warning('No data returned from trakt for %s list %s.' % (config['type'], config['list'])) return entries = [] list_type = (config['type']).rstrip('s') for item in data: # Collection and watched lists don't return 'type' along with the items (right now) if 'type' in item and item['type'] != list_type: log.debug('Skipping %s because it is not a %s' % (item[item['type']].get('title', 'unknown'), list_type)) continue if not item[list_type]['title']: # There seems to be some bad shows sometimes in lists with no titles. Skip them. log.warning('Item in trakt list does not appear to have a title, skipping.') continue entry = Entry() if list_type == 'episode': entry['url'] = 'http://trakt.tv/shows/%s/seasons/%s/episodes/%s' % ( item['show']['ids']['slug'], item['episode']['season'], item['episode']['number']) else: entry['url'] = 'http://trakt.tv/%s/%s' % (list_type, item[list_type]['ids'].get('slug')) entry.update_using_map(field_maps[list_type], item) if entry.isvalid(): if config.get('strip_dates'): # Remove year from end of name if present entry['title'] = re.sub(r'\s+\(\d{4}\)$', '', entry['title']) entries.append(entry) else: log.debug('Invalid entry created? %s' % entry) return entries
def on_task_output(self, task, config): """Submits accepted movies or episodes to trakt api.""" if config.get('account') and not config.get('username'): config['username'] = '******' found = {'shows': [], 'movies': []} for entry in task.accepted: if config['type'] in ['auto', 'shows', 'seasons', 'episodes'] and entry.get('series_name') is not None: show = {'title': entry['series_name'], 'ids': get_entry_ids(entry)} if config['type'] in ['auto', 'seasons', 'episodes'] and entry.get('series_season') is not None: season = {'number': entry['series_season']} if config['type'] in ['auto', 'episodes'] and entry.get('series_episode') is not None: season['episodes'] = [{'number': entry['series_episode']}] show['seasons'] = [season] if config['type'] in ['seasons', 'episodes'] and 'seasons' not in show: self.log.debug('Not submitting `%s`, no season found.' % entry['title']) continue if config['type'] == 'episodes' and 'episodes' not in show: self.log.debug('Not submitting `%s`, no episode number found.' % entry['title']) continue found['shows'].append(show) elif config['type'] in ['auto', 'movies']: movie = {'ids': get_entry_ids(entry)} if not movie['ids']: if entry.get('movie_name') is not None: movie['title'] = entry.get('movie_name') or entry.get('imdb_name') movie['year'] = entry.get('movie_year') or entry.get('imdb_year') else: self.log.debug('Not submitting `%s`, no movie name or id found.' % entry['title']) continue found['movies'].append(movie) if not (found['shows'] or found['movies']): self.log.debug('Nothing to submit to trakt.') return if config['list'] in ['collection', 'watchlist', 'watched']: args = ('sync', 'history' if config['list'] == 'watched' else config['list']) else: args = ('users', config['username'], 'lists', make_list_slug(config['list']), 'items') if self.remove: args += ('remove', ) url = get_api_url(args) if task.manager.options.test: self.log.info('Not submitting to trakt.tv because of test mode.') return session = get_session(account=config.get('account')) self.log.debug('Submitting data to trakt.tv (%s): %s' % (url, found)) try: result = session.post(url, data=json.dumps(found), raise_status=False) except RequestException as e: self.log.error('Error submitting data to trakt.tv: %s' % e) return if 200 <= result.status_code < 300: action = 'added' if self.remove: action = 'deleted' res = result.json() movies = res[action].get('movies', 0) shows = res[action].get('shows', 0) eps = res[action].get('episodes', 0) self.log.info('Successfully %s to/from list %s: %s movie(s), %s show(s), %s episode(s).', action, config['list'], movies, shows, eps) for k, r in res['not_found'].iteritems(): if r: self.log.debug('not found %s: %s' % (k, r)) # TODO: Improve messages about existing and unknown results elif result.status_code == 404: self.log.error('List does not appear to exist on trakt: %s' % config['list']) elif result.status_code == 401: self.log.error('Authentication error: have you authorized Flexget on Trakt.tv?') self.log.debug('trakt response: ' + result.text) else: self.log.error('Unknown error submitting data to trakt.tv: %s' % result.text)
def on_task_input(self, task, config): if config.get('account') and not config.get('username'): config['username'] = '******' session = get_session(account=config.get('account')) listed_series = {} if config.get('list'): args = ('users', config['username']) if config['list'] in ['collection', 'watchlist', 'watched']: args += (config['list'], 'shows') else: args += ('lists', make_list_slug(config['list']), 'items') try: data = session.get(get_api_url(args)).json() except RequestException as e: raise plugin.PluginError('Unable to get trakt list `%s`: %s' % (config['list'], e)) if not data: log.warning('The list "%s" is empty.' % config['list']) return for item in data: if item.get('show'): if not item['show']['title']: # Seems we can get entries with a blank show title sometimes log.warning('Found trakt list show with no series name.') continue trakt_id = item['show']['ids']['trakt'] listed_series[trakt_id] = { 'series_name': '%s (%s)' % (item['show']['title'], item['show']['year']), 'trakt_id': trakt_id, 'tvdb_id': item['show']['ids']['tvdb'], 'trakt_list': config.get('list')} context = config['context'] if context == 'collected': context = 'collection' entries = [] for trakt_id, fields in listed_series.items(): url = get_api_url('shows', trakt_id, 'progress', context) try: data = session.get(url).json() except RequestException as e: raise plugin.PluginError('An error has occured looking up: Trakt_id: %s Error: %s' % (trakt_id, e)) if config['position'] == 'next' and data.get('next_episode'): # If the next episode is already in the trakt database, we'll get it here eps = data['next_episode']['season'] epn = data['next_episode']['number'] else: # If we need last ep, or next_episode was not provided, search for last ep for seas in reversed(data['seasons']): # Find the first season with collected/watched episodes if seas['completed'] > 0: eps = seas['number'] # Pick the highest collected/watched episode epn = max(item['number'] for item in seas['episodes'] if item['completed']) # If we are in next episode mode, we have to increment this number if config['position'] == 'next': if seas['completed'] >= seas['aired']: # TODO: next_episode doesn't count unaired episodes right now, this will skip to next # season too early when there are episodes left to air this season. eps += 1 epn = 1 else: epn += 1 break else: if config['position'] == 'next': eps = epn = 1 else: # There were no watched/collected episodes, nothing to emit in 'last' mode continue if eps and epn: if config.get('strip_dates'): # remove year from end of series_name if present fields['series_name'] = re.sub(r'\s+\(\d{4}\)$', '', fields['series_name']) entry = self.make_entry(fields, eps, epn) entries.append(entry) return entries
def on_task_input(self, task, config): if config.get('account') and not config.get('username'): config['username'] = '******' session = get_session(account=config.get('account')) listed_series = {} if config.get('list'): args = ('users', config['username']) if config['list'] in ['collection', 'watchlist', 'watched']: args += (config['list'], 'shows') else: args += ('lists', make_list_slug(config['list']), 'items') try: data = session.get(get_api_url(args)).json() except RequestException as e: raise plugin.PluginError('Unable to get trakt list `%s`: %s' % (config['list'], e)) if not data: log.warning('The list "%s" is empty.' % config['list']) return for item in data: if item.get('show'): if not item['show']['title']: # Seems we can get entries with a blank show title sometimes log.warning( 'Found trakt list show with no series name.') continue trakt_id = item['show']['ids']['trakt'] listed_series[trakt_id] = { 'series_name': '%s (%s)' % (item['show']['title'], item['show']['year']), 'trakt_id': trakt_id, 'tvdb_id': item['show']['ids']['tvdb'], 'trakt_list': config.get('list') } context = config['context'] if context == 'collected': context = 'collection' entries = [] for trakt_id, fields in listed_series.items(): url = get_api_url('shows', trakt_id, 'progress', context) try: data = session.get(url).json() except RequestException as e: raise plugin.PluginError('TODO: error message') if config['position'] == 'next' and data.get('next_episode'): # If the next episode is already in the trakt database, we'll get it here eps = data['next_episode']['season'] epn = data['next_episode']['number'] else: # If we need last ep, or next_episode was not provided, search for last ep for seas in reversed(data['seasons']): # Find the first season with collected/watched episodes if seas['completed'] > 0: eps = seas['number'] # Pick the highest collected/watched episode epn = max(item['number'] for item in seas['episodes'] if item['completed']) # If we are in next episode mode, we have to increment this number if config['position'] == 'next': if seas['completed'] >= seas['aired']: # TODO: next_episode doesn't count unaired episodes right now, this will skip to next # season too early when there are episodes left to air this season. eps += 1 epn = 1 else: epn += 1 break else: if config['position'] == 'next': eps = epn = 1 else: # There were no watched/collected episodes, nothing to emit in 'last' mode continue if eps and epn: if config.get('strip_dates'): # remove year from end of series_name if present fields['series_name'] = re.sub(r'\s+\(\d{4}\)$', '', fields['series_name']) entry = self.make_entry(fields, eps, epn) entries.append(entry) return entries
def on_task_output(self, task, config): """Submits accepted movies or episodes to trakt api.""" if config.get('account') and not config.get('username'): config['username'] = '******' found = {'shows': [], 'movies': []} for entry in task.accepted: if 'series_name' in entry: show = { 'title': entry['series_name'], 'ids': get_entry_ids(entry) } if 'series_season' in entry: season = {'number': entry['series_season']} if 'series_episode' in entry: season['episodes'] = [{ 'number': entry['series_episode'] }] show['seasons'] = [season] found['shows'].append(show) elif any(field in entry for field in ['imdb_id', 'tmdb_id', 'movie_name']): movie = {'ids': get_entry_ids(entry)} if not movie['ids']: movie['title'] = entry.get('movie_name') or entry.get( 'imdb_name') movie['year'] = entry.get('movie_year') or entry.get( 'imdb_year') found['movies'].append(movie) if not (found['shows'] or found['movies']): self.log.debug('Nothing to submit to trakt.') return if config['list'] in ['collection', 'watchlist', 'watched']: args = ('sync', 'history' if config['list'] == 'watched' else config['list']) else: args = ('users', config['username'], 'lists', make_list_slug(config['list']), 'items') if self.remove: args += ('remove', ) url = get_api_url(args) if task.manager.options.test: self.log.info('Not submitting to trakt.tv because of test mode.') return session = get_session(account=config.get('account')) self.log.debug('Submitting data to trakt.tv (%s): %s' % (url, found)) try: result = session.post(url, data=json.dumps(found), raise_status=False) except RequestException as e: self.log.error('Error submitting data to trakt.tv: %s' % e) return if 200 <= result.status_code < 300: action = 'added' if self.remove: action = 'deleted' res = result.json() movies = res[action].get('movies', 0) eps = res[action].get('episodes', 0) self.log.info( 'Successfully %s to/from list %s: %s movie(s), %s episode(s).' % (action, config['list'], movies, eps)) for k, r in res['not_found'].iteritems(): if r: self.log.debug('not found %s: %s' % (k, r)) # TODO: Improve messages about existing and unknown results elif result.status_code == 404: self.log.error('List does not appear to exist on trakt: %s' % config['list']) elif result.status_code == 401: self.log.error( 'Authentication error: have you authorized Flexget on Trakt.tv?' ) self.log.debug('trakt response: ' + result.text) else: self.log.error('Unknown error submitting data to trakt.tv: %s' % result.text)
def on_task_input(self, task, config): if config.get("account") and not config.get("username"): config["username"] = "******" session = get_session(account=config.get("account")) listed_series = {} if config.get("list"): args = ("users", config["username"]) if config["list"] in ["collection", "watchlist", "watched"]: args += (config["list"], "shows") else: args += ("lists", make_list_slug(config["list"]), "items") try: data = session.get(get_api_url(args)).json() except RequestException as e: raise plugin.PluginError("Unable to get trakt list `%s`: %s" % (config["list"], e)) if not data: log.warning('The list "%s" is empty.' % config["list"]) return for item in data: if item.get("show"): if not item["show"]["title"]: # Seems we can get entries with a blank show title sometimes log.warning("Found trakt list show with no series name.") continue trakt_id = item["show"]["ids"]["trakt"] listed_series[trakt_id] = { "series_name": "%s (%s)" % (item["show"]["title"], item["show"]["year"]), "trakt_id": trakt_id, "tvdb_id": item["show"]["ids"]["tvdb"], "trakt_list": config.get("list"), } context = config["context"] if context == "collected": context = "collection" entries = [] for trakt_id, fields in listed_series.iteritems(): url = get_api_url("shows", trakt_id, "progress", context) try: data = session.get(url).json() except RequestException as e: raise plugin.PluginError("TODO: error message") if config["position"] == "next" and data.get("next_episode"): # If the next episode is already in the trakt database, we'll get it here eps = data["next_episode"]["season"] epn = data["next_episode"]["number"] else: # If we need last ep, or next_episode was not provided, search for last ep for seas in reversed(data["seasons"]): # Find the first season with collected/watched episodes if seas["completed"] > 0: eps = seas["number"] # Pick the highest collected/watched episode epn = max(item["number"] for item in seas["episodes"] if item["completed"]) # If we are in next episode mode, we have to increment this number if config["position"] == "next": if seas["completed"] >= seas["aired"]: # TODO: next_episode doesn't count unaired episodes right now, this will skip to next # season too early when there are episodes left to air this season. eps += 1 epn = 1 else: epn += 1 break else: if config["position"] == "next": eps = epn = 1 else: # There were no watched/collected episodes, nothing to emit in 'last' mode continue if eps and epn: entry = self.make_entry(fields, eps, epn) entries.append(entry) return entries