Example #1
0
    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')):
                lookup_series('house m.d.', session=session)
Example #2
0
    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')):
                lookup_series('house m.d.', session=session)
Example #3
0
    def get(self, title, session=None):
        args = series_parser.parse_args()
        language = args['language']

        try:
            tvdb_id = int(title)
        except ValueError:
            tvdb_id = None

        kwargs = {'session': session,
                  'language': language}

        if tvdb_id:
            kwargs['tvdb_id'] = tvdb_id
        else:
            kwargs['name'] = title

        try:
            series = lookup_series(**kwargs)
        except LookupError as e:
            raise NotFoundError(e.args[0])

        result = series.to_dict()
        if args.get('include_actors'):
            result['actors'] = series.actors
        return jsonify(result)
Example #4
0
 def items(self):
     if self._items is None:
         try:
             req = plugin_api_tvdb.TVDBRequest(
                 username=self.config['username'],
                 account_id=self.config['account_id'],
                 api_key=self.config['api_key']).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 = plugin_api_tvdb.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
Example #5
0
    def get(self, title, session=None):
        """TheTVDB series lookup"""
        args = series_parser.parse_args()
        language = args['language']

        try:
            tvdb_id = int(title)
        except ValueError:
            tvdb_id = None

        kwargs = {'session': session,
                  'language': language}

        if tvdb_id:
            kwargs['tvdb_id'] = tvdb_id
        else:
            kwargs['name'] = title

        try:
            series = lookup_series(**kwargs)
        except LookupError as e:
            raise NotFoundError(e.args[0])

        result = series.to_dict()
        if args.get('include_actors'):
            result['actors'] = series.actors
        return jsonify(result)
Example #6
0
 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
Example #7
0
    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.name
            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
Example #8
0
    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)
Example #9
0
    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)
Example #10
0
 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
Example #11
0
 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
Example #12
0
    def on_task_input(self, task, config):
        """Creates an entry for each item in your uoccin watchlist.

        Example::
            
            uoccin_emit:
              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).name
                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
Example #13
0
    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.name
            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
Example #14
0
 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))
Example #15
0
 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))
Example #16
0
    def on_task_input(self, task, config):
        """Creates an entry for each item in your uoccin watchlist.

        Example::
            
            uoccin_emit:
              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).name
                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