def add_show_trakt_library(self, show_obj): """Add show to trakt library.""" data = {} if not self.find_show(show_obj.indexerid, show_obj.indexer): # Check if TRAKT supports that indexer if not get_trakt_indexer(show_obj.indexer): return # URL parameters title = get_title_without_year(show_obj.name, show_obj.start_year) data = { 'shows': [ { 'title': title, 'year': show_obj.start_year, 'ids': {} } ] } data['shows'][0]['ids'][get_trakt_indexer(show_obj.indexer)] = show_obj.indexerid if data: log.info("Adding show '{show}' to Trakt library", {'show': show_obj.name}) try: self._request('sync/collection', data, method='POST') except (TraktException, AuthException, TokenExpiredException) as error: log.info("Unable to add show '{show}' to Trakt library. Error: {error!r}", { 'show': show_obj.name, 'error': error }) return
def add_show_watchlist(self): """Add show to Trakt watchlist. It will add all shows from Medusa library """ if app.TRAKT_SYNC_WATCHLIST and app.USE_TRAKT: if app.showList: trakt_data = [] for show_obj in app.showList: if not self._check_list(show_obj=show_obj, list_type='Show'): log.info("Adding show '{show}' to Trakt watchlist", {'show': show_obj.name}) title = get_title_without_year(show_obj.name, show_obj.start_year) show_el = { 'title': title, 'year': show_obj.start_year, 'ids': {} } trakt_data.append(show_el) if trakt_data: try: data = {'shows': trakt_data} self._request('sync/watchlist', data, method='POST') except (TraktException, AuthException, TokenExpiredException) as e: log.info( 'Unable to add shows to Trakt watchlist. Error: {error}', {'error': e.message}) self._get_show_watchlist()
def add_episode_trakt_collection(self): """Add all existing episodes to Trakt collections. For episodes that have a media file (location) """ if app.TRAKT_SYNC and app.USE_TRAKT: main_db_con = db.DBConnection() statuses = [DOWNLOADED, ARCHIVED] sql_selection = b'SELECT s.indexer, s.startyear, s.indexer_id, s.show_name, e.season, e.episode ' \ b'FROM tv_episodes AS e, tv_shows AS s ' \ b'WHERE e.indexer = s.indexer AND s.indexer_id = e.showid ' \ b"AND e.status in ({0}) AND e.location <> ''".format(','.join(['?'] * len(statuses))) sql_result = main_db_con.select(sql_selection, statuses) episodes = [dict(e) for e in sql_result] if episodes: trakt_data = [] for cur_episode in episodes: # Check if TRAKT supports that indexer if not get_trakt_indexer(cur_episode[b'indexer']): continue if not self._check_list( indexer=cur_episode[b'indexer'], indexer_id=cur_episode[b'indexer_id'], season=cur_episode[b'season'], episode=cur_episode[b'episode'], list_type='Collection'): log.info( "Adding episode '{show}' {ep} to Trakt collection", { 'show': cur_episode[b'show_name'], 'ep': episode_num(cur_episode[b'season'], cur_episode[b'episode']) }) title = get_title_without_year( cur_episode[b'show_name'], cur_episode[b'startyear']) trakt_data.append( (cur_episode[b'indexer_id'], cur_episode[b'indexer'], title, cur_episode[b'startyear'], cur_episode[b'season'], cur_episode[b'episode'])) if trakt_data: try: data = self.trakt_bulk_data_generate(trakt_data) self._request('sync/collection', data, method='POST') self._get_show_collection() except (TraktException, AuthException, TokenExpiredException) as e: log.info( 'Unable to add episodes to Trakt collection. Error: {error}', {'error': e.message})
def remove_episode_watchlist(self): """Remove episode from Trakt watchlist.""" if app.TRAKT_SYNC_WATCHLIST and app.USE_TRAKT: main_db_con = db.DBConnection() statuses = [DOWNLOADED, ARCHIVED] sql_selection = b'SELECT s.indexer, s.startyear, e.showid, s.show_name, e.season, e.episode ' \ b'FROM tv_episodes AS e, tv_shows AS s ' \ b'WHERE e.indexer = s.indexer ' \ b'AND s.indexer_id = e.showid AND e.status in ({0})'.format(','.join(['?'] * len(statuses))) sql_result = main_db_con.select(sql_selection, statuses) episodes = [dict(i) for i in sql_result] if episodes: trakt_data = [] for cur_episode in episodes: # Check if TRAKT supports that indexer if not get_trakt_indexer(cur_episode[b'indexer']): continue if self._check_list(indexer=cur_episode[b'indexer'], indexer_id=cur_episode[b'showid'], season=cur_episode[b'season'], episode=cur_episode[b'episode']): log.info( "Removing episode '{show}' {ep} from Trakt watchlist", { 'show': cur_episode[b'show_name'], 'ep': episode_num(cur_episode[b'season'], cur_episode[b'episode']) }) title = get_title_without_year( cur_episode[b'show_name'], cur_episode[b'startyear']) trakt_data.append( (cur_episode[b'showid'], cur_episode[b'indexer'], title, cur_episode[b'startyear'], cur_episode[b'season'], cur_episode[b'episode'])) if trakt_data: try: data = self.trakt_bulk_data_generate(trakt_data) self._request('sync/watchlist/remove', data, method='POST') self._get_episode_watchlist() except (TraktException, AuthException, TokenExpiredException) as e: log.info( 'Unable to remove episodes from Trakt watchlist. Error: {error}', {'error': e.message})
def add_episode_watchlist(self): """Add episode to Tratk watchlist.""" if app.TRAKT_SYNC_WATCHLIST and app.USE_TRAKT: main_db_con = db.DBConnection() status = Quality.SNATCHED + Quality.SNATCHED_BEST + Quality.SNATCHED_PROPER + [ WANTED ] selection_status = [b'?' for _ in status] sql_selection = b'SELECT s.indexer, s.startyear, e.showid, s.show_name, e.season, e.episode ' \ b'FROM tv_episodes AS e, tv_shows AS s ' \ b'WHERE e.indexer = s.indexer AND s.indexer_id = e.showid AND s.paused = 0 ' \ b'AND e.status in ({0})'.format(b','.join(selection_status)) sql_result = main_db_con.select(sql_selection, status) episodes = [dict(i) for i in sql_result] if episodes: trakt_data = [] for cur_episode in episodes: # Check if TRAKT supports that indexer if not get_trakt_indexer(cur_episode[b'indexer']): continue if not self._check_list(indexer=cur_episode[b'indexer'], indexer_id=cur_episode[b'showid'], season=cur_episode[b'season'], episode=cur_episode[b'episode']): log.info( "Adding episode '{show}' {ep} to Trakt watchlist", { 'show': cur_episode[b'show_name'], 'ep': episode_num(cur_episode[b'season'], cur_episode[b'episode']) }) title = get_title_without_year( cur_episode[b'show_name'], cur_episode[b'startyear']) trakt_data.append( (cur_episode[b'showid'], cur_episode[b'indexer'], title, cur_episode[b'startyear'], cur_episode[b'season'], cur_episode[b'episode'])) if trakt_data: try: data = self.trakt_bulk_data_generate(trakt_data) self._request('sync/watchlist', data, method='POST') self._get_episode_watchlist() except (TraktException, AuthException, TokenExpiredException) as e: log.info( 'Unable to add episode to Trakt watchlist. Error: {error}', {'error': e.message})
def create_show_structure(show_obj): """Prepare a trakt standard media object. With the show identifier.""" show = { 'title': get_title_without_year(show_obj.name, show_obj.start_year), 'year': show_obj.start_year, 'ids': {} } for valid_trakt_id in ['tvdb_id', 'trakt_id', 'tmdb_id', 'imdb_id']: if show_obj.externals.get(valid_trakt_id): show['ids'][valid_trakt_id[:-3]] = show_obj.externals.get(valid_trakt_id) return show
def remove_episode_trakt_collection(self, filter_show=None): """Remove episode from trakt collection. For episodes that no longer have a media file (location) :param filter_show: optional. Only remove episodes from trakt collection for given shows """ if app.TRAKT_SYNC_REMOVE and app.TRAKT_SYNC and app.USE_TRAKT: params = [] main_db_con = db.DBConnection() selection_status = ['?' for _ in Quality.DOWNLOADED + Quality.ARCHIVED] sql_selection = b'SELECT s.indexer, s.startyear, s.indexer_id, s.show_name,' \ b'e.season, e.episode, e.status ' \ b'FROM tv_episodes AS e, tv_shows AS s WHERE e.indexer = s.indexer AND ' \ b's.indexer_id = e.showid and e.location = "" ' \ b'AND e.status in ({0})'.format(','.join(selection_status)) if filter_show: sql_selection += b' AND s.indexer_id = ? AND e.indexer = ?' params = [filter_show.series_id, filter_show.indexer] sql_result = main_db_con.select(sql_selection, Quality.DOWNLOADED + Quality.ARCHIVED + params) episodes = [dict(e) for e in sql_result] if episodes: trakt_data = [] for cur_episode in episodes: # Check if TRAKT supports that indexer if not get_trakt_indexer(cur_episode[b'indexer']): continue if self._check_list(indexer=cur_episode[b'indexer'], indexer_id=cur_episode[b'indexer_id'], season=cur_episode[b'season'], episode=cur_episode[b'episode'], list_type='Collection'): log.info("Removing episode '{show}' {ep} from Trakt collection", { 'show': cur_episode[b'show_name'], 'ep': episode_num(cur_episode[b'season'], cur_episode[b'episode']) }) title = get_title_without_year(cur_episode[b'show_name'], cur_episode[b'startyear']) trakt_data.append((cur_episode[b'indexer_id'], cur_episode[b'indexer'], title, cur_episode[b'startyear'], cur_episode[b'season'], cur_episode[b'episode'])) if trakt_data: try: data = self.trakt_bulk_data_generate(trakt_data) self._request('sync/collection/remove', data, method='POST') self._get_show_collection() except (TraktException, AuthException, TokenExpiredException) as e: log.info('Unable to remove episodes from Trakt collection. Error: {error}', { 'error': e.message })
def remove_episode_trakt_collection(self, filter_show=None): """Remove episode from trakt collection. For episodes that no longer have a media file (location) :param filter_show: optional. Only remove episodes from trakt collection for given shows """ if app.TRAKT_SYNC_REMOVE and app.TRAKT_SYNC and app.USE_TRAKT: params = [] main_db_con = db.DBConnection() statuses = [DOWNLOADED, ARCHIVED] sql_selection = 'SELECT s.indexer, s.startyear, s.indexer_id, s.show_name,' \ 'e.season, e.episode, e.status ' \ 'FROM tv_episodes AS e, tv_shows AS s WHERE e.indexer = s.indexer AND ' \ 's.indexer_id = e.showid and e.location = "" ' \ 'AND e.status in ({0})'.format(','.join(['?'] * len(statuses))) if filter_show: sql_selection += ' AND s.indexer_id = ? AND e.indexer = ?' params = [filter_show.series_id, filter_show.indexer] sql_result = main_db_con.select(sql_selection, statuses + params) if sql_result: trakt_data = [] for cur_episode in sql_result: # Check if TRAKT supports that indexer if not get_trakt_indexer(cur_episode['indexer']): continue if self._check_list(indexer=cur_episode['indexer'], indexer_id=cur_episode['indexer_id'], season=cur_episode['season'], episode=cur_episode['episode'], list_type='Collection'): log.info("Removing episode '{show}' {ep} from Trakt collection", { 'show': cur_episode['show_name'], 'ep': episode_num(cur_episode['season'], cur_episode['episode']) }) title = get_title_without_year(cur_episode['show_name'], cur_episode['startyear']) trakt_data.append((cur_episode['indexer_id'], cur_episode['indexer'], title, cur_episode['startyear'], cur_episode['season'], cur_episode['episode'])) if trakt_data: try: data = self.trakt_bulk_data_generate(trakt_data) self._request('sync/collection/remove', data, method='POST') self._get_show_collection() except (TraktException, AuthException, TokenExpiredException) as error: log.info('Unable to remove episodes from Trakt collection. Error: {error!r}', { 'error': error })
def remove_show_trakt_library(self, show_obj): """Remove show from trakt library.""" if self.find_show(show_obj.indexerid, show_obj.indexer): # Check if TRAKT supports that indexer if not get_trakt_indexer(show_obj.indexer): return # URL parameters title = get_title_without_year(show_obj.name, show_obj.start_year) data = { 'shows': [{ 'title': title, 'year': show_obj.start_year, 'ids': {} }] } data['shows'][0]['ids'][get_trakt_indexer( show_obj.indexer)] = show_obj.indexerid log.info("Removing '{show}' from Trakt library", {'show': show_obj.name}) # Remove all episodes from the Trakt collection for this show try: self.remove_episode_trakt_collection(filter_show=show_obj) except (TraktException, AuthException, TokenExpiredException) as error: log.info( "Unable to remove all episodes from show '{show}' from Trakt library. Error: {error!r}", { 'show': show_obj.name, 'error': error }) try: self._request('sync/collection/remove', data, method='POST') except (TraktException, AuthException, TokenExpiredException) as error: log.info( "Unable to remove show '{show}' from Trakt library. Error: {error!r}", { 'show': show_obj.name, 'error': error })
def update_library(ep_obj): """Send a request to trakt indicating that the given episode is part of our library. ep_obj: The Episode object to add to trakt """ # Check if TRAKT supports that indexer if not get_trakt_indexer(ep_obj.series.indexer): return if app.USE_TRAKT: try: # URL parameters title = get_title_without_year(ep_obj.series.name, ep_obj.series.start_year) data = { 'shows': [{ 'title': title, 'year': ep_obj.series.start_year, 'ids': {}, }] } data['shows'][0]['ids'][get_trakt_indexer( ep_obj.series.indexer)] = ep_obj.series.indexerid # Add Season and Episode + Related Episodes data['shows'][0]['seasons'] = [{ 'number': ep_obj.season, 'episodes': [] }] for rel_ep_obj in [ep_obj] + ep_obj.related_episodes: data['shows'][0]['seasons'][0]['episodes'].append( {'number': rel_ep_obj.episode}) if app.TRAKT_SYNC_WATCHLIST: if app.TRAKT_REMOVE_SERIESLIST: sync.remove_from_watchlist(data) # update library sync.add_to_collection(data) except (TraktException, RequestException) as error: log.warning('Unable to update Trakt: {error!r}', {'error': error})
def add_episode_trakt_collection(self): """Add all existing episodes to Trakt collections. For episodes that have a media file (location) """ if app.TRAKT_SYNC and app.USE_TRAKT: main_db_con = db.DBConnection() statuses = [DOWNLOADED, ARCHIVED] sql_selection = 'SELECT s.indexer, s.startyear, s.indexer_id, s.show_name, e.season, e.episode ' \ 'FROM tv_episodes AS e, tv_shows AS s ' \ 'WHERE e.indexer = s.indexer AND s.indexer_id = e.showid ' \ "AND e.status in ({0}) AND e.location <> ''".format(','.join(['?'] * len(statuses))) sql_result = main_db_con.select(sql_selection, statuses) if sql_result: trakt_data = [] for cur_episode in sql_result: # Check if TRAKT supports that indexer if not get_trakt_indexer(cur_episode['indexer']): continue if not self._check_list(indexer=cur_episode['indexer'], indexer_id=cur_episode['indexer_id'], season=cur_episode['season'], episode=cur_episode['episode'], list_type='Collection'): log.info("Adding episode '{show}' {ep} to Trakt collection", { 'show': cur_episode['show_name'], 'ep': episode_num(cur_episode['season'], cur_episode['episode']) }) title = get_title_without_year(cur_episode['show_name'], cur_episode['startyear']) trakt_data.append((cur_episode['indexer_id'], cur_episode['indexer'], title, cur_episode['startyear'], cur_episode['season'], cur_episode['episode'])) if trakt_data: try: data = self.trakt_bulk_data_generate(trakt_data) self._request('sync/collection', data, method='POST') self._get_show_collection() except (TraktException, AuthException, TokenExpiredException) as error: log.info('Unable to add episodes to Trakt collection. Error: {error!r}', {'error': error})
def remove_episode_watchlist(self): """Remove episode from Trakt watchlist.""" if app.TRAKT_SYNC_WATCHLIST and app.USE_TRAKT: main_db_con = db.DBConnection() statuses = [DOWNLOADED, ARCHIVED] sql_selection = 'SELECT s.indexer, s.startyear, e.showid, s.show_name, e.season, e.episode ' \ 'FROM tv_episodes AS e, tv_shows AS s ' \ 'WHERE e.indexer = s.indexer ' \ 'AND s.indexer_id = e.showid AND e.status in ({0})'.format(','.join(['?'] * len(statuses))) sql_result = main_db_con.select(sql_selection, statuses) if sql_result: trakt_data = [] for cur_episode in sql_result: # Check if TRAKT supports that indexer if not get_trakt_indexer(cur_episode['indexer']): continue if self._check_list(indexer=cur_episode['indexer'], indexer_id=cur_episode['showid'], season=cur_episode['season'], episode=cur_episode['episode']): log.info("Removing episode '{show}' {ep} from Trakt watchlist", { 'show': cur_episode['show_name'], 'ep': episode_num(cur_episode['season'], cur_episode['episode']) }) title = get_title_without_year(cur_episode['show_name'], cur_episode['startyear']) trakt_data.append((cur_episode['showid'], cur_episode['indexer'], title, cur_episode['startyear'], cur_episode['season'], cur_episode['episode'])) if trakt_data: try: data = self.trakt_bulk_data_generate(trakt_data) self._request('sync/watchlist/remove', data, method='POST') self._get_episode_watchlist() except (TraktException, AuthException, TokenExpiredException) as error: log.info('Unable to remove episodes from Trakt watchlist. Error: {error!r}', { 'error': error })
def remove_show_trakt_library(self, show_obj): """Remove show from trakt library.""" if self.find_show(show_obj.indexerid, show_obj.indexer): # Check if TRAKT supports that indexer if not get_trakt_indexer(show_obj.indexer): return # URL parameters title = get_title_without_year(show_obj.name, show_obj.start_year) data = { 'shows': [ { 'title': title, 'year': show_obj.start_year, 'ids': {} } ] } data['shows'][0]['ids'][get_trakt_indexer(show_obj.indexer)] = show_obj.indexerid log.info("Removing '{show}' from Trakt library", {'show': show_obj.name}) # Remove all episodes from the Trakt collection for this show try: self.remove_episode_trakt_collection(filter_show=show_obj) except (TraktException, AuthException, TokenExpiredException) as error: log.info("Unable to remove all episodes from show '{show}' from Trakt library. Error: {error!r}", { 'show': show_obj.name, 'error': error }) try: self._request('sync/collection/remove', data, method='POST') except (TraktException, AuthException, TokenExpiredException) as error: log.info("Unable to remove show '{show}' from Trakt library. Error: {error!r}", { 'show': show_obj.name, 'error': error })
def add_show_trakt_library(self, show_obj): """Add show to trakt library.""" data = {} if not self.find_show(show_obj.indexerid, show_obj.indexer): # Check if TRAKT supports that indexer if not get_trakt_indexer(show_obj.indexer): return # URL parameters title = get_title_without_year(show_obj.name, show_obj.start_year) data = { 'shows': [{ 'title': title, 'year': show_obj.start_year, 'ids': {} }] } data['shows'][0]['ids'][get_trakt_indexer( show_obj.indexer)] = show_obj.indexerid if data: log.info("Adding show '{show}' to Trakt library", {'show': show_obj.name}) try: self._request('sync/collection', data, method='POST') except (TraktException, AuthException, TokenExpiredException) as error: log.info( "Unable to add show '{show}' to Trakt library. Error: {error!r}", { 'show': show_obj.name, 'error': error }) return
def add_show_watchlist(self): """Add show to Trakt watchlist. It will add all shows from Medusa library """ if app.TRAKT_SYNC_WATCHLIST and app.USE_TRAKT: if app.showList: trakt_data = [] for show_obj in app.showList: if not self._check_list(show_obj=show_obj, list_type='Show'): log.info("Adding show '{show}' to Trakt watchlist", {'show': show_obj.name}) title = get_title_without_year(show_obj.name, show_obj.start_year) show_el = {'title': title, 'year': show_obj.start_year, 'ids': {}} trakt_data.append(show_el) if trakt_data: try: data = {'shows': trakt_data} self._request('sync/watchlist', data, method='POST') except (TraktException, AuthException, TokenExpiredException) as error: log.info('Unable to add shows to Trakt watchlist. Error: {error!r}', {'error': error}) self._get_show_watchlist()
def update_library(ep_obj): """Send a request to trakt indicating that the given episode is part of our library. ep_obj: The Episode object to add to trakt """ # Check if TRAKT supports that indexer if not get_trakt_indexer(ep_obj.series.indexer): return # Create a trakt settings dict trakt_settings = { 'trakt_api_secret': app.TRAKT_API_SECRET, 'trakt_api_key': app.TRAKT_API_KEY, 'trakt_access_token': app.TRAKT_ACCESS_TOKEN, 'trakt_refresh_token': app.TRAKT_REFRESH_TOKEN } trakt_api = TraktApi(app.SSL_VERIFY, app.TRAKT_TIMEOUT, **trakt_settings) if app.USE_TRAKT: try: # URL parameters title = get_title_without_year(ep_obj.series.name, ep_obj.series.start_year) data = { 'shows': [{ 'title': title, 'year': ep_obj.series.start_year, 'ids': {}, }] } data['shows'][0]['ids'][get_trakt_indexer( ep_obj.series.indexer)] = ep_obj.series.indexerid if app.TRAKT_SYNC_WATCHLIST: if app.TRAKT_REMOVE_SERIESLIST: trakt_api.request('sync/watchlist/remove', data, method='POST') # Add Season and Episode + Related Episodes data['shows'][0]['seasons'] = [{ 'number': ep_obj.season, 'episodes': [] }] for relEp_Obj in [ep_obj] + ep_obj.related_episodes: data['shows'][0]['seasons'][0]['episodes'].append( {'number': relEp_Obj.episode}) if app.TRAKT_SYNC_WATCHLIST: if app.TRAKT_REMOVE_WATCHLIST: trakt_api.request('sync/watchlist/remove', data, method='POST') # update library trakt_api.request('sync/collection', data, method='POST') except (TokenExpiredException, TraktException, AuthException) as error: log.debug('Unable to update Trakt: {0}', error.message)
def update_watchlist(show_obj=None, s=None, e=None, data_show=None, data_episode=None, update='add'): """Send a request to trakt indicating that the given episode is part of our library. show_obj: The Series object to add to trakt s: season number e: episode number data_show: structured object of shows trakt type data_episode: structured object of episodes trakt type update: type o action add or remove """ # Check if TRAKT supports that indexer if not get_trakt_indexer(show_obj.indexer): return trakt_settings = { 'trakt_api_secret': app.TRAKT_API_SECRET, 'trakt_api_key': app.TRAKT_API_KEY, 'trakt_access_token': app.TRAKT_ACCESS_TOKEN, 'trakt_refresh_token': app.TRAKT_REFRESH_TOKEN } trakt_api = TraktApi(app.SSL_VERIFY, app.TRAKT_TIMEOUT, **trakt_settings) if app.USE_TRAKT: data = {} try: # URL parameters if show_obj is not None: title = get_title_without_year(show_obj.name, show_obj.start_year) data = { 'shows': [{ 'title': title, 'year': show_obj.start_year, 'ids': {}, }] } data['shows'][0]['ids'][get_trakt_indexer( show_obj.indexer)] = show_obj.indexerid elif data_show is not None: data.update(data_show) else: log.warning( "There's a coding problem contact developer. It's needed to be provided at" " least one of the two: data_show or show_obj", ) return False if data_episode is not None: data['shows'][0].update(data_episode) elif s is not None: # trakt URL parameters season = { 'season': [{ 'number': s, }] } if e is not None: # trakt URL parameters episode = {'episodes': [{'number': e}]} season['season'][0].update(episode) data['shows'][0].update(season) trakt_url = 'sync/watchlist' if update == 'remove': trakt_url += '/remove' trakt_api.request(trakt_url, data, method='POST') except (TokenExpiredException, TraktException, AuthException) as error: log.debug('Unable to update Trakt watchlist: {0}', error.message) return False return True