def test_cache(self, mocked_expired, execute_task): persist['auth_tokens'] = {'default': None} task = execute_task('test_search_cache') entry = task.find_entry(tvdb_id=73255) # Force tvdb lazy eval assert entry['afield'] with Session() as session: # Ensure search cache was added search_results = session.query(TVDBSearchResult).all() assert len(search_results) == 3 aliases = ['house', 'house m.d.', 'house md'] for search_result in search_results: assert search_result.series assert search_result.search in aliases # No requests should be sent as we restore from cache with mock.patch('requests.sessions.Session.request', side_effect=Exception('TVDB should restore from cache')) as _: lookup_series('house m.d.', session=session)
def test_cache(self, mocked_expired, execute_task): persist['auth_tokens'] = {'default': None} task = execute_task('test_search_cache') entry = task.find_entry(tvdb_id=73255) # Force tvdb lazy eval assert entry['afield'] with Session() as session: # Ensure search cache was added search_results = session.query(TVDBSearchResult).all() assert len(search_results) == 3 aliases = ['house', 'house m.d.', 'house md'] for search_result in search_results: assert search_result.series assert search_result.search in aliases # No requests should be sent as we restore from cache with mock.patch('requests.sessions.Session.request', side_effect=Exception( 'TVDB should restore from cache')) as _: lookup_series('house m.d.', session=session)
def get(self, search, session=None): try: tvdb_id = int(search) except ValueError: tvdb_id = None try: if tvdb_id: result = lookup_series(tvdb_id=tvdb_id, session=session) else: result = lookup_series(name=search, session=session) except LookupError as e: return {'status': 'error', 'message': e.args[0]}, 404 return jsonify(result.to_dict())
def lookup_myepisodes_id(self, entry, opener, session): """Populates myepisodes_id field for an entry, and returns the id. Call will also set entry field `myepisode_id` if successful. Return: myepisode id Raises: LookupError if entry does not have field series_name """ # Don't need to look it up if we already have it. if entry.get("myepisodes_id"): return entry["myepisodes_id"] if not entry.get("series_name"): raise LookupError("Cannot lookup myepisodes id for entries without series_name") series_name = entry["series_name"] # First check if we already have a myepisodes id stored for this series myepisodes_info = ( session.query(MyEpisodesInfo).filter(MyEpisodesInfo.series_name == series_name.lower()).first() ) if myepisodes_info: entry["myepisodes_id"] = myepisodes_info.myepisodes_id return myepisodes_info.myepisodes_id # Get the series name from thetvdb to increase match chance on myepisodes if entry.get("series_name_tvdb"): query_name = entry["series_name_tvdb"] else: try: series = lookup_series(name=series_name, tvdb_id=entry.get("thetvdb_id")) query_name = series.seriesname except LookupError as e: log.warning("Unable to lookup series `%s` from tvdb, using raw name." % series_name) query_name = series_name baseurl = urllib2.Request("http://myepisodes.com/search.php?") params = urllib.urlencode({"tvshow": query_name, "action": "Search myepisodes.com"}) try: con = opener.open(baseurl, params) txt = con.read() except urllib2.URLError as e: log.error("Error searching for myepisodes id: %s" % e) matchObj = re.search(r'&showid=([0-9]*)">' + query_name + "</a>", txt, re.MULTILINE | re.IGNORECASE) if matchObj: myepisodes_id = matchObj.group(1) db_item = session.query(MyEpisodesInfo).filter(MyEpisodesInfo.myepisodes_id == myepisodes_id).first() if db_item: log.info( "Changing name to `%s` for series with myepisodes_id %s" % (series_name.lower(), myepisodes_id) ) db_item.series_name = series_name.lower() else: session.add(MyEpisodesInfo(series_name.lower(), myepisodes_id)) entry["myepisodes_id"] = myepisodes_id return myepisodes_id
def items(self): if self._items is None: try: req = TVDBRequest(username=self.config['username'], account_id=self.config['account_id']).get( 'user/favorites') series_ids = [int(f_id) for f_id in req['favorites'] if f_id != ''] except RequestException as e: raise PluginError('Error retrieving favorites from thetvdb: %s' % str(e)) self._items = [] for series_id in series_ids: # Lookup the series name from the id try: series = lookup_series(tvdb_id=series_id) except LookupError as e: log.error('Error looking up %s from thetvdb: %s' % (series_id, e.args[0])) else: series_name = series.name if self.config.get('strip_dates'): # Remove year from end of series name if present series_name, _ = split_title_year(series_name) entry = Entry() entry['title'] = entry['series_name'] = series_name entry['url'] = 'http://thetvdb.com/index.php?tab=series&id={}'.format(str(series.id)) entry['tvdb_id'] = str(series.id) self._items.append(entry) return self._items
def items(self): if self._items is None: try: req = TVDBRequest( username=self.config['username'], account_id=self.config['account_id']).get('user/favorites') series_ids = [ int(f_id) for f_id in req['favorites'] if f_id != '' ] except RequestException as e: raise PluginError( 'Error retrieving favorites from thetvdb: %s' % str(e)) self._items = [] for series_id in series_ids: # Lookup the series name from the id try: series = lookup_series(tvdb_id=series_id) except LookupError as e: log.error('Error looking up %s from thetvdb: %s' % (series_id, e.args[0])) else: series_name = series.name if self.config.get('strip_dates'): # Remove year from end of series name if present series_name, _ = split_title_year(series_name) entry = Entry() entry['title'] = entry['series_name'] = series_name entry[ 'url'] = 'http://thetvdb.com/index.php?tab=series&id={}'.format( str(series.id)) entry['tvdb_id'] = str(series.id) self._items.append(entry) return self._items
def get(self, search, session=None): try: tvdb_id = int(search) except ValueError: tvdb_id = None try: if tvdb_id: result = lookup_series(tvdb_id=tvdb_id, session=session) else: result = lookup_series(name=search, session=session) except LookupError as e: return {'status': 'error', 'message': e.args[0] }, 404 return jsonify(result.to_dict())
def lookup_myepisodes_id(self, entry, opener, session): """Populates myepisodes_id field for an entry, and returns the id. Call will also set entry field `myepisode_id` if successful. Return: myepisode id Raises: LookupError if entry does not have field series_name """ # Don't need to look it up if we already have it. if entry.get('myepisodes_id'): return entry['myepisodes_id'] if not entry.get('series_name'): raise LookupError('Cannot lookup myepisodes id for entries without series_name') series_name = entry['series_name'] # First check if we already have a myepisodes id stored for this series myepisodes_info = session.query(MyEpisodesInfo).\ filter(MyEpisodesInfo.series_name == series_name.lower()).first() if myepisodes_info: entry['myepisodes_id'] = myepisodes_info.myepisodes_id return myepisodes_info.myepisodes_id # Get the series name from thetvdb to increase match chance on myepisodes if entry.get('tvdb_series_name'): query_name = entry['tvdb_series_name'] else: try: series = lookup_series(name=series_name, tvdb_id=entry.get('tvdb_id')) query_name = series.seriesname except LookupError as e: log.warning('Unable to lookup series `%s` from tvdb, using raw name.' % series_name) query_name = series_name baseurl = request.Request('http://www.myepisodes.com/search.php?') params = parse.urlencode({'tvshow': query_name, 'action': 'Search myepisodes.com'}) try: con = opener.open(baseurl, params) txt = con.read() except URLError as e: log.error('Error searching for myepisodes id: %s' % e) matchObj = re.search(r'&showid=([0-9]*)">' + query_name + '</a>', txt, re.MULTILINE | re.IGNORECASE) if matchObj: myepisodes_id = matchObj.group(1) db_item = session.query(MyEpisodesInfo).filter(MyEpisodesInfo.myepisodes_id == myepisodes_id).first() if db_item: log.info('Changing name to `%s` for series with myepisodes_id %s' % (series_name.lower(), myepisodes_id)) db_item.series_name = series_name.lower() else: session.add(MyEpisodesInfo(series_name.lower(), myepisodes_id)) entry['myepisodes_id'] = myepisodes_id return myepisodes_id
def get(self, title, session=None): args = series_parser.parse_args() try: tvdb_id = int(title) except ValueError: tvdb_id = None try: if tvdb_id: series = lookup_series(tvdb_id=tvdb_id, session=session) else: series = lookup_series(name=title, session=session) except LookupError as e: return {'status': 'error', 'message': e.args[0]}, 404 result = series.to_dict() if args.get('include_actors'): result['actors'] = series.actors return jsonify(result)
def lazy_series_lookup(self, entry): """Does the lookup for this entry and populates the entry fields.""" try: with Session(expire_on_commit=False) as session: series = lookup_series(entry.get('series_name', eval_lazy=False), tvdb_id=entry.get('tvdb_id', eval_lazy=False), session=session) entry.update_using_map(self.series_map, series) except LookupError as e: log.debug('Error looking up tvdb series information for %s: %s' % (entry['title'], e.args[0]))
def lazy_series_lookup(self, entry, field): """Does the lookup for this entry and populates the entry fields.""" try: series = lookup_series(entry.get('series_name', eval_lazy=False), tvdb_id=entry.get('thetvdb_id', eval_lazy=False)) entry.update_using_map(self.series_map, series) except LookupError, e: log.debug('Error looking up tvdb series information for %s: %s' % (entry['title'], e.message)) entry.unregister_lazy_fields(self.series_map, self.lazy_series_lookup) # Also clear episode fields, since episode lookup cannot succeed without series lookup entry.unregister_lazy_fields(self.episode_map, self.lazy_episode_lookup)
def get(self, title, session=None): args = series_parser.parse_args() try: tvdb_id = int(title) except ValueError: tvdb_id = None try: if tvdb_id: series = lookup_series(tvdb_id=tvdb_id, session=session) else: series = lookup_series(name=title, session=session) except LookupError as e: return {'status': 'error', 'message': e.args[0] }, 404 result = series.to_dict() if args.get('include_actors'): result['actors'] = series.actors return jsonify(result)
def series_lookup(self, entry, field_map, session=None): try: series = lookup_series(entry.get('series_name', eval_lazy=False), tvdb_id=entry.get('tvdb_id', eval_lazy=False), session=session) entry.update_using_map(field_map, series) except LookupError as e: log.debug('Error looking up tvdb series information for %s: %s' % (entry['title'], e.args[0])) return entry
def series_lookup(self, entry, field_map, session=None): try: series = lookup_series( entry.get('series_name', eval_lazy=False), tvdb_id=entry.get('tvdb_id', eval_lazy=False), session=session ) entry.update_using_map(field_map, series) except LookupError as e: log.debug('Error looking up tvdb series information for %s: %s' % (entry['title'], e.args[0])) return entry
def on_task_input(self, task, config, session=None): account_id = str(config['account_id']) # Get the cache for this user user_favorites = session.query(ThetvdbFavorites).filter( ThetvdbFavorites.account_id == account_id).first() if user_favorites and user_favorites.updated > datetime.now( ) - timedelta(minutes=10): log.debug( 'Using cached thetvdb favorite series information for account ID %s' % account_id) else: try: url = 'http://thetvdb.com/api/User_Favorites.php?accountid=%s' % account_id log.debug('requesting %s' % url) data = ElementTree.fromstring(urlopener(url, log).read()) favorite_ids = [] for i in data.findall('Series'): if i.text: favorite_ids.append(i.text) except (urllib2.URLError, IOError, AttributeError): import traceback # If there are errors getting the favorites or parsing the xml, fall back on cache log.error( 'Error retrieving favorites from thetvdb, using cache.') log.debug(traceback.format_exc()) else: # Successfully updated from tvdb, update the database log.debug('Successfully updated favorites from thetvdb.com') if not user_favorites: user_favorites = ThetvdbFavorites(account_id, favorite_ids) else: user_favorites.series_ids = favorite_ids user_favorites.updated = datetime.now() session.merge(user_favorites) if not user_favorites.series_ids: log.warning('Didn\'t find any thetvdb.com favorites.') return # Construct list of entries with our series names entries = [] for series_id in user_favorites.series_ids: # Lookup the series name from the id try: series = lookup_series(tvdb_id=series_id) except LookupError as e: log.error('Error looking up %s from thetvdb: %s' % (series_id, e.message)) else: series_name = series.seriesname if config.get('strip_dates'): # Remove year from end of series name if present series_name = re.sub(r'\s+\(\d{4}\)$', '', series_name) entries.append(Entry(series_name, '', tvdb_id=series.id)) return entries
def on_task_input(self, task, config): account_id = str(config['account_id']) favorite_ids = [] # Get the cache for this user with Session() as session: user_favorites = session.query(ThetvdbFavorites).filter(ThetvdbFavorites.account_id == account_id).first() if user_favorites: favorite_ids = user_favorites.series_ids if user_favorites and user_favorites.updated > datetime.now() - timedelta(minutes=10): log.debug('Using cached thetvdb favorite series information for account ID %s' % account_id) else: try: url = 'http://thetvdb.com/api/User_Favorites.php?accountid=%s' % account_id log.debug('requesting %s' % url) data = ElementTree.fromstring(urlopener(url, log).read()) favorite_ids = [] for i in data.findall('Series'): if i.text: favorite_ids.append(i.text) except (urllib2.URLError, IOError, AttributeError): import traceback # If there are errors getting the favorites or parsing the xml, fall back on cache log.error('Error retrieving favorites from thetvdb, using cache.') log.debug(traceback.format_exc()) else: # Successfully updated from tvdb, update the database log.debug('Successfully updated favorites from thetvdb.com') if not user_favorites: user_favorites = ThetvdbFavorites(account_id, favorite_ids) else: user_favorites.series_ids = favorite_ids user_favorites.updated = datetime.now() session.merge(user_favorites) if not favorite_ids: log.warning('Didn\'t find any thetvdb.com favorites.') return # Construct list of entries with our series names entries = [] for series_id in favorite_ids: # Lookup the series name from the id try: series = lookup_series(tvdb_id=series_id) except LookupError as e: log.error('Error looking up %s from thetvdb: %s' % (series_id, e.args[0])) else: series_name = series.seriesname if config.get('strip_dates'): # Remove year from end of series name if present series_name = re.sub(r'\s+\(\d{4}\)$', '', series_name) entries.append(Entry(series_name, '', tvdb_id=series.id)) return entries
def lazy_series_lookup(self, entry, field): """Does the lookup for this entry and populates the entry fields.""" try: with Session(expire_on_commit=False) as session: series = lookup_series(entry.get('series_name', eval_lazy=False), tvdb_id=entry.get('tvdb_id', eval_lazy=False), session=session) entry.update_using_map(self.series_map, series) except LookupError as e: log.debug('Error looking up tvdb series information for %s: %s' % (entry['title'], e.args[0])) entry.unregister_lazy_fields(self.series_map, self.lazy_series_lookup) # Also clear episode fields, since episode lookup cannot succeed without series lookup entry.unregister_lazy_fields(self.episode_map, self.lazy_episode_lookup) return entry[field]
def on_task_input(self, task, config, session=None): account_id = str(config["account_id"]) # Get the cache for this user user_favorites = session.query(ThetvdbFavorites).filter(ThetvdbFavorites.account_id == account_id).first() if user_favorites and user_favorites.updated > datetime.now() - timedelta(minutes=10): log.debug("Using cached thetvdb favorite series information for account ID %s" % account_id) else: try: url = "http://thetvdb.com/api/User_Favorites.php?accountid=%s" % account_id log.debug("requesting %s" % url) data = BeautifulStoneSoup(urlopener(url, log)) favorite_ids = [] for i in data.favorites.findAll("series", recursive=False): if i.string: favorite_ids.append(i.string) except (urllib2.URLError, IOError, AttributeError): import traceback # If there are errors getting the favorites or parsing the xml, fall back on cache log.error("Error retrieving favorites from thetvdb, using cache.") log.debug(traceback.format_exc()) else: # Successfully updated from tvdb, update the database log.debug("Successfully updated favorites from thetvdb.com") if not user_favorites: user_favorites = ThetvdbFavorites(account_id, favorite_ids) else: user_favorites.series_ids = favorite_ids user_favorites.updated = datetime.now() session.merge(user_favorites) if not user_favorites.series_ids: log.warning("Didn't find any thetvdb.com favorites.") return # Construct list of entries with our series names entries = [] for series_id in user_favorites.series_ids: # Lookup the series name from the id try: series = lookup_series(tvdb_id=series_id) except LookupError as e: log.error("Error looking up %s from thetvdb: %s" % (series_id, e.message)) else: series_name = series.seriesname if config.get("strip_dates"): # Remove year from end of series name if present series_name = re.sub(r"\s+\(\d{4}\)$", "", series_name) entries.append(Entry(series_name, "", tvdb_id=series.id)) return entries
def on_task_input(self, task, config, session=None): # Get the cache for this user user_favorites = session.query(TVDBUserFavorite).filter( TVDBUserFavorite.username == config['username']).first() if not user_favorites: user_favorites = TVDBUserFavorite(username=config['username']) session.add(user_favorites) if user_favorites.updated and user_favorites.updated > datetime.now( ) - timedelta(minutes=10): log.debug( 'Using cached thetvdb favorite series information for account %s' % config['username']) else: try: req = TVDBRequest( username=config['username'], account_id=config['account_id']).get('user/favorites') user_favorites.series_ids = [ int(f_id) for f_id in req['favorites'] ] except RequestException as e: log.error('Error retrieving favorites from thetvdb: %s' % str(e)) # Successfully updated from tvdb, update the database user_favorites.updated = datetime.now() # Construct list of entries with our series names entries = [] for series_id in user_favorites.series_ids: # Lookup the series name from the id try: series = lookup_series(tvdb_id=series_id) except LookupError as e: log.error('Error looking up %s from thetvdb: %s' % (series_id, e.args[0])) else: series_name = series.name if config.get('strip_dates'): # Remove year from end of series name if present series_name = re.sub(r'\s+\(\d{4}\)$', '', series_name) entries.append(Entry(series_name, '', tvdb_id=series.id)) return entries
def lookup_myepisodes_id(self, entry, opener, session): """Populates myepisodes_id field for an entry, and returns the id. Call will also set entry field `myepisode_id` if successful. Return: myepisode id Raises: LookupError if entry does not have field series_name """ # Don't need to look it up if we already have it. if entry.get('myepisodes_id'): return entry['myepisodes_id'] if not entry.get('series_name'): raise LookupError( 'Cannot lookup myepisodes id for entries without series_name') series_name = entry['series_name'] # First check if we already have a myepisodes id stored for this series myepisodes_info = session.query(MyEpisodesInfo).filter( MyEpisodesInfo.series_name == series_name.lower()).first() if myepisodes_info: entry['myepisodes_id'] = myepisodes_info.myepisodes_id return myepisodes_info.myepisodes_id # Get the series name from thetvdb to increase match chance on myepisodes if entry.get('series_name_tvdb'): query_name = entry['series_name_tvdb'] else: try: series = lookup_series(name=series_name, tvdb_id=entry.get('thetvdb_id')) query_name = series.seriesname except LookupError, e: log.warning( 'Unable to lookup series `%s` from tvdb, using raw name.' % series_name) query_name = series_name
def lookup_myepisodes_id(self, entry, opener, session): """Populates myepisodes_id field for an entry, and returns the id. Call will also set entry field `myepisode_id` if successful. Return: myepisode id Raises: LookupError if entry does not have field series_name """ # Don't need to look it up if we already have it. if entry.get('myepisodes_id'): return entry['myepisodes_id'] if not entry.get('series_name'): raise LookupError('Cannot lookup myepisodes id for entries without series_name') series_name = entry['series_name'] # First check if we already have a myepisodes id stored for this series myepisodes_info = session.query(MyEpisodesInfo).filter(MyEpisodesInfo.series_name == series_name.lower()).first() if myepisodes_info: entry['myepisodes_id'] = myepisodes_info.myepisodes_id return myepisodes_info.myepisodes_id # Get the series name from thetvdb to increase match chance on myepisodes if entry.get('series_name_tvdb'): query_name = entry['series_name_tvdb'] else: try: series = lookup_series(name=series_name, tvdb_id=entry.get('thetvdb_id')) query_name = series.seriesname except LookupError, e: log.warning('Unable to lookup series `%s` from tvdb, using raw name.' % series_name) query_name = series_name
def on_task_input(self, task, config, session=None): # Get the cache for this user user_favorites = session.query(TVDBUserFavorite).filter(TVDBUserFavorite.username == config['username']).first() if not user_favorites: user_favorites = TVDBUserFavorite(username=config['username']) session.add(user_favorites) if user_favorites.updated and user_favorites.updated > datetime.now() - timedelta(minutes=10): log.debug('Using cached thetvdb favorite series information for account %s' % config['username']) else: try: req = TVDBRequest(username=config['username'], account_id=config['account_id']).get('user/favorites') user_favorites.series_ids = [int(f_id) for f_id in req['favorites']] except RequestException as e: log.error('Error retrieving favorites from thetvdb: %s' % str(e)) # Successfully updated from tvdb, update the database user_favorites.updated = datetime.now() # Construct list of entries with our series names entries = [] for series_id in user_favorites.series_ids: # Lookup the series name from the id try: series = lookup_series(tvdb_id=series_id) except LookupError as e: log.error('Error looking up %s from thetvdb: %s' % (series_id, e.args[0])) else: series_name = series.name if config.get('strip_dates'): # Remove year from end of series name if present series_name = re.sub(r'\s+\(\d{4}\)$', '', series_name) entries.append(Entry(series_name, '', tvdb_id=series.id)) return entries
def on_task_input(self, task, config): """Creates an entry for each item in your uoccin watchlist. Example:: from_uoccin: path: /path/to/gdrive/uoccin type: series tags: [ 'favorite', 'hires' ] check_tags: all Options path and type are required while the others are for filtering: - 'any' will include all the items marked with one or more tags in the list - 'all' will only include the items marked with all the listed tags - 'none' will only include the items not marked with any of the listed tags. The entries created will have a valid imdb/tvdb url and id. """ imdb_lookup = plugin.get_plugin_by_name('imdb_lookup').instance udata = load_uoccin_data(config['path']) section = udata['movies'] if config['type'] == 'movies' else udata['series'] entries = [] for eid, itm in list(section.items()): if not itm['watchlist']: continue if 'tags' in config: n = len(set(config['tags']) & set(itm.get('tags', []))) if config['check_tags'] == 'any' and n <= 0: continue if config['check_tags'] == 'all' and n != len(config['tags']): continue if config['check_tags'] == 'none' and n > 0: continue if config['type'] == 'movies': entry = Entry() entry['url'] = 'http://www.imdb.com/title/' + eid entry['imdb_id'] = eid if itm['name'] != 'N/A': entry['title'] = itm['name'] else: try: imdb_lookup.lookup(entry) except plugin.PluginError as e: self.log.trace('entry %s imdb failed (%s)' % (entry['imdb_id'], e.value)) continue entry['title'] = entry.get('imdb_name') if 'tags' in itm: entry['uoccin_tags'] = itm['tags'] if entry.isvalid(): entries.append(entry) else: self.log.debug('Invalid entry created? %s' % entry) else: sname = itm['name'] try: sname = lookup_series(tvdb_id=eid).seriesname except LookupError: self.log.warning('Unable to lookup series %s from tvdb, using raw name.' % eid) surl = 'http://thetvdb.com/?tab=series&id=' + eid if config['type'] == 'series': entry = Entry() entry['url'] = surl entry['title'] = sname entry['tvdb_id'] = eid if 'tags' in itm: entry['uoccin_tags'] = itm['tags'] if entry.isvalid(): entries.append(entry) else: self.log.debug('Invalid entry created? %s' % entry) elif config['ep_flags'] == 'collected': slist = itm.get('collected', {}) for sno in list(slist.keys()): for eno in slist[sno]: entry = Entry() entry['url'] = surl entry['title'] = '%s S%02dE%02d' % (sname, int(sno), int(eno)) entry['tvdb_id'] = eid if entry.isvalid(): entries.append(entry) else: self.log.debug('Invalid entry created? %s' % entry) else: slist = itm.get('watched', {}) for sno in list(slist.keys()): for eno in slist[sno]: entry = Entry() entry['url'] = surl entry['title'] = '%s S%02dE%02d' % (sname, int(sno), eno) entry['tvdb_id'] = eid if entry.isvalid(): entries.append(entry) else: self.log.debug('Invalid entry created? %s' % entry) entries.sort(key=lambda x: x['title']) return entries
def process(self): imdb_lookup = plugin.get_plugin_by_name('imdb_lookup').instance self.changes.sort() udata = load_uoccin_data(self.folder) for line in self.changes: tmp = line.split('|') typ = tmp[1] tid = tmp[2] fld = tmp[3] val = tmp[4] self.log.verbose( 'processing: type=%s, target=%s, field=%s, value=%s' % (typ, tid, fld, val)) if typ == 'movie': # default mov = udata['movies'].setdefault( tid, { 'name': 'N/A', 'watchlist': False, 'collected': False, 'watched': False }) # movie title is unknown at this time fake = Entry() fake['url'] = 'http://www.imdb.com/title/' + tid fake['imdb_id'] = tid try: imdb_lookup.lookup(fake) mov['name'] = fake.get('imdb_name') except plugin.PluginError: self.log.warning( 'Unable to lookup movie %s from imdb, using raw name.' % tid) # setting if fld == 'watchlist': mov['watchlist'] = val == 'true' elif fld == 'collected': mov['collected'] = val == 'true' elif fld == 'watched': mov['watched'] = val == 'true' elif fld == 'tags': mov['tags'] = re.split(',\s*', val) elif fld == 'subtitles': mov['subtitles'] = re.split(',\s*', val) elif fld == 'rating': mov['rating'] = int(val) # cleaning if not (mov['watchlist'] or mov['collected'] or mov['watched']): self.log.verbose('deleting unused section: movies\%s' % tid) udata['movies'].pop(tid) elif typ == 'series': tmp = tid.split('.') sid = tmp[0] sno = tmp[1] if len(tmp) > 2 else None eno = tmp[2] if len(tmp) > 2 else None # default ser = udata['series'].setdefault( sid, { 'name': 'N/A', 'watchlist': False, 'collected': {}, 'watched': {} }) # series name is unknown at this time try: series = lookup_series(tvdb_id=sid) ser['name'] = series.name except LookupError: self.log.warning( 'Unable to lookup series %s from tvdb, using raw name.' % sid) # setting if fld == 'watchlist': ser['watchlist'] = val == 'true' elif fld == 'tags': ser['tags'] = re.split(',\s*', val) elif fld == 'rating': ser['rating'] = int(val) elif sno is None or eno is None: self.log.warning( 'invalid line "%s": season and episode numbers are required' % line) elif fld == 'collected': season = ser['collected'].setdefault(sno, {}) if val == 'true': season.setdefault(eno, []) else: if eno in season: season.pop(eno) if not season: self.log.verbose( 'deleting unused section: series\%s\collected\%s' % (sid, sno)) ser['collected'].pop(sno) elif fld == 'subtitles': ser['collected'].setdefault(sno, {})[eno] = re.split( ',\s*', val) elif fld == 'watched': season = ser['watched'].setdefault(sno, []) if val == 'true': season = ser['watched'][sno] = list( set(season) | set([int(eno)])) elif int(eno) in season: season.remove(int(eno)) season.sort() if not season: self.log.debug( 'deleting unused section: series\%s\watched\%s' % (sid, sno)) ser['watched'].pop(sno) # cleaning if not (ser['watchlist'] or ser['collected'] or ser['watched']): self.log.debug('deleting unused section: series\%s' % sid) udata['series'].pop(sid) else: self.log.warning('invalid element type "%s"' % typ) # save the updated uoccin.json ufile = os.path.join(self.folder, 'uoccin.json') try: text = json.dumps(udata, sort_keys=True, indent=4, separators=(',', ': ')) with open(ufile, 'w') as f: f.write(text) except Exception as err: self.log.debug('error writing %s: %s' % (ufile, err)) raise plugin.PluginError('error writing %s: %s' % (ufile, err))
def on_task_input(self, task, config): """Creates an entry for each item in your uoccin watchlist. Example:: from_uoccin: path: /path/to/gdrive/uoccin type: series tags: [ 'favorite', 'hires' ] check_tags: all Options path and type are required while the others are for filtering: - 'any' will include all the items marked with one or more tags in the list - 'all' will only include the items marked with all the listed tags - 'none' will only include the items not marked with any of the listed tags. The entries created will have a valid imdb/tvdb url and id. """ imdb_lookup = plugin.get_plugin_by_name('imdb_lookup').instance udata = load_uoccin_data(config['path']) section = udata['movies'] if config['type'] == 'movies' else udata[ 'series'] entries = [] for eid, itm in list(section.items()): if not itm['watchlist']: continue if 'tags' in config: n = len(set(config['tags']) & set(itm.get('tags', []))) if config['check_tags'] == 'any' and n <= 0: continue if config['check_tags'] == 'all' and n != len(config['tags']): continue if config['check_tags'] == 'none' and n > 0: continue if config['type'] == 'movies': entry = Entry() entry['url'] = 'http://www.imdb.com/title/' + eid entry['imdb_id'] = eid if itm['name'] != 'N/A': entry['title'] = itm['name'] else: try: imdb_lookup.lookup(entry) except plugin.PluginError as e: self.log.trace('entry %s imdb failed (%s)' % (entry['imdb_id'], e.value)) continue entry['title'] = entry.get('imdb_name') if 'tags' in itm: entry['uoccin_tags'] = itm['tags'] if entry.isvalid(): entries.append(entry) else: self.log.debug('Invalid entry created? %s' % entry) else: sname = itm['name'] try: sname = lookup_series(tvdb_id=eid).seriesname except LookupError: self.log.warning( 'Unable to lookup series %s from tvdb, using raw name.' % eid) surl = 'http://thetvdb.com/?tab=series&id=' + eid if config['type'] == 'series': entry = Entry() entry['url'] = surl entry['title'] = sname entry['tvdb_id'] = eid if 'tags' in itm: entry['uoccin_tags'] = itm['tags'] if entry.isvalid(): entries.append(entry) else: self.log.debug('Invalid entry created? %s' % entry) elif config['ep_flags'] == 'collected': slist = itm.get('collected', {}) for sno in list(slist.keys()): for eno in slist[sno]: entry = Entry() entry['url'] = surl entry['title'] = '%s S%02dE%02d' % ( sname, int(sno), int(eno)) entry['tvdb_id'] = eid if entry.isvalid(): entries.append(entry) else: self.log.debug('Invalid entry created? %s' % entry) else: slist = itm.get('watched', {}) for sno in list(slist.keys()): for eno in slist[sno]: entry = Entry() entry['url'] = surl entry['title'] = '%s S%02dE%02d' % (sname, int(sno), eno) entry['tvdb_id'] = eid if entry.isvalid(): entries.append(entry) else: self.log.debug('Invalid entry created? %s' % entry) entries.sort(key=lambda x: x['title']) return entries
def process(self): imdb_lookup = plugin.get_plugin_by_name('imdb_lookup').instance self.changes.sort() udata = load_uoccin_data(self.folder) for line in self.changes: tmp = line.split('|') typ = tmp[1] tid = tmp[2] fld = tmp[3] val = tmp[4] self.log.verbose('processing: type=%s, target=%s, field=%s, value=%s' % (typ, tid, fld, val)) if typ == 'movie': # default mov = udata['movies'].setdefault(tid, {'name':'N/A', 'watchlist':False, 'collected':False, 'watched':False}) # movie title is unknown at this time fake = Entry() fake['url'] = 'http://www.imdb.com/title/' + tid fake['imdb_id'] = tid try: imdb_lookup.lookup(fake) mov['name'] = fake.get('imdb_name') except plugin.PluginError: self.log.warning('Unable to lookup movie %s from imdb, using raw name.' % tid) # setting if fld == 'watchlist': mov['watchlist'] = val == 'true' elif fld == 'collected': mov['collected'] = val == 'true' elif fld == 'watched': mov['watched'] = val == 'true' elif fld == 'tags': mov['tags'] = re.split(',\s*', val) elif fld == 'subtitles': mov['subtitles'] = re.split(',\s*', val) elif fld == 'rating': mov['rating'] = int(val) # cleaning if not (mov['watchlist'] or mov['collected'] or mov['watched']): self.log.verbose('deleting unused section: movies\%s' % tid) udata['movies'].pop(tid) elif typ == 'series': tmp = tid.split('.') sid = tmp[0] sno = tmp[1] if len(tmp) > 2 else None eno = tmp[2] if len(tmp) > 2 else None # default ser = udata['series'].setdefault(sid, {'name':'N/A', 'watchlist':False, 'collected':{}, 'watched':{}}) # series name is unknown at this time try: series = lookup_series(tvdb_id=sid) ser['name'] = series.seriesname except LookupError: self.log.warning('Unable to lookup series %s from tvdb, using raw name.' % sid) # setting if fld == 'watchlist': ser['watchlist'] = val == 'true' elif fld == 'tags': ser['tags'] = re.split(',\s*', val) elif fld == 'rating': ser['rating'] = int(val) elif sno is None or eno is None: self.log.warning('invalid line "%s": season and episode numbers are required' % line) elif fld == 'collected': season = ser['collected'].setdefault(sno, {}) if val == 'true': season.setdefault(eno, []) else: if eno in season: season.pop(eno) if not season: self.log.verbose('deleting unused section: series\%s\collected\%s' % (sid, sno)) ser['collected'].pop(sno) elif fld == 'subtitles': ser['collected'].setdefault(sno, {})[eno] = re.split(',\s*', val) elif fld == 'watched': season = ser['watched'].setdefault(sno, []) if val == 'true': season = ser['watched'][sno] = list(set(season) | set([int(eno)])) elif int(eno) in season: season.remove(int(eno)) season.sort() if not season: self.log.debug('deleting unused section: series\%s\watched\%s' % (sid, sno)) ser['watched'].pop(sno) # cleaning if not (ser['watchlist'] or ser['collected'] or ser['watched']): self.log.debug('deleting unused section: series\%s' % sid) udata['series'].pop(sid) else: self.log.warning('invalid element type "%s"' % typ) # save the updated uoccin.json ufile = os.path.join(self.folder, 'uoccin.json') try: text = json.dumps(udata, sort_keys=True, indent=4, separators=(',', ': ')) with open(ufile, 'w') as f: f.write(text) except Exception as err: self.log.debug('error writing %s: %s' % (ufile, err)) raise plugin.PluginError('error writing %s: %s' % (ufile, err))