Exemplo n.º 1
0
    def _ep_data(self, ep_obj):
        """
        Creates an elementTree XML structure for a MediaBrowser style episode.xml
        and returns the resulting data object.

        show_obj: a TVShow instance to create the NFO for
        """

        eps_to_write = [ep_obj] + ep_obj.relatedEps

        persons_dict = {}
        persons_dict['Director'] = []
        persons_dict['GuestStar'] = []
        persons_dict['Writer'] = []

        indexer_lang = ep_obj.show.lang

        try:
            lINDEXER_API_PARMS = sickbeard.indexerApi(ep_obj.show.indexer).api_params.copy()

            lINDEXER_API_PARMS['actors'] = True

            if indexer_lang and not indexer_lang == 'en':
                lINDEXER_API_PARMS['language'] = indexer_lang

            if ep_obj.show.dvdorder != 0:
                lINDEXER_API_PARMS['dvdorder'] = True

            t = sickbeard.indexerApi(ep_obj.show.indexer).indexer(**lINDEXER_API_PARMS)

            myShow = t[ep_obj.show.indexerid]
        except sickbeard.indexer_shownotfound, e:
            raise exceptions.ShowNotFoundException(e.message)
Exemplo n.º 2
0
    def _get_episode_thumb_url(self, ep_obj):
        """
        Returns the URL to use for downloading an episode's thumbnail. Uses
        theTVDB.com and TVRage.com data.

        ep_obj: a TVEpisode object for which to grab the thumb URL
        """
        all_eps = [ep_obj] + ep_obj.relatedEps

        indexer_lang = ep_obj.show.lang

        # get a TVDB object
        try:
            # There's gotta be a better way of doing this but we don't wanna
            # change the language value elsewhere
            lINDEXER_API_PARMS = sickbeard.indexerApi(ep_obj.show.indexer).api_params.copy()

            lINDEXER_API_PARMS['actors'] = True

            if indexer_lang and not indexer_lang == 'en':
                lINDEXER_API_PARMS['language'] = indexer_lang

            if ep_obj.show.dvdorder != 0:
                lINDEXER_API_PARMS['dvdorder'] = True

            t = sickbeard.indexerApi(ep_obj.show.indexer).indexer(**lINDEXER_API_PARMS)

            indexer_show_obj = t[ep_obj.show.indexerid]
        except sickbeard.indexer_shownotfound, e:
            raise exceptions.ShowNotFoundException(e.message)
Exemplo n.º 3
0
    def _retrieve_show_image(self, image_type, show_obj, which=None):
        """
        Gets an image URL from theTVDB.com and TMDB.com, downloads it and returns the data.

        image_type: type of image to retrieve (currently supported: fanart, poster, banner)
        show_obj: a TVShow object to use when searching for the image
        which: optional, a specific numbered poster to look for

        Returns: the binary image data if available, or else None
        """
        image_url = None
        indexer_lang = show_obj.lang

        try:
            # There's gotta be a better way of doing this but we don't wanna
            # change the language value elsewhere
            lINDEXER_API_PARMS = sickbeard.indexerApi(show_obj.indexer).api_params.copy()

            lINDEXER_API_PARMS['banners'] = True

            if indexer_lang and not indexer_lang == sickbeard.INDEXER_DEFAULT_LANGUAGE:
                lINDEXER_API_PARMS['language'] = indexer_lang

            if show_obj.dvdorder != 0:
                lINDEXER_API_PARMS['dvdorder'] = True

            t = sickbeard.indexerApi(show_obj.indexer).indexer(**lINDEXER_API_PARMS)
            indexer_show_obj = t[show_obj.indexerid]
        except (sickbeard.indexer_error, IOError), e:
            logger.log(u"Unable to look up show on " + sickbeard.indexerApi(
                show_obj.indexer).name + ", not downloading images: " + ex(e), logger.WARNING)
            logger.log(u"Indexer " + sickbeard.indexerApi(show_obj.indexer).name + "maybe experiencing some problems. Try again later", logger.DEBUG)
            return None
Exemplo n.º 4
0
def _xem_refresh(indexer_id, indexer):
    """
    Refresh data from xem for a tv show
    
    @param indexer_id: int
    """
    if indexer_id is None:
        return

    indexer_id = int(indexer_id)
    indexer = int(indexer)

    try:
        logger.log(
            u'Looking up XEM scene mapping for show %s on %s' % (indexer_id, sickbeard.indexerApi(indexer).name,),
            logger.DEBUG)
        data = requests.get("http://thexem.de/map/all?id=%s&origin=%s&destination=scene" % (
            indexer_id, sickbeard.indexerApi(indexer).config['xem_origin'],), verify=False).json()

        if data is None or data == '':
            logger.log(u'No XEN data for show "%s on %s", trying TVTumbler' % (
                indexer_id, sickbeard.indexerApi(indexer).name,), logger.MESSAGE)
            data = requests.get("http://show-api.tvtumbler.com/api/thexem/all?id=%s&origin=%s&destination=scene" % (
                indexer_id, sickbeard.indexerApi(indexer).config['xem_origin'],), verify=False).json()
            if data is None or data == '':
                logger.log(u'TVTumbler also failed for show "%s on %s".  giving up.' % (indexer_id, indexer,),
                           logger.MESSAGE)
                return None

        result = data
        if result:
            cacheDB = db.DBConnection('cache.db')
            cacheDB.action("INSERT OR REPLACE INTO xem_refresh (indexer, indexer_id, last_refreshed) VALUES (?,?,?)",
                           [indexer, indexer_id, time.time()])
            if 'success' in result['result']:
                cacheDB.action("DELETE FROM xem_numbering where indexer = ? and indexer_id = ?", [indexer, indexer_id])
                for entry in result['data']:
                    if 'scene' in entry:
                        cacheDB.action(
                            "INSERT INTO xem_numbering (indexer, indexer_id, season, episode, scene_season, scene_episode) VALUES (?,?,?,?,?,?)",
                            [indexer, indexer_id, entry[sickbeard.indexerApi(indexer).config['xem_origin']]['season'],
                             entry[sickbeard.indexerApi(indexer).config['xem_origin']]['episode'],
                             entry['scene']['season'], entry['scene']['episode']])
                    if 'scene_2' in entry:  # for doubles
                        cacheDB.action(
                            "INSERT INTO xem_numbering (indexer, indexer_id, season, episode, scene_season, scene_episode) VALUES (?,?,?,?,?,?)",
                            [indexer, indexer_id, entry[sickbeard.indexerApi(indexer).config['xem_origin']]['season'],
                             entry[sickbeard.indexerApi(indexer).config['xem_origin']]['episode'],
                             entry['scene_2']['season'], entry['scene_2']['episode']])
            else:
                logger.log(u'Failed to get XEM scene data for show %s from %s because "%s"' % (
                    indexer_id, sickbeard.indexerApi(indexer).name, result['message']), logger.DEBUG)
        else:
            logger.log(u"Empty lookup result - no XEM data for show %s on %s" % (
                indexer_id, sickbeard.indexerApi(indexer).name,), logger.DEBUG)
    except Exception, e:
        logger.log(u"Exception while refreshing XEM data for show " + str(indexer_id) + " on " + sickbeard.indexerApi(
            indexer).name + ": " + ex(e), logger.WARNING)
        logger.log(traceback.format_exc(), logger.DEBUG)
        return None
Exemplo n.º 5
0
    def _retrieve_show_image(self, image_type, show_obj, which=None):
        """
        Gets an image URL from theTVDB.com and TMDB.com, downloads it and returns the data.

        image_type: type of image to retrieve (currently supported: fanart, poster, banner)
        show_obj: a TVShow object to use when searching for the image
        which: optional, a specific numbered poster to look for

        Returns: the binary image data if available, or else None
        """
        image_url = None
        indexer_lang = show_obj.lang

        try:
            # There's gotta be a better way of doing this but we don't wanna
            # change the language value elsewhere
            lINDEXER_API_PARMS = sickbeard.indexerApi(show_obj.indexer).api_params.copy()

            lINDEXER_API_PARMS['banners'] = True

            if indexer_lang and not indexer_lang == sickbeard.INDEXER_DEFAULT_LANGUAGE:
                lINDEXER_API_PARMS['language'] = indexer_lang

            if show_obj.dvdorder != 0:
                lINDEXER_API_PARMS['dvdorder'] = True

            t = sickbeard.indexerApi(show_obj.indexer).indexer(**lINDEXER_API_PARMS)
            indexer_show_obj = t[show_obj.indexerid]
        except (sickbeard.indexer_error, IOError) as e:
            logger.log(u"Unable to look up show on " + sickbeard.indexerApi(
                show_obj.indexer).name + ", not downloading images: " + ex(e), logger.WARNING)
            logger.log(u"%s may be experiencing some problems. Try again later." % sickbeard.indexerApi(show_obj.indexer).name, logger.DEBUG)
            return None

        if image_type not in ('fanart', 'poster', 'banner', 'poster_thumb', 'banner_thumb'):
            logger.log(u"Invalid image type " + str(image_type) + ", couldn't find it in the " + sickbeard.indexerApi(
                show_obj.indexer).name + " object", logger.ERROR)
            return None

        if image_type == 'poster_thumb':
            if getattr(indexer_show_obj, 'poster', None):
                image_url = re.sub('posters', '_cache/posters', indexer_show_obj['poster'])
            if not image_url:
                # Try and get images from TMDB
                image_url = self._retrieve_show_images_from_tmdb(show_obj, image_type)
        elif image_type == 'banner_thumb':
            if getattr(indexer_show_obj, 'banner', None):
                image_url = re.sub('graphical', '_cache/graphical', indexer_show_obj['banner'])
        else:
            if getattr(indexer_show_obj, image_type, None):
                image_url = indexer_show_obj[image_type]
            if not image_url:
                # Try and get images from TMDB
                image_url = self._retrieve_show_images_from_tmdb(show_obj, image_type)

        if image_url:
            image_data = metadata_helpers.getShowImage(image_url, which)
            return image_data

        return None
Exemplo n.º 6
0
def get_xem_ids():
    global xem_ids_list

    for iid, name in sickbeard.indexerApi().xem_supported_indexers.iteritems():
        xem_ids = _xem_get_ids(name, sickbeard.indexerApi(iid).config['xem_origin'])
        if len(xem_ids):
            xem_ids_list[iid] = xem_ids
Exemplo n.º 7
0
def _xem_exceptions_fetcher():
    global xem_exception_dict

    xem_list = 'xem_us'
    for show in sickbeard.showList:
        if show.is_anime and not show.paused:
            xem_list = 'xem'
            break

    if shouldRefresh(xem_list):
        for indexer in [i for i in sickbeard.indexerApi().indexers if 'xem_origin' in sickbeard.indexerApi(i).config]:
            logger.log(u'Checking for XEM scene exception updates for %s' % sickbeard.indexerApi(indexer).name)

            url = 'http://thexem.de/map/allNames?origin=%s%s&seasonNumbers=1'\
                  % (sickbeard.indexerApi(indexer).config['xem_origin'], ('&language=us', '')['xem' == xem_list])

            parsed_json = helpers.getURL(url, json=True, timeout=90)
            if not parsed_json:
                logger.log(u'Check scene exceptions update failed for %s, Unable to get URL: %s'
                           % (sickbeard.indexerApi(indexer).name, url), logger.ERROR)
                continue

            if 'failure' == parsed_json['result']:
                continue

            for indexerid, names in parsed_json['data'].items():
                try:
                    xem_exception_dict[int(indexerid)] = names
                except:
                    continue

        setLastRefresh(xem_list)

    return xem_exception_dict
Exemplo n.º 8
0
    def _season_banners_dict(self, show_obj, season):
        """
        Should return a dict like:

        result = {<season number>:
                    {1: '<url 1>', 2: <url 2>, ...},}
        """

        # This holds our resulting dictionary of season art
        result = {}

        indexer_lang = show_obj.lang

        try:
            # There's gotta be a better way of doing this but we don't wanna
            # change the language value elsewhere
            lINDEXER_API_PARMS = sickbeard.indexerApi(show_obj.indexer).api_params.copy()

            lINDEXER_API_PARMS['banners'] = True

            if indexer_lang and not indexer_lang == sickbeard.INDEXER_DEFAULT_LANGUAGE:
                lINDEXER_API_PARMS['language'] = indexer_lang

            t = sickbeard.indexerApi(show_obj.indexer).indexer(**lINDEXER_API_PARMS)
            indexer_show_obj = t[show_obj.indexerid]
        except (sickbeard.indexer_error, IOError), e:
            logger.log(u"Unable to look up show on " + sickbeard.indexerApi(
                show_obj.indexer).name + ", not downloading images: " + ex(e), logger.WARNING)
            logger.log(u"Indexer " + sickbeard.indexerApi(show_obj.indexer).name + "maybe experiencing some problems. Try again later", logger.DEBUG)
            return result
Exemplo n.º 9
0
    def _ep_data(self, ep_obj):
        """
        Creates an elementTree XML structure for a MediaBrowser style episode.xml
        and returns the resulting data object.

        show_obj: a TVShow instance to create the NFO for
        """

        eps_to_write = [ep_obj] + ep_obj.relatedEps

        indexer_lang = ep_obj.show.lang

        try:
            # There's gotta be a better way of doing this but we don't wanna
            # change the language value elsewhere
            lINDEXER_API_PARMS = sickbeard.indexerApi(ep_obj.show.indexer).api_params.copy()

            if indexer_lang and not indexer_lang == sickbeard.INDEXER_DEFAULT_LANGUAGE:
                lINDEXER_API_PARMS['language'] = indexer_lang

            if ep_obj.show.dvdorder != 0:
                lINDEXER_API_PARMS['dvdorder'] = True

            t = sickbeard.indexerApi(ep_obj.show.indexer).indexer(**lINDEXER_API_PARMS)
            myShow = t[ep_obj.show.indexerid]
        except sickbeard.indexer_shownotfound, e:
            raise exceptions.ShowNotFoundException(e.message)
Exemplo n.º 10
0
    def _ep_data(self, ep_obj):
        """
        Creates an elementTree XML structure for a WDTV style episode.xml
        and returns the resulting data object.

        ep_obj: a TVShow instance to create the NFO for
        """

        eps_to_write = [ep_obj] + ep_obj.relatedEps

        indexer_lang = ep_obj.show.lang

        try:
            lINDEXER_API_PARMS = sickbeard.indexerApi(ep_obj.show.indexer).api_params.copy()

            lINDEXER_API_PARMS['actors'] = True

            if indexer_lang and not indexer_lang == sickbeard.INDEXER_DEFAULT_LANGUAGE:
                lINDEXER_API_PARMS['language'] = indexer_lang

            if ep_obj.show.dvdorder != 0:
                lINDEXER_API_PARMS['dvdorder'] = True

            t = sickbeard.indexerApi(ep_obj.show.indexer).indexer(**lINDEXER_API_PARMS)
            myShow = t[ep_obj.show.indexerid]
        except sickbeard.indexer_shownotfound, e:
            raise ShowNotFoundException(e.message)
Exemplo n.º 11
0
    def run(self, force=False):

        update_datetime = datetime.datetime.now()
        update_date = update_datetime.date()

        logger.log(u"Doing full update on all shows")

        # clean out cache directory, remove everything > 12 hours old
        if sickbeard.CACHE_DIR:
            for indexer in sickbeard.indexerApi().indexers:
                cache_dir = sickbeard.indexerApi(indexer).cache
                logger.log(u"Trying to clean cache folder " + cache_dir)

                # Does our cache_dir exists
                if not ek.ek(os.path.isdir, cache_dir):
                    logger.log(u"Can't clean " + cache_dir + " if it doesn't exist", logger.WARNING)
                else:
                    max_age = datetime.timedelta(hours=12)
                    # Get all our cache files
                    cache_files = ek.ek(os.listdir, cache_dir)

                    for cache_file in cache_files:
                        cache_file_path = ek.ek(os.path.join, cache_dir, cache_file)

                        if ek.ek(os.path.isfile, cache_file_path):
                            cache_file_modified = datetime.datetime.fromtimestamp(
                                ek.ek(os.path.getmtime, cache_file_path))

                            if update_datetime - cache_file_modified > max_age:
                                try:
                                    ek.ek(os.remove, cache_file_path)
                                except OSError, e:
                                    logger.log(u"Unable to clean " + cache_dir + ": " + repr(e) + " / " + str(e),
                                               logger.WARNING)
                                    break
Exemplo n.º 12
0
    def _ep_data(self, ep_obj):
        """
        Creates an elementTree XML structure for a Kodi-style episode.nfo and
        returns the resulting data object.
            show_obj: a TVEpisode instance to create the NFO for
        """

        eps_to_write = [ep_obj] + ep_obj.relatedEps

        indexer_lang = ep_obj.show.lang

        lINDEXER_API_PARMS = sickbeard.indexerApi(ep_obj.show.indexer).api_params.copy()

        lINDEXER_API_PARMS["actors"] = True

        if indexer_lang and not indexer_lang == "en":
            lINDEXER_API_PARMS["language"] = indexer_lang

        if ep_obj.show.dvdorder != 0:
            lINDEXER_API_PARMS["dvdorder"] = True

        try:
            t = sickbeard.indexerApi(ep_obj.show.indexer).indexer(**lINDEXER_API_PARMS)
            myShow = t[ep_obj.show.indexerid]
        except sickbeard.indexer_shownotfound, e:
            raise exceptions.ShowNotFoundException(e.message)
Exemplo n.º 13
0
def searchIndexerForShowID(regShowName, indexer=None, indexer_id=None, ui=True):
    showNames = list(set([re.sub('[. -]', ' ', regShowName), regShowName]))

    # Query Indexers for each search term and build the list of results
    for indexer in sickbeard.indexerApi().indexers if not indexer else [int(indexer)]:
        # Query Indexers for each search term and build the list of results
        lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
        if ui:lINDEXER_API_PARMS['custom_ui'] = classes.ShowListUI
        t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)

        for name in showNames:
            logger.log(u"Trying to find " + name + " on " + sickbeard.indexerApi(indexer).name, logger.DEBUG)
            try:
                if indexer_id:
                    search = t[indexer_id]
                else:
                    search = t[name]

                if isinstance(search, dict):
                    search = [search]

                # add search results
                for i in range(len(search)):
                    part = search[i]
                    seriesname = part['seriesname'].encode('UTF-8').lower()
                    name = name.encode('UTF-8').lower()

                    if (name in seriesname) or (indexer_id is not None and part['id'] == indexer_id):
                        return [sickbeard.indexerApi(indexer).config['id'], part['id']]

            except KeyError:break
            except Exception:continue
Exemplo n.º 14
0
def _xem_exceptions_fetcher():

    exception_dict = {}

    if shouldRefresh('xem'):
        success = False
        for indexer in sickbeard.indexerApi().indexers:
            logger.log(u"Checking for XEM scene exception updates for " + sickbeard.indexerApi(indexer).name)

            url = "http://thexem.de/map/allNames?origin=%s&seasonNumbers=1" % sickbeard.indexerApi(indexer).config[
                'xem_origin']

            url_data = helpers.getURL(url, json=True)
            if url_data is None:
                logger.log(u"Check scene exceptions update failed for " + sickbeard.indexerApi(
                    indexer).name + ", Unable to get URL: " + url, logger.ERROR)
                continue

            if url_data['result'] == 'failure':
                continue

            for indexerid, names in url_data['data'].items():
                exception_dict[int(indexerid)] = names

            success = True

        if success:
            setLastRefresh('xem')

    return exception_dict
Exemplo n.º 15
0
def searchIndexerForShowID(regShowName, indexer=None, indexer_id=None, ui=None):
    showNames = list(set([re.sub('[. -]', ' ', regShowName), regShowName]))

    # Query Indexers for each search term and build the list of results
    for indexer in sickbeard.indexerApi().indexers if not indexer else [int(indexer)]:
        # Query Indexers for each search term and build the list of results
        lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
        if ui: lINDEXER_API_PARMS['custom_ui'] = ui
        t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)

        for name in showNames:
            logger.log(u"Trying to find " + name + " on " + sickbeard.indexerApi(indexer).name, logger.DEBUG)
            try:
                search = t[indexer_id] if indexer_id else t[name]

                # add search results
                for i in range(len(search)):
                    part = search[i]
                    seriesname = part['seriesname'].lower()

                    if str(name).lower() == seriesname or (indexer_id and part['id'] == indexer_id):
                        return [sickbeard.indexerApi(indexer).config['id'], part['id']]

            except KeyError:
                if indexer:
                    break
                else:
                    continue
            except Exception:
                continue
Exemplo n.º 16
0
def get_show_by_name(name, showList, useIndexer=False):
    logger.log(u"Trying to get the indexerid for " + name, logger.DEBUG)

    if showList:
        for show in showList:
            if _check_against_names(name, show):
                logger.log(u"Matched " + name + " in the showlist to the show " + show.name, logger.DEBUG)
                return show

    if useIndexer:
        for indexer in sickbeard.indexerApi().indexers:
            try:
                lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
                lINDEXER_API_PARMS['custom_ui'] = classes.ShowListUI
                lINDEXER_API_PARMS['search_all_languages'] = True

                t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)
                showObj = t[name]
            except:continue

            if showObj:
                showResult = findCertainShow(sickbeard.showList, int(showObj["id"]))
                if showResult is not None:
                    return showResult

    return None
Exemplo n.º 17
0
def _xem_exceptions_fetcher():
    global xem_exception_dict

    if shouldRefresh('xem'):
        for indexer in sickbeard.indexerApi().indexers:
            logger.log(u"Checking for XEM scene exception updates for " + sickbeard.indexerApi(indexer).name)

            url = "http://thexem.de/map/allNames?origin=%s&seasonNumbers=1" % sickbeard.indexerApi(indexer).config[
                'xem_origin']

            parsedJSON = helpers.getURL(url, json=True)
            if not parsedJSON:
                logger.log(u"Check scene exceptions update failed for " + sickbeard.indexerApi(
                    indexer).name + ", Unable to get URL: " + url, logger.ERROR)
                continue

            if parsedJSON['result'] == 'failure':
                continue

            for indexerid, names in parsedJSON['data'].items():
                xem_exception_dict[int(indexerid)] = names

        setLastRefresh('xem')

    return xem_exception_dict
Exemplo n.º 18
0
def _xem_exceptions_fetcher():
    if shouldRefresh('xem'):
        for indexer in sickbeard.indexerApi().indexers:
            logger.log(u'Checking for XEM scene exception updates for {0}'.format
                       (sickbeard.indexerApi(indexer).name))

            url = 'http://thexem.de/map/allNames?origin={0}&seasonNumbers=1'.format(sickbeard.indexerApi(indexer).config['xem_origin'])

            parsedJSON = helpers.getURL(url, session=xem_session, timeout=90, returns='json')
            if not parsedJSON:
                logger.log(u'Check scene exceptions update failed for {0}, Unable to get URL: {1}'.format
                           (sickbeard.indexerApi(indexer).name, url), logger.DEBUG)
                continue

            if parsedJSON['result'] == 'failure':
                continue

            if not parsedJSON['data']:
                logger.log(u'No data returned from XEM when checking scene exceptions. Update failed for {0}'.format
                           (sickbeard.indexerApi(indexer).name), logger.DEBUG)
                continue

            for indexerid, names in iteritems(parsedJSON['data']):
                try:
                    xem_exception_dict[int(indexerid)] = names
                except Exception as error:
                    logger.log(u'XEM: Rejected entry: indexerid:{0}; names:{1}'.format(indexerid, names), logger.WARNING)
                    logger.log(u'XEM: Rejected entry error message:{0}'.format(error), logger.DEBUG)

        setLastRefresh('xem')

    return xem_exception_dict
Exemplo n.º 19
0
    def _season_posters_dict(self, show_obj, season):
        """
        Should return a dict like:

        result = {<season number>:
                    {1: '<url 1>', 2: <url 2>, ...},}
        """

        # This holds our resulting dictionary of season art
        result = {}

        indexer_lang = show_obj.lang

        try:
            # There's gotta be a better way of doing this but we don't wanna
            # change the language value elsewhere
            lINDEXER_API_PARMS = sickbeard.indexerApi(show_obj.indexer).api_params.copy()

            lINDEXER_API_PARMS['banners'] = True

            if indexer_lang and not indexer_lang == 'en':
                lINDEXER_API_PARMS['language'] = indexer_lang

            if show_obj.dvdorder != 0:
                lINDEXER_API_PARMS['dvdorder'] = True

            t = sickbeard.indexerApi(show_obj.indexer).indexer(**lINDEXER_API_PARMS)
            indexer_show_obj = t[show_obj.indexerid]
        except (sickbeard.indexer_error, IOError), e:
            logger.log(u"Unable to look up show on " + sickbeard.indexerApi(
                show_obj.indexer).name + ", not downloading images: " + ex(e), logger.ERROR)
            return result
Exemplo n.º 20
0
def _xem_exceptions_fetcher():
    global xem_exception_dict
    global xem_session

    if shouldRefresh('xem'):
        for indexer in sickbeard.indexerApi().indexers:
            logger.log(u"Checking for XEM scene exception updates for " + sickbeard.indexerApi(indexer).name)

            url = "http://thexem.de/map/allNames?origin=%s&seasonNumbers=1" % sickbeard.indexerApi(indexer).config[
                'xem_origin']

            parsedJSON = helpers.getURL(url, session=xem_session, json=True)
            if not parsedJSON:
                logger.log(u"Check scene exceptions update failed for " + sickbeard.indexerApi(
                    indexer).name + ", Unable to get URL: " + url, logger.ERROR)
                continue

            if parsedJSON['result'] == 'failure':
                continue

            for indexerid, names in parsedJSON['data'].iteritems():
                try:
                    xem_exception_dict[int(indexerid)] = names
                except Exception as e:
                    logger.log(u"XEM: Rejected entry: indexerid:{0}; names:{1}".format(indexerid, names), logger.WARNING)
                    logger.log(u"XEM: Rejected entry error message:{0}".format(str(e)), logger.DEBUG)

        setLastRefresh('xem')

    return xem_exception_dict
Exemplo n.º 21
0
    def _season_posters_dict(self, show_obj, season):
        """
        Should return a dict like:

        result = {<season number>:
                    {1: '<url 1>', 2: <url 2>, ...},}
        """

        # This holds our resulting dictionary of season art
        result = {}

        indexer_lang = show_obj.lang

        try:
            # There's gotta be a better way of doing this but we don't wanna
            # change the language value elsewhere
            lINDEXER_API_PARMS = sickbeard.indexerApi(show_obj.indexer).api_params.copy()

            lINDEXER_API_PARMS['banners'] = True

            if indexer_lang and not indexer_lang == sickbeard.INDEXER_DEFAULT_LANGUAGE:
                lINDEXER_API_PARMS['language'] = indexer_lang

            if show_obj.dvdorder != 0:
                lINDEXER_API_PARMS['dvdorder'] = True

            t = sickbeard.indexerApi(show_obj.indexer).indexer(**lINDEXER_API_PARMS)
            indexer_show_obj = t[show_obj.indexerid]
        except (sickbeard.indexer_error, IOError) as e:
            logger.log(u"Unable to look up show on " + sickbeard.indexerApi(
                show_obj.indexer).name + ", not downloading images: " + ex(e), logger.WARNING)
            logger.log(u"%s may be experiencing some problems. Try again later." % sickbeard.indexerApi(show_obj.indexer).name, logger.DEBUG)
            return result

        # if we have no season banners then just finish
        if not getattr(indexer_show_obj, '_banners', None):
            return result

        if 'season' not in indexer_show_obj['_banners'] or 'season' not in indexer_show_obj['_banners']['season']:
            return result

        # Give us just the normal poster-style season graphics
        seasonsArtObj = indexer_show_obj['_banners']['season']['season']

        # Returns a nested dictionary of season art with the season
        # number as primary key. It's really overkill but gives the option
        # to present to user via ui to pick down the road.

        result[season] = {}

        # find the correct season in the TVDB object and just copy the dict into our result dict
        for seasonArtID in seasonsArtObj.keys():
            if int(seasonsArtObj[seasonArtID]['season']) == season and seasonsArtObj[seasonArtID]['language'] == sickbeard.INDEXER_DEFAULT_LANGUAGE:
                result[season][seasonArtID] = seasonsArtObj[seasonArtID]['_bannerpath']

        return result
Exemplo n.º 22
0
    def execute(self):

        ShowQueueItem.execute(self)

        logger.log(u"Beginning update of " + self.show.name)

        logger.log(u"Retrieving show info from " + sickbeard.indexerApi(self.show.indexer).name + "", logger.DEBUG)
        try:
            self.show.loadFromIndexer(cache=not self.force)
        except sickbeard.indexer_error, e:
            logger.log(u"Unable to contact " + sickbeard.indexerApi(self.show.indexer).name + ", aborting: " + ex(e),
                       logger.WARNING)
            return
Exemplo n.º 23
0
    def run(self):

        ShowQueueItem.run(self)

        logger.log(u'Beginning update of ' + self.show.name)

        logger.log(u'Retrieving show info from ' + sickbeard.indexerApi(self.show.indexer).name + '', logger.DEBUG)
        try:
            result = self.show.loadFromIndexer(cache=not self.force)
            if None is not result:
                return
        except sickbeard.indexer_error, e:
            logger.log(u'Unable to contact ' + sickbeard.indexerApi(self.show.indexer).name + ', aborting: ' + ex(e),
                       logger.WARNING)
            return
Exemplo n.º 24
0
    def addEpisodeToTraktWatchList(self):
        if sickbeard.TRAKT_SYNC_WATCHLIST and sickbeard.USE_TRAKT:
            logger.log(u"WATCHLIST::ADD::START - Look for Episodes to Add to Trakt Watchlist", logger.DEBUG)

            myDB = db.DBConnection()
            sql_selection = 'select tv_shows.indexer, tv_shows.startyear, showid, show_name, season, episode from tv_episodes,tv_shows where tv_shows.indexer_id = tv_episodes.showid and tv_episodes.status in (' + ','.join([str(x) for x in Quality.SNATCHED + Quality.SNATCHED_PROPER + [WANTED]]) + ')'
            episodes = myDB.select(sql_selection)

            if episodes is not None:
                trakt_data = []

                for cur_episode in episodes:
                    trakt_id = sickbeard.indexerApi(cur_episode["indexer"]).config['trakt_id']

                    if not self._checkInList(trakt_id, str(cur_episode["showid"]), str(cur_episode["season"]), str(cur_episode["episode"])):
                        logger.log(u"Adding Episode %s S%02dE%02d to watchlist" %
                                   (cur_episode["show_name"], cur_episode["season"], cur_episode["episode"]), logger.DEBUG)
                        trakt_data.append((cur_episode["showid"], cur_episode["indexer"], cur_episode["show_name"], cur_episode["startyear"], cur_episode["season"],
                                           cur_episode["episode"]))

                if len(trakt_data):
                    try:
                        data = self.trakt_bulk_data_generate(trakt_data)
                        self.trakt_api.traktRequest("sync/watchlist", data, method='POST')
                        self._getEpisodeWatchlist()
                    except traktException as e:
                        logger.log(u"Could not connect to Trakt service. Error %s" % ex(e), logger.WARNING)

            logger.log(u"WATCHLIST::ADD::FINISH - Look for Episodes to Add to Trakt Watchlist", logger.DEBUG)
Exemplo n.º 25
0
    def updateShows(self):
        logger.log(u"SHOW_WATCHLIST::CHECK::START - Trakt Show Watchlist", logger.DEBUG)

        if not len(self.ShowWatchlist):
            logger.log(u"No shows found in your watchlist, aborting watchlist update", logger.DEBUG)
            return

        indexer = int(sickbeard.TRAKT_DEFAULT_INDEXER)
        trakt_id = sickbeard.indexerApi(indexer).config['trakt_id']

        for show_el in self.ShowWatchlist[trakt_id]:
            indexer_id = int(str(show_el))
            show = self.ShowWatchlist[trakt_id][show_el]

            # logger.log(u"Checking Show: %s %s %s" % (trakt_id, indexer_id, show['title']),logger.DEBUG)
            if int(sickbeard.TRAKT_METHOD_ADD) != 2:
                self.addDefaultShow(indexer, indexer_id, show['title'], SKIPPED)
            else:
                self.addDefaultShow(indexer, indexer_id, show['title'], WANTED)

            if int(sickbeard.TRAKT_METHOD_ADD) == 1:
                newShow = Show.find(sickbeard.showList, indexer_id)

                if newShow is not None:
                    setEpisodeToWanted(newShow, 1, 1)
                else:
                    self.todoWanted.append((indexer_id, 1, 1))
        logger.log(u"SHOW_WATCHLIST::CHECK::FINISH - Trakt Show Watchlist", logger.DEBUG)
Exemplo n.º 26
0
    def addShowToTraktWatchList(self):
        if sickbeard.TRAKT_SYNC_WATCHLIST and sickbeard.USE_TRAKT:
            logger.log(u"SHOW_WATCHLIST::ADD::START - Look for Shows to Add to Trakt Watchlist", logger.DEBUG)

            if sickbeard.showList is not None:
                trakt_data = []

                for show in sickbeard.showList:
                    trakt_id = sickbeard.indexerApi(show.indexer).config['trakt_id']

                    if not self._checkInList(trakt_id, str(show.indexerid), '0', '0', List='Show'):
                        logger.log(u"Adding Show: Indexer %s %s - %s to Watchlist" % (trakt_id, str(show.indexerid), show.name), logger.DEBUG)
                        show_el = {'title': show.name, 'year': show.startyear, 'ids': {}}
                        if trakt_id == 'tvdb_id':
                            show_el['ids']['tvdb'] = show.indexerid
                        else:
                            show_el['ids']['tvrage'] = show.indexerid
                        trakt_data.append(show_el)

                if len(trakt_data):
                    try:
                        data = {'shows': trakt_data}
                        self.trakt_api.traktRequest("sync/watchlist", data, method='POST')
                        self._getShowWatchlist()
                    except traktException as e:
                        logger.log(u"Could not connect to Trakt service. Error: %s" % ex(e), logger.WARNING)

            logger.log(u"SHOW_WATCHLIST::ADD::FINISH - Look for Shows to Add to Trakt Watchlist", logger.DEBUG)
Exemplo n.º 27
0
    def addShowToTraktLibrary(self, show_obj):
        """
        Sends a request to trakt indicating that the given show and all its episodes is part of our library.

        show_obj: The TVShow object to add to trakt
        """
        data = {}

        if not self.findShow(show_obj.indexer, show_obj.indexerid):
            trakt_id = sickbeard.indexerApi(show_obj.indexer).config['trakt_id']
            # URL parameters
            data = {
                'shows': [
                    {
                        'title': show_obj.name,
                        'year': show_obj.startyear,
                        'ids': {}
                    }
                ]
            }

            if trakt_id == 'tvdb_id':
                data['shows'][0]['ids']['tvdb'] = show_obj.indexerid
            else:
                data['shows'][0]['ids']['tvrage'] = show_obj.indexerid

        if len(data):
            logger.log(u"Adding %s to trakt.tv library" % show_obj.name, logger.DEBUG)

            try:
                self.trakt_api.traktRequest("sync/collection", data, method='POST')
            except traktException as e:
                logger.log(u"Could not connect to Trakt service. Aborting adding show %s to Trakt library. Error: %s" % (show_obj.name, repr(e)), logger.WARNING)
                return
Exemplo n.º 28
0
    def removeEpisodeFromTraktCollection(self):
        if sickbeard.TRAKT_SYNC_REMOVE and sickbeard.TRAKT_SYNC and sickbeard.USE_TRAKT:
            logger.log(u"COLLECTION::REMOVE::START - Look for Episodes to Remove From Trakt Collection", logger.DEBUG)

            myDB = db.DBConnection()
            sql_selection = 'select tv_shows.indexer, tv_shows.startyear, showid, show_name, season, episode, tv_episodes.status, tv_episodes.location from tv_episodes,tv_shows where tv_shows.indexer_id = tv_episodes.showid'
            episodes = myDB.select(sql_selection)

            if episodes is not None:
                trakt_data = []

                for cur_episode in episodes:
                    trakt_id = sickbeard.indexerApi(cur_episode["indexer"]).config['trakt_id']

                    if self._checkInList(trakt_id, str(cur_episode["showid"]), str(cur_episode["season"]), str(cur_episode["episode"]), List='Collection'):
                        if cur_episode["location"] == '':
                            logger.log(u"Removing Episode %s S%02dE%02d from collection" %
                                       (cur_episode["show_name"], cur_episode["season"], cur_episode["episode"]), logger.DEBUG)
                            trakt_data.append((cur_episode["showid"], cur_episode["indexer"], cur_episode["show_name"], cur_episode["startyear"], cur_episode["season"], cur_episode["episode"]))

                if len(trakt_data):
                    try:
                        data = self.trakt_bulk_data_generate(trakt_data)
                        self.trakt_api.traktRequest("sync/collection/remove", data, method='POST')
                        self._getShowCollection()
                    except traktException as e:
                        logger.log(u"Could not connect to Trakt service. Error: %s" % ex(e), logger.WARNING)

            logger.log(u"COLLECTION::REMOVE::FINISH - Look for Episodes to Remove From Trakt Collection", logger.DEBUG)
Exemplo n.º 29
0
def validateShow(show, season=None, episode=None):
    indexer_lang = show.lang

    try:
        lINDEXER_API_PARMS = sickbeard.indexerApi(show.indexer).api_params.copy()

        if indexer_lang and not indexer_lang == 'en':
            lINDEXER_API_PARMS['language'] = indexer_lang

        t = sickbeard.indexerApi(show.indexer).indexer(**lINDEXER_API_PARMS)
        if season is None and episode is None:
            return t

        return t[show.indexerid][season][episode]
    except (sickbeard.indexer_episodenotfound, sickbeard.indexer_seasonnotfound):
        pass
Exemplo n.º 30
0
    def removeShowFromTraktLibrary(self, show_obj):
        if self.findShow(show_obj.indexer, show_obj.indexerid):
            trakt_id = sickbeard.indexerApi(show_obj.indexer).config['trakt_id']

            # URL parameters
            data = {
                'shows': [
                    {
                        'title': show_obj.name,
                        'year': show_obj.startyear,
                        'ids': {}
                    }
                ]
            }

            if trakt_id == 'tvdb_id':
                data['shows'][0]['ids']['tvdb'] = show_obj.indexerid
            else:
                data['shows'][0]['ids']['tvrage'] = show_obj.indexerid

            logger.log(u"Removing %s from trakt.tv library" % show_obj.name, logger.DEBUG)

            try:
                self.trakt_api.traktRequest("sync/collection/remove", data, method='POST')
            except traktException as e:
                logger.log(u"Could not connect to Trakt service. Aborting removing show %s from Trakt library. Error: %s" % (show_obj.name, repr(e)), logger.WARNING)
Exemplo n.º 31
0
            self.show.saveToDB()
        except Exception, e:
            logger.log(u"Error saving the show to the database: " + ex(e),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finishEarly()
            raise

        # add it to the show list
        sickbeard.showList.append(self.show)

        try:
            self.show.loadEpisodesFromIndexer()
        except Exception, e:
            logger.log(
                u"Error with " + sickbeard.indexerApi(self.show.indexer).name +
                ", not creating episode list: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        try:
            self.show.loadEpisodesFromDir()
        except Exception, e:
            logger.log(u"Error searching dir for episodes: " + ex(e),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # if they gave a custom status then change all the eps to it
        if self.default_status != SKIPPED:
            logger.log(
                u"Setting all episodes to the specified default status: " +
                str(self.default_status))
Exemplo n.º 32
0
    def execute(self):

        ShowQueueItem.execute(self)

        logger.log(u"Starting to add show " + self.showDir)
        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = sickbeard.indexerApi(
                self.indexer).api_params.copy()
            if self.lang:
                lINDEXER_API_PARMS['language'] = self.lang

            logger.log(u"" + sickbeard.indexerApi(self.indexer).name + ": " +
                       repr(lINDEXER_API_PARMS))

            t = sickbeard.indexerApi(
                self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id]

            # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that has no proper english version of the show
            if getattr(s, 'seriesname', None) is None:
                logger.log(
                    u"Show in " + self.showDir + " has no name on " +
                    sickbeard.indexerApi(self.indexer).name +
                    ", probably the wrong language used to search with.",
                    logger.ERROR)
                ui.notifications.error(
                    "Unable to add show",
                    "Show in " + self.showDir + " has no name on " +
                    sickbeard.indexerApi(self.indexer).name +
                    ", probably the wrong language. Delete .nfo and add manually in the correct language."
                )
                self._finishEarly()
                return
            # if the show has no episodes/seasons
            if not s:
                logger.log(
                    u"Show " + str(s['seriesname']) + " is on " +
                    sickbeard.indexerApi(self.indexer).name +
                    " but contains no season/episode data.", logger.ERROR)
                ui.notifications.error(
                    "Unable to add show", "Show " + str(s['seriesname']) +
                    " is on " + sickbeard.indexerApi(self.indexer).name +
                    " but contains no season/episode data.")
                self._finishEarly()
                return
        except Exception, e:
            logger.log(
                u"Unable to find show ID:" + str(self.indexer_id) +
                " on Indexer: " + sickbeard.indexerApi(self.indexer).name,
                logger.ERROR)
            ui.notifications.error(
                "Unable to add show",
                "Unable to look up the show in " + self.showDir + " on " +
                sickbeard.indexerApi(self.indexer).name + " using ID " +
                str(self.indexer_id) +
                ", not using the NFO. Delete .nfo and try adding manually again."
            )
            self._finishEarly()
            return
Exemplo n.º 33
0
    def _show_data(self, show_obj):
        """
        Creates an elementTree XML structure for a MediaBrowser-style series.xml
        returns the resulting data object.

        show_obj: a TVShow instance to create the NFO for
        """

        indexer_lang = show_obj.lang
        lINDEXER_API_PARMS = sickbeard.indexerApi(
            show_obj.indexer).api_params.copy()

        lINDEXER_API_PARMS['actors'] = True

        if indexer_lang and not indexer_lang == sickbeard.INDEXER_DEFAULT_LANGUAGE:
            lINDEXER_API_PARMS['language'] = indexer_lang

        if show_obj.dvdorder != 0:
            lINDEXER_API_PARMS['dvdorder'] = True

        t = sickbeard.indexerApi(
            show_obj.indexer).indexer(**lINDEXER_API_PARMS)

        rootNode = etree.Element("details")
        tv_node = etree.SubElement(rootNode, "movie")
        tv_node.attrib["isExtra"] = "false"
        tv_node.attrib["isSet"] = "false"
        tv_node.attrib["isTV"] = "true"

        try:
            myShow = t[int(show_obj.indexerid)]
        except sickbeard.indexer_shownotfound:
            logger.log(
                u"Unable to find show with id " + str(show_obj.indexerid) +
                " on tvdb, skipping it", logger.ERROR)
            raise

        except sickbeard.indexer_error:
            logger.log(u"TVDB is down, can't use its data to make the NFO",
                       logger.ERROR)
            raise

        # check for title and id
        if not (getattr(myShow, 'seriesname', None)
                and getattr(myShow, 'id', None)):
            logger.log(u"Incomplete info for show with id " +
                       str(show_obj.indexerid) + " on " +
                       sickbeard.indexerApi(show_obj.indexer).name +
                       ", skipping it")
            return False

        SeriesName = etree.SubElement(tv_node, "title")
        SeriesName.text = myShow['seriesname']

        if getattr(myShow, "genre", None):
            Genres = etree.SubElement(tv_node, "genres")
            for genre in myShow['genre'].split('|'):
                if genre and genre.strip():
                    cur_genre = etree.SubElement(Genres, "Genre")
                    cur_genre.text = genre.strip()

        if getattr(myShow, 'firstaired', None):
            FirstAired = etree.SubElement(tv_node, "premiered")
            FirstAired.text = myShow['firstaired']

        if getattr(myShow, "firstaired", None):
            try:
                year_text = str(
                    datetime.datetime.strptime(myShow["firstaired"],
                                               dateFormat).year)
                if year_text:
                    year = etree.SubElement(tv_node, "year")
                    year.text = year_text
            except Exception:
                pass

        if getattr(myShow, 'overview', None):
            plot = etree.SubElement(tv_node, "plot")
            plot.text = myShow["overview"]

        if getattr(myShow, 'rating', None):
            try:
                rating = int(float(myShow['rating']) * 10)
            except ValueError:
                rating = 0

            if rating:
                Rating = etree.SubElement(tv_node, "rating")
                Rating.text = str(rating)

        if getattr(myShow, 'status', None):
            Status = etree.SubElement(tv_node, "status")
            Status.text = myShow['status']

        if getattr(myShow, "contentrating", None):
            mpaa = etree.SubElement(tv_node, "mpaa")
            mpaa.text = myShow["contentrating"]

        if getattr(myShow, 'imdb_id', None):
            imdb_id = etree.SubElement(tv_node, "id")
            imdb_id.attrib["moviedb"] = "imdb"
            imdb_id.text = myShow['imdb_id']

        if getattr(myShow, 'id', None):
            indexerid = etree.SubElement(tv_node, "indexerid")
            indexerid.text = myShow['id']

        if getattr(myShow, 'runtime', None):
            Runtime = etree.SubElement(tv_node, "runtime")
            Runtime.text = myShow['runtime']

        if getattr(myShow, '_actors', None):
            cast = etree.SubElement(tv_node, "cast")
            for actor in myShow['_actors']:
                if 'name' in actor and actor['name'].strip():
                    cur_actor = etree.SubElement(cast, "actor")
                    cur_actor.text = actor['name'].strip()

        helpers.indentXML(rootNode)

        data = etree.ElementTree(rootNode)

        return data
Exemplo n.º 34
0
def xem_refresh(indexer_id, indexer, force=False):
    """
    Refresh data from xem for a tv show

    @param indexer_id: int
    """
    if None is indexer_id:
        return

    indexer_id = int(indexer_id)
    indexer = int(indexer)

    if 'xem_origin' not in sickbeard.indexerApi(
            indexer).config or indexer_id not in xem_ids_list.get(indexer, []):
        return

    # XEM API URL
    url = 'http://thexem.de/map/all?id=%s&origin=%s&destination=scene' % (
        indexer_id, sickbeard.indexerApi(indexer).config['xem_origin'])

    max_refresh_age_secs = 86400  # 1 day

    my_db = db.DBConnection()
    rows = my_db.select(
        'SELECT last_refreshed FROM xem_refresh WHERE indexer = ? and indexer_id = ?',
        [indexer, indexer_id])
    if rows:
        last_refresh = int(rows[0]['last_refreshed'])
        refresh = int(time.mktime(datetime.datetime.today().timetuple())
                      ) > last_refresh + max_refresh_age_secs
    else:
        refresh = True

    if refresh or force:
        logger.log(
            u'Looking up XEM scene mapping for show %s on %s' %
            (indexer_id, sickbeard.indexerApi(indexer).name), logger.DEBUG)

        # mark refreshed
        my_db.upsert(
            'xem_refresh', {
                'indexer':
                indexer,
                'last_refreshed':
                int(time.mktime(datetime.datetime.today().timetuple()))
            }, {'indexer_id': indexer_id})

        try:
            parsed_json = sickbeard.helpers.getURL(url, json=True, timeout=90)
            if not parsed_json or '' == parsed_json:
                logger.log(
                    u'No XEM data for show %s on %s' %
                    (indexer_id, sickbeard.indexerApi(indexer).name),
                    logger.MESSAGE)
                return

            if 'success' in parsed_json['result']:
                cl = []
                for entry in parsed_json['data']:
                    if 'scene' in entry:
                        cl.append([
                            'UPDATE tv_episodes SET scene_season = ?, scene_episode = ?, scene_absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?',
                            [
                                entry['scene']['season'],
                                entry['scene']['episode'],
                                entry['scene']['absolute'], indexer_id,
                                entry[sickbeard.indexerApi(
                                    indexer).config['xem_origin']]['season'],
                                entry[sickbeard.indexerApi(
                                    indexer).config['xem_origin']]['episode']
                            ]
                        ])
                    if 'scene_2' in entry:  # for doubles
                        cl.append([
                            'UPDATE tv_episodes SET scene_season = ?, scene_episode = ?, scene_absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?',
                            [
                                entry['scene_2']['season'],
                                entry['scene_2']['episode'],
                                entry['scene_2']['absolute'], indexer_id,
                                entry[sickbeard.indexerApi(
                                    indexer).config['xem_origin']]['season'],
                                entry[sickbeard.indexerApi(
                                    indexer).config['xem_origin']]['episode']
                            ]
                        ])

                if 0 < len(cl):
                    my_db = db.DBConnection()
                    my_db.mass_action(cl)
            else:
                logger.log(
                    u'Empty lookup result - no XEM data for show %s on %s' %
                    (indexer_id, sickbeard.indexerApi(indexer).name),
                    logger.DEBUG)
        except Exception as e:
            logger.log(
                u'Exception while refreshing XEM data for show ' +
                str(indexer_id) + ' on ' + sickbeard.indexerApi(indexer).name +
                ': ' + ex(e), logger.WARNING)
            logger.log(traceback.format_exc(), logger.ERROR)
Exemplo n.º 35
0
class TIVOMetadata(generic.GenericMetadata):
    """
    Metadata generation class for TIVO

    The following file structure is used:

    show_root/Season ##/filename.ext            (*)
    show_root/Season ##/.meta/filename.ext.txt  (episode metadata)

    This class only generates episode specific metadata files, it does NOT generate a default.txt file.
    """
    def __init__(self,
                 show_metadata=False,
                 episode_metadata=False,
                 fanart=False,
                 poster=False,
                 banner=False,
                 episode_thumbnails=False,
                 season_posters=False,
                 season_banners=False,
                 season_all_poster=False,
                 season_all_banner=False):

        generic.GenericMetadata.__init__(self, show_metadata, episode_metadata,
                                         fanart, poster, banner,
                                         episode_thumbnails, season_posters,
                                         season_banners, season_all_poster,
                                         season_all_banner)

        self.name = 'TIVO'

        self._ep_nfo_extension = "txt"

        # web-ui metadata template
        self.eg_show_metadata = "<i>not supported</i>"
        self.eg_episode_metadata = "Season##\\.meta\\<i>filename</i>.ext.txt"
        self.eg_fanart = "<i>not supported</i>"
        self.eg_poster = "<i>not supported</i>"
        self.eg_banner = "<i>not supported</i>"
        self.eg_episode_thumbnails = "<i>not supported</i>"
        self.eg_season_posters = "<i>not supported</i>"
        self.eg_season_banners = "<i>not supported</i>"
        self.eg_season_all_poster = "<i>not supported</i>"
        self.eg_season_all_banner = "<i>not supported</i>"

    # Override with empty methods for unsupported features
    def retrieveShowMetadata(self, folder):
        # no show metadata generated, we abort this lookup function
        return (None, None, None)

    def create_show_metadata(self, show_obj, force=False):
        pass

    def get_show_file_path(self, show_obj):
        pass

    def create_fanart(self, show_obj):
        pass

    def create_poster(self, show_obj):
        pass

    def create_banner(self, show_obj):
        pass

    def create_episode_thumb(self, ep_obj):
        pass

    def get_episode_thumb_path(self, ep_obj):
        pass

    def create_season_posters(self, ep_obj):
        pass

    def create_season_banners(self, ep_obj):
        pass

    def create_season_all_poster(self, show_obj):
        pass

    def create_season_all_banner(self, show_obj):
        pass

    # Override generic class
    def get_episode_file_path(self, ep_obj):
        """
        Returns a full show dir/.meta/episode.txt path for Tivo
        episode metadata files.

        Note, that pyTivo requires the metadata filename to include the original extention.

        ie If the episode name is foo.avi, the metadata name is foo.avi.txt

        ep_obj: a TVEpisode object to get the path for
        """
        if ek.ek(os.path.isfile, ep_obj.location):
            metadata_file_name = ek.ek(
                os.path.basename,
                ep_obj.location) + "." + self._ep_nfo_extension
            metadata_dir_name = ek.ek(os.path.join,
                                      ek.ek(os.path.dirname, ep_obj.location),
                                      '.meta')
            metadata_file_path = ek.ek(os.path.join, metadata_dir_name,
                                       metadata_file_name)
        else:
            logger.log(
                u"Episode location doesn't exist: " + str(ep_obj.location),
                logger.DEBUG)
            return ''
        return metadata_file_path

    def _ep_data(self, ep_obj):
        """
        Creates a key value structure for a Tivo episode metadata file and
        returns the resulting data object.

        ep_obj: a TVEpisode instance to create the metadata file for.

        Lookup the show in http://thetvdb.com/ using the python library:

        https://github.com/dbr/indexer_api/

        The results are saved in the object myShow.

        The key values for the tivo metadata file are from:

        http://pytivo.sourceforge.net/wiki/index.php/Metadata
        """

        data = ""

        eps_to_write = [ep_obj] + ep_obj.relatedEps

        indexer_lang = ep_obj.show.lang

        try:
            lINDEXER_API_PARMS = sickbeard.indexerApi(
                ep_obj.show.indexer).api_params.copy()

            lINDEXER_API_PARMS['actors'] = True

            if indexer_lang and not indexer_lang == 'en':
                lINDEXER_API_PARMS['language'] = indexer_lang

            if ep_obj.show.dvdorder != 0:
                lINDEXER_API_PARMS['dvdorder'] = True

            t = sickbeard.indexerApi(
                ep_obj.show.indexer).indexer(**lINDEXER_API_PARMS)
            myShow = t[ep_obj.show.indexerid]
        except sickbeard.indexer_shownotfound, e:
            raise exceptions.ShowNotFoundException(str(e))
        except sickbeard.indexer_error, e:
            logger.log(
                u"Unable to connect to " +
                sickbeard.indexerApi(ep_obj.show.indexer).name +
                " while creating meta files - skipping - " + str(e),
                logger.ERROR)
            return False
Exemplo n.º 36
0
def get_show_by_name(name, checkExceptions=False, checkIndexers=False):
    in_cache = False
    foundResult = None

    logger.log(
        u"Checking the cache for:" + str(name),
        logger.DEBUG)

    cacheResult = sickbeard.name_cache.retrieveNameFromCache(name)
    if cacheResult:
        foundResult = findCertainShow(sickbeard.showList, cacheResult)
        if foundResult:
            in_cache = True
            logger.log(
                u"Cache lookup found Indexer ID:" + repr(
                    foundResult.indexerid) + ", using that for " + name,
                logger.DEBUG)

    if not foundResult:
        logger.log(
            u"Checking the database for:" + str(name),
            logger.DEBUG)

        dbResult = searchDBForShow(name)
        if dbResult:
            foundResult = findCertainShow(sickbeard.showList, dbResult[1])
            if foundResult:
                logger.log(
                    u"Database lookup found Indexer ID:" + str(
                        foundResult.indexerid) + ", using that for " + name, logger.DEBUG)

    if not foundResult and checkExceptions:
        if not foundResult:
            logger.log(
                u"Checking the scene exceptions list for:" + str(name),
                logger.DEBUG)

            for show in sickbeard.showList:
                if _check_against_names(name, show):
                    logger.log(
                        u"Scene exceptions lookup found Indexer ID:" + str(show.indexerid) + ", using that for " + name,
                        logger.DEBUG)
                    foundResult = show

    if not foundResult and checkIndexers:
        logger.log(
            u"Checking the Indexers for:" + str(name),
            logger.DEBUG)

        for indexer in sickbeard.indexerApi().indexers:
            try:
                lINDEXER_API_PARMS = sickbeard.indexerApi(indexer).api_params.copy()
                lINDEXER_API_PARMS['custom_ui'] = classes.ShowListUI
                lINDEXER_API_PARMS['search_all_languages'] = True

                t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)
                showObj = t[name]
            except:
                continue

            if showObj:
                foundResult = findCertainShow(sickbeard.showList, int(showObj["id"]))
                if foundResult:
                    logger.log(
                        u"Indexers lookup found Indexer ID:" + str(
                            foundResult.indexerid) + ", using that for " + name, logger.DEBUG)

    # add to name cache if we didn't get it from the cache
    if foundResult and not in_cache:
        sickbeard.name_cache.addNameToCache(name, foundResult.indexerid)

    return foundResult
Exemplo n.º 37
0
    def run(self):  # pylint: disable=too-many-branches, too-many-statements, too-many-return-statements

        super(QueueItemAdd, self).run()

        if self.showDir:
            try:
                assert isinstance(self.showDir, six.text_type)
            except AssertionError:
                logger.log(traceback.format_exc(), logger.WARNING)
                self._finish_early()
                return

        logger.log('Starting to add show {0}'.format(
            'by ShowDir: {0}'.format(self.showDir) if self.
            showDir else 'by Indexer Id: {0}'.format(self.indexer_id)))
        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = sickbeard.indexerApi(
                self.indexer).api_params.copy()
            lINDEXER_API_PARMS[
                'language'] = self.lang or sickbeard.INDEXER_DEFAULT_LANGUAGE

            logger.log('{0}: {1!r}'.format(
                sickbeard.indexerApi(self.indexer).name, lINDEXER_API_PARMS))

            t = sickbeard.indexerApi(
                self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id]

            # Let's try to create the show Dir if it's not provided. This way we force the show dir to build build using the
            # Indexers provided series name
            if self.root_dir and not self.showDir:
                show_name = get_showname_from_indexer(self.indexer,
                                                      self.indexer_id,
                                                      self.lang)
                if not show_name:
                    logger.log(
                        'Unable to get a show {0}, can\'t add the show'.format(
                            self.showDir))
                    self._finish_early()
                    return

                self.showDir = ek(os.path.join, self.root_dir,
                                  sanitize_filename(show_name))

                dir_exists = makeDir(self.showDir)
                if not dir_exists:
                    logger.log(
                        'Unable to create the folder {0}, can\'t add the show'.
                        format(self.showDir))
                    self._finish_early()
                    return

                chmodAsParent(self.showDir)

            # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that has no proper english version of the show
            if getattr(s, 'seriesname', None) is None:
                # noinspection PyPep8
                error_string = 'Show in {0} has no name on {1}, probably searched with the wrong language. Delete .nfo and add manually in the correct language.'.format(
                    self.showDir,
                    sickbeard.indexerApi(self.indexer).name)

                logger.log(error_string, logger.WARNING)
                ui.notifications.error('Unable to add show', error_string)

                self._finish_early()
                return

            # if the show has no episodes/seasons
            if not s:
                error_string = 'Show {0} is on {1} but contains no season/episode data.'.format(
                    s[b'seriesname'],
                    sickbeard.indexerApi(self.indexer).name)

                logger.log(error_string)
                ui.notifications.error('Unable to add show', error_string)

                self._finish_early()
                return
        except Exception as error:
            error_string = 'Unable to look up the show in {0} on {1} using ID {2}, not using the NFO. Delete .nfo and try adding manually again.'.format(
                self.showDir,
                sickbeard.indexerApi(self.indexer).name, self.indexer_id)

            logger.log('{0}: {1}'.format(error_string, error), logger.ERROR)
            ui.notifications.error('Unable to add show', error_string)

            if sickbeard.USE_TRAKT:
                trakt_id = sickbeard.indexerApi(
                    self.indexer).config[b'trakt_id']
                trakt_api = TraktAPI(sickbeard.SSL_VERIFY,
                                     sickbeard.TRAKT_TIMEOUT)

                title = self.showDir.split('/')[-1]
                data = {'shows': [{'title': title, 'ids': {}}]}
                if trakt_id == 'tvdb_id':
                    data['shows'][0]['ids']['tvdb'] = self.indexer_id
                else:
                    data['shows'][0]['ids']['tvrage'] = self.indexer_id

                trakt_api.traktRequest('sync/watchlist/remove',
                                       data,
                                       method='POST')

            self._finish_early()
            return

        try:
            try:
                newShow = TVShow(self.indexer, self.indexer_id, self.lang)
            except MultipleShowObjectsException as error:
                # If we have the show in our list, but the location is wrong, lets fix it and refresh!
                existing_show = Show.find(sickbeard.showList, self.indexer_id)
                # noinspection PyProtectedMember
                if existing_show and not ek(os.path.isdir,
                                            existing_show._location):  # pylint: disable=protected-access
                    newShow = existing_show
                else:
                    raise error

            newShow.loadFromIndexer()

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles if self.subtitles is not None else sickbeard.SUBTITLES_DEFAULT
            self.show.subtitles_sr_metadata = self.subtitles_sr_metadata
            self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
            self.show.season_folders = self.season_folders if self.season_folders is not None else sickbeard.SEASON_FOLDERS_DEFAULT
            self.show.anime = self.anime if self.anime is not None else sickbeard.ANIME_DEFAULT
            self.show.scene = self.scene if self.scene is not None else sickbeard.SCENE_DEFAULT
            self.show.paused = self.paused if self.paused is not None else False

            # set up default new/missing episode status
            logger.log(
                'Setting all episodes to the specified default status: {0}'.
                format(self.show.default_ep_status))
            self.show.default_ep_status = self.default_status

            if self.show.anime:
                self.show.release_groups = BlackAndWhiteList(
                    self.show.indexerid)
                if self.blacklist:
                    self.show.release_groups.set_black_keywords(self.blacklist)
                if self.whitelist:
                    self.show.release_groups.set_white_keywords(self.whitelist)

            # # be smart-ish about this
            # if self.show.genre and 'talk show' in self.show.genre.lower():
            #     self.show.air_by_date = 1
            # if self.show.genre and 'documentary' in self.show.genre.lower():
            #     self.show.air_by_date = 0
            # if self.show.classification and 'sports' in self.show.classification.lower():
            #     self.show.sports = 1

        except sickbeard.indexer_exception as error:
            error_string = 'Unable to add {0} due to an error with {1}'.format(
                self.show.name if self.show else 'show',
                sickbeard.indexerApi(self.indexer).name)

            logger.log('{0}: {1}'.format(error_string, error), logger.ERROR)
            ui.notifications.error('Unable to add show', error_string)

            self._finish_early()
            return

        except MultipleShowObjectsException:
            error_string = 'The show in {0} is already in your show list, skipping'.format(
                self.showDir)
            logger.log(error_string, logger.WARNING)
            ui.notifications.error('Show skipped', error_string)

            self._finish_early()
            return

        except Exception as error:
            logger.log('Error trying to add show: {0}'.format(error),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finish_early()
            raise

        logger.log('Retrieving show info from IMDb', logger.DEBUG)
        try:
            self.show.loadIMDbInfo()
        except imdb_exceptions.IMDbError as error:
            logger.log(' Something wrong on IMDb api: {0}'.format(error),
                       logger.WARNING)
        except Exception as error:
            logger.log('Error loading IMDb info: {0}'.format(error),
                       logger.ERROR)

        try:
            self.show.saveToDB()
        except Exception as error:
            logger.log(
                'Error saving the show to the database: {0}'.format(error),
                logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finish_early()
            raise

        # add it to the show list
        if not Show.find(sickbeard.showList, self.indexer_id):
            sickbeard.showList.append(self.show)

        try:
            self.show.loadEpisodesFromIndexer()
        except Exception as error:
            logger.log(
                'Error with {0}, not creating episode list: {1}'.format(
                    sickbeard.indexerApi(self.show.indexer).name, error),
                logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # update internal name cache
        name_cache.buildNameCache(self.show)

        try:
            self.show.loadEpisodesFromDir()
        except Exception as error:
            logger.log('Error searching dir for episodes: {0}'.format(error),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # if they set default ep status to WANTED then run the backlog to search for episodes
        # FIXME: This needs to be a backlog queue item!!!
        if self.show.default_ep_status == WANTED:
            logger.log(
                'Launching backlog for this show since its episodes are WANTED'
            )
            sickbeard.backlogSearchScheduler.action.searchBacklog([self.show])

        self.show.writeMetadata()
        self.show.updateMetadata()
        self.show.populateCache()

        self.show.flushEpisodes()

        if sickbeard.USE_TRAKT:
            # if there are specific episodes that need to be added by trakt
            sickbeard.traktCheckerScheduler.action.manageNewShow(self.show)
            # add show to trakt.tv library
            if sickbeard.TRAKT_SYNC:
                sickbeard.traktCheckerScheduler.action.addShowToTraktLibrary(
                    self.show)

            if sickbeard.TRAKT_SYNC_WATCHLIST:
                logger.log('update watchlist')
                notifiers.trakt_notifier.update_watchlist(show_obj=self.show)

        # Load XEM data to DB for show
        scene_numbering.xem_refresh(self.show.indexerid,
                                    self.show.indexer,
                                    force=True)

        # check if show has XEM mapping so we can determine if searches should go by scene numbering or indexer numbering.
        if not self.scene and scene_numbering.get_xem_numbering_for_show(
                self.show.indexerid, self.show.indexer):
            self.show.scene = 1

        # After initial add, set to default_status_after.
        self.show.default_ep_status = self.default_status_after

        super(QueueItemAdd, self).finish()
        self.finish()
Exemplo n.º 38
0
    def _show_data(self, show_obj):
        """
        Creates an elementTree XML structure for a MediaBrowser-style series.xml
        returns the resulting data object.

        show_obj: a TVShow instance to create the NFO for
        """

        indexer_lang = show_obj.lang
        # There's gotta be a better way of doing this but we don't wanna
        # change the language value elsewhere
        lINDEXER_API_PARMS = sickbeard.indexerApi(
            show_obj.indexer).api_params.copy()

        lINDEXER_API_PARMS['actors'] = True

        if indexer_lang and not indexer_lang == 'en':
            lINDEXER_API_PARMS['language'] = indexer_lang

        if show_obj.dvdorder != 0:
            lINDEXER_API_PARMS['dvdorder'] = True

        t = sickbeard.indexerApi(
            show_obj.indexer).indexer(**lINDEXER_API_PARMS)

        tv_node = etree.Element("Series")

        try:
            myShow = t[int(show_obj.indexerid)]
        except sickbeard.indexer_shownotfound:
            logger.log(
                u"Unable to find show with id " + str(show_obj.indexerid) +
                " on " + sickbeard.indexerApi(show_obj.indexer).name +
                ", skipping it", logger.ERROR)
            raise

        except sickbeard.indexer_error:
            logger.log(
                u"" + sickbeard.indexerApi(show_obj.indexer).name +
                " is down, can't use its data to make the NFO", logger.ERROR)
            raise

        # check for title and id
        if getattr(myShow, 'seriesname', None) is None or getattr(
                myShow, 'id', None) is None:
            logger.log(
                u"Incomplete info for show with id " +
                str(show_obj.indexerid) + " on " +
                sickbeard.indexerApi(show_obj.indexer).name + ", skipping it",
                logger.ERROR)
            return False

        indexerid = etree.SubElement(tv_node, "id")
        if getattr(myShow, 'id', None) is not None:
            indexerid.text = str(myShow['id'])

        indexer = etree.SubElement(tv_node, "indexer")
        if show_obj.indexer != None:
            indexer.text = str(show_obj.indexer)

        SeriesName = etree.SubElement(tv_node, "SeriesName")
        if getattr(myShow, 'seriesname', None) is not None:
            SeriesName.text = myShow['seriesname']

        Status = etree.SubElement(tv_node, "Status")
        if getattr(myShow, 'status', None) is not None:
            Status.text = myShow['status']

        Network = etree.SubElement(tv_node, "Network")
        if getattr(myShow, 'network', None) is not None:
            Network.text = myShow['network']

        Airs_Time = etree.SubElement(tv_node, "Airs_Time")
        if getattr(myShow, 'airs_time', None) is not None:
            Airs_Time.text = myShow['airs_time']

        Airs_DayOfWeek = etree.SubElement(tv_node, "Airs_DayOfWeek")
        if getattr(myShow, 'airs_dayofweek', None) is not None:
            Airs_DayOfWeek.text = myShow['airs_dayofweek']

        FirstAired = etree.SubElement(tv_node, "FirstAired")
        if getattr(myShow, 'firstaired', None) is not None:
            FirstAired.text = myShow['firstaired']

        ContentRating = etree.SubElement(tv_node, "ContentRating")
        MPAARating = etree.SubElement(tv_node, "MPAARating")
        certification = etree.SubElement(tv_node, "certification")
        if getattr(myShow, 'contentrating', None) is not None:
            ContentRating.text = myShow['contentrating']
            MPAARating.text = myShow['contentrating']
            certification.text = myShow['contentrating']

        MetadataType = etree.SubElement(tv_node, "Type")
        MetadataType.text = "Series"

        Overview = etree.SubElement(tv_node, "Overview")
        if getattr(myShow, 'overview', None) is not None:
            Overview.text = myShow['overview']

        PremiereDate = etree.SubElement(tv_node, "PremiereDate")
        if getattr(myShow, 'firstaired', None) is not None:
            PremiereDate.text = myShow['firstaired']

        Rating = etree.SubElement(tv_node, "Rating")
        if getattr(myShow, 'rating', None) is not None:
            Rating.text = myShow['rating']

        ProductionYear = etree.SubElement(tv_node, "ProductionYear")
        if getattr(myShow, 'firstaired', None) is not None:
            try:
                year_text = str(
                    datetime.datetime.strptime(myShow['firstaired'],
                                               '%Y-%m-%d').year)
                if year_text:
                    ProductionYear.text = year_text
            except:
                pass

        RunningTime = etree.SubElement(tv_node, "RunningTime")
        Runtime = etree.SubElement(tv_node, "Runtime")
        if getattr(myShow, 'runtime', None) is not None:
            RunningTime.text = myShow['runtime']
            Runtime.text = myShow['runtime']

        IMDB_ID = etree.SubElement(tv_node, "IMDB_ID")
        IMDB = etree.SubElement(tv_node, "IMDB")
        IMDbId = etree.SubElement(tv_node, "IMDbId")
        if getattr(myShow, 'imdb_id', None) is not None:
            IMDB_ID.text = myShow['imdb_id']
            IMDB.text = myShow['imdb_id']
            IMDbId.text = myShow['imdb_id']

        Zap2ItId = etree.SubElement(tv_node, "Zap2ItId")
        if getattr(myShow, 'zap2it_id', None) is not None:
            Zap2ItId.text = myShow['zap2it_id']

        Genres = etree.SubElement(tv_node, "Genres")
        for genre in myShow['genre'].split('|'):
            if genre:
                cur_genre = etree.SubElement(Genres, "Genre")
                cur_genre.text = genre

        Genre = etree.SubElement(tv_node, "Genre")
        if getattr(myShow, 'genre', None) is not None:
            Genre.text = "|".join([x for x in myShow["genre"].split('|') if x])

        Studios = etree.SubElement(tv_node, "Studios")
        Studio = etree.SubElement(Studios, "Studio")
        if getattr(myShow, 'network', None) is not None:
            Studio.text = myShow['network']

        Persons = etree.SubElement(tv_node, "Persons")
        if getattr(myShow, 'actors', None) is not None:
            for actor in myShow['_actors']:
                cur_actor = etree.SubElement(Persons, "Person")
                cur_actor_name = etree.SubElement(cur_actor, "Name")
                cur_actor_name.text = actor['name'].strip()
                cur_actor_type = etree.SubElement(cur_actor, "Type")
                cur_actor_type.text = "Actor"
                cur_actor_role = etree.SubElement(cur_actor, "Role")
                cur_actor_role_text = actor['role']
                if cur_actor_role_text != None:
                    cur_actor_role.text = cur_actor_role_text

        helpers.indentXML(tv_node)

        data = etree.ElementTree(tv_node)

        return data
Exemplo n.º 39
0
                logger.ERROR)
            return False

        rootNode = etree.Element("Item")

        # write an MediaBrowser XML containing info for all matching episodes
        for curEpToWrite in eps_to_write:

            try:
                myEp = myShow[curEpToWrite.season][curEpToWrite.episode]
            except (sickbeard.indexer_episodenotfound,
                    sickbeard.indexer_seasonnotfound):
                logger.log(u"Unable to find episode " +
                           str(curEpToWrite.season) + "x" +
                           str(curEpToWrite.episode) + " on " +
                           sickbeard.indexerApi(ep_obj.show.indexer).name +
                           ".. has it been removed? Should I delete from db?")
                return None

            if curEpToWrite == ep_obj:
                # root (or single) episode

                # default to today's date for specials if firstaired is not set
                if getattr(myEp, 'firstaired',
                           None) is None and ep_obj.season == 0:
                    myEp['firstaired'] = str(datetime.date.fromordinal(1))

                if getattr(myEp, 'episodename', None) is None or getattr(
                        myEp, 'firstaired', None) is None:
                    return None
Exemplo n.º 40
0
def fix_xem_numbering(indexer_id, indexer):
    """
    Returns a dict of (season, episode) : (sceneSeason, sceneEpisode) mappings
    for an entire show.  Both the keys and values of the dict are tuples.
    Will be empty if there are no scene numbers set in xem
    """
    if indexer_id is None:
        return {}

    indexer_id = int(indexer_id)
    indexer = int(indexer)

    # query = [{
    # "name": self.show.name,
    # "seasons": [{
    # "episodes": [{
    # "episode_number": None,
    # "name": None
    # }],
    # "season_number": None,
    #                          }],
    #              "/tv/tv_program/number_of_seasons": [],
    #              "/tv/tv_program/number_of_episodes": [],
    #              "/tv/tv_program/thetvdb_id": [],
    #              "/tv/tv_program/tvrage_id": [],
    #              "type": "/tv/tv_program",
    #          }]
    #
    #
    # url = 'https://www.googleapis.com/freebase/v1/mqlread'
    # api_key = "AIzaSyCCHNp4dhVHxJYzbLiCE4y4a1rgTnX4fDE"
    # params = {
    #     'query': json.dumps(query),
    #     'key': api_key
    # }
    #
    #
    # def get_from_api(url, params=None):
    #     """Build request and return results
    #     """
    #     import xmltodict
    #
    #     response = requests.get(url, params=params)
    #     if response.status_code == 200:
    #         try:
    #             return response.json()
    #         except ValueError:
    #             return xmltodict.parse(response.text)['Data']
    #
    # # Get query results
    # tmp = get_from_api(url, params=params)['result']

    myDB = db.DBConnection()
    rows = myDB.select(
        'SELECT season, episode, absolute_number, scene_season, scene_episode, scene_absolute_number FROM tv_episodes WHERE indexer = ? and showid = ?',
        [indexer, indexer_id])

    last_absolute_number = None
    last_scene_season = None
    last_scene_episode = None
    last_scene_absolute_number = None

    update_absolute_number = False
    update_scene_season = False
    update_scene_episode = False
    update_scene_absolute_number = False

    logger.log(
        u'Fixing any XEM scene mapping issues for show %s on %s' % (
            indexer_id,
            sickbeard.indexerApi(indexer).name,
        ), logger.DEBUG)

    cl = []
    for row in rows:
        season = int(row['season'])
        episode = int(row['episode'])

        if not int(row['scene_season']) and last_scene_season:
            scene_season = last_scene_season + 1
            update_scene_season = True
        else:
            scene_season = int(row['scene_season'])
            if last_scene_season and scene_season < last_scene_season:
                scene_season = last_scene_season + 1
                update_scene_season = True

        if not int(row['scene_episode']) and last_scene_episode:
            scene_episode = last_scene_episode + 1
            update_scene_episode = True
        else:
            scene_episode = int(row['scene_episode'])
            if last_scene_episode and scene_episode < last_scene_episode:
                scene_episode = last_scene_episode + 1
                update_scene_episode = True

        # check for unset values and correct them
        if not int(row['absolute_number']) and last_absolute_number:
            absolute_number = last_absolute_number + 1
            update_absolute_number = True
        else:
            absolute_number = int(row['absolute_number'])
            if last_absolute_number and absolute_number < last_absolute_number:
                absolute_number = last_absolute_number + 1
                update_absolute_number = True

        if not int(
                row['scene_absolute_number']) and last_scene_absolute_number:
            scene_absolute_number = last_scene_absolute_number + 1
            update_scene_absolute_number = True
        else:
            scene_absolute_number = int(row['scene_absolute_number'])
            if last_scene_absolute_number and scene_absolute_number < last_scene_absolute_number:
                scene_absolute_number = last_scene_absolute_number + 1
                update_scene_absolute_number = True

        # store values for lookup on next iteration
        last_absolute_number = absolute_number
        last_scene_season = scene_season
        last_scene_episode = scene_episode
        last_scene_absolute_number = scene_absolute_number

        if update_absolute_number:
            cl.append([
                "UPDATE tv_episodes SET absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?",
                [absolute_number, indexer_id, season, episode]
            ])
            update_absolute_number = False

        if update_scene_season:
            cl.append([
                "UPDATE tv_episodes SET scene_season = ? WHERE showid = ? AND season = ? AND episode = ?",
                [scene_season, indexer_id, season, episode]
            ])
            update_scene_season = False

        if update_scene_episode:
            cl.append([
                "UPDATE tv_episodes SET scene_episode = ? WHERE showid = ? AND season = ? AND episode = ?",
                [scene_episode, indexer_id, season, episode]
            ])
            update_scene_episode = False

        if update_scene_absolute_number:
            cl.append([
                "UPDATE tv_episodes SET scene_absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?",
                [scene_absolute_number, indexer_id, season, episode]
            ])
            update_scene_absolute_number = False

    if len(cl) > 0:
        myDB = db.DBConnection()
        myDB.mass_action(cl)
Exemplo n.º 41
0
def xem_refresh(indexer_id, indexer, force=False):
    """
    Refresh data from xem for a tv show
    
    @param indexer_id: int
    """
    if indexer_id is None:
        return

    indexer_id = int(indexer_id)
    indexer = int(indexer)

    # XEM API URL
    url = "http://thexem.de/map/all?id=%s&origin=%s&destination=scene" % (
        indexer_id, sickbeard.indexerApi(indexer).config['xem_origin'])

    MAX_REFRESH_AGE_SECS = 86400  # 1 day

    myDB = db.DBConnection()
    rows = myDB.select(
        "SELECT last_refreshed FROM xem_refresh WHERE indexer = ? and indexer_id = ?",
        [indexer, indexer_id])
    if rows:
        lastRefresh = int(rows[0]['last_refreshed'])
        refresh = int(time.mktime(datetime.datetime.today().timetuple())
                      ) > lastRefresh + MAX_REFRESH_AGE_SECS
    else:
        refresh = True

    if refresh or force:
        logger.log(
            u'Looking up XEM scene mapping for show %s on %s' % (
                indexer_id,
                sickbeard.indexerApi(indexer).name,
            ), logger.DEBUG)

        # mark refreshed
        myDB.upsert(
            "xem_refresh", {
                'indexer':
                indexer,
                'last_refreshed':
                int(time.mktime(datetime.datetime.today().timetuple()))
            }, {'indexer_id': indexer_id})

        try:
            from .scene_exceptions import xem_session
            parsedJSON = sickbeard.helpers.getURL(url,
                                                  session=xem_session,
                                                  json=True)
            if not parsedJSON or parsedJSON == '':
                logger.log(
                    u'No XEM data for show "%s on %s"' % (
                        indexer_id,
                        sickbeard.indexerApi(indexer).name,
                    ), logger.INFO)
                return

            if 'success' in parsedJSON['result']:
                cl = []
                for entry in parsedJSON['data']:
                    if 'scene' in entry:
                        cl.append([
                            "UPDATE tv_episodes SET scene_season = ?, scene_episode = ?, scene_absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?",
                            [
                                entry['scene']['season'],
                                entry['scene']['episode'],
                                entry['scene']['absolute'], indexer_id,
                                entry[sickbeard.indexerApi(
                                    indexer).config['xem_origin']]['season'],
                                entry[sickbeard.indexerApi(
                                    indexer).config['xem_origin']]['episode']
                            ]
                        ])
                    if 'scene_2' in entry:  # for doubles
                        cl.append([
                            "UPDATE tv_episodes SET scene_season = ?, scene_episode = ?, scene_absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?",
                            [
                                entry['scene_2']['season'],
                                entry['scene_2']['episode'],
                                entry['scene_2']['absolute'], indexer_id,
                                entry[sickbeard.indexerApi(
                                    indexer).config['xem_origin']]['season'],
                                entry[sickbeard.indexerApi(
                                    indexer).config['xem_origin']]['episode']
                            ]
                        ])

                if len(cl) > 0:
                    myDB = db.DBConnection()
                    myDB.mass_action(cl)
            else:
                logger.log(
                    u"Empty lookup result - no XEM data for show %s on %s" % (
                        indexer_id,
                        sickbeard.indexerApi(indexer).name,
                    ), logger.DEBUG)
        except Exception, e:
            logger.log(
                u"Exception while refreshing XEM data for show " +
                str(indexer_id) + " on " + sickbeard.indexerApi(indexer).name +
                ": " + ex(e), logger.WARNING)
            logger.log(traceback.format_exc(), logger.DEBUG)
Exemplo n.º 42
0
def retrieve_exceptions():
    """
    Looks up the exceptions on github, parses them into a dict, and inserts them into the
    scene_exceptions table in cache.db. Also clears the scene name cache.
    """
    global exception_dict, anidb_exception_dict, xem_exception_dict

    # exceptions are stored on github pages
    for indexer in sickbeard.indexerApi().indexers:
        if shouldRefresh(sickbeard.indexerApi(indexer).name):
            logger.log(u'Checking for scene exception updates for %s' %
                       sickbeard.indexerApi(indexer).name)

            url = sickbeard.indexerApi(indexer).config['scene_url']

            url_data = helpers.getURL(url)
            if None is url_data:
                # When None is urlData, trouble connecting to github
                logger.log(
                    u'Check scene exceptions update failed. Unable to get URL: %s'
                    % url, logger.ERROR)
                continue

            else:
                setLastRefresh(sickbeard.indexerApi(indexer).name)

                # each exception is on one line with the format indexer_id: 'show name 1', 'show name 2', etc
                for cur_line in url_data.splitlines():
                    cur_line = cur_line.decode('utf-8')
                    indexer_id, sep, aliases = cur_line.partition(
                        ':')  # @UnusedVariable

                    if not aliases:
                        continue

                    indexer_id = int(indexer_id)

                    # regex out the list of shows, taking \' into account
                    # alias_list = [re.sub(r'\\(.)', r'\1', x) for x in re.findall(r"'(.*?)(?<!\\)',?", aliases)]
                    alias_list = [{
                        re.sub(r'\\(.)', r'\1', x): -1
                    } for x in re.findall(r"'(.*?)(?<!\\)',?", aliases)]
                    exception_dict[indexer_id] = alias_list
                    del alias_list
                del url_data

    # XEM scene exceptions
    _xem_exceptions_fetcher()
    for xem_ex in xem_exception_dict:
        if xem_ex in exception_dict:
            exception_dict[
                xem_ex] = exception_dict[xem_ex] + xem_exception_dict[xem_ex]
        else:
            exception_dict[xem_ex] = xem_exception_dict[xem_ex]

    # AniDB scene exceptions
    _anidb_exceptions_fetcher()
    for anidb_ex in anidb_exception_dict:
        if anidb_ex in exception_dict:
            exception_dict[anidb_ex] = exception_dict[
                anidb_ex] + anidb_exception_dict[anidb_ex]
        else:
            exception_dict[anidb_ex] = anidb_exception_dict[anidb_ex]

    changed_exceptions = False

    # write all the exceptions we got off the net into the database
    my_db = db.DBConnection()
    cl = []
    for cur_indexer_id in exception_dict:

        # get a list of the existing exceptions for this ID
        existing_exceptions = [
            x['show_name'] for x in my_db.select(
                'SELECT * FROM scene_exceptions WHERE indexer_id = ?',
                [cur_indexer_id])
        ]

        if cur_indexer_id not in exception_dict:
            continue

        for cur_exception_dict in exception_dict[cur_indexer_id]:
            try:
                cur_exception, cur_season = cur_exception_dict.items()[0]
            except Exception:
                logger.log('scene exception error', logger.ERROR)
                logger.log(traceback.format_exc(), logger.ERROR)
                continue

            # if this exception isn't already in the DB then add it
            if cur_exception not in existing_exceptions:

                if not isinstance(cur_exception, unicode):
                    cur_exception = unicode(cur_exception, 'utf-8', 'replace')

                cl.append([
                    'INSERT INTO scene_exceptions (indexer_id, show_name, season) VALUES (?,?,?)',
                    [cur_indexer_id, cur_exception, cur_season]
                ])
                changed_exceptions = True

    my_db.mass_action(cl)

    # since this could invalidate the results of the cache we clear it out after updating
    if changed_exceptions:
        logger.log(u'Updated scene exceptions')
    else:
        logger.log(u'No scene exceptions update needed')

    # cleanup
    exception_dict.clear()
    anidb_exception_dict.clear()
    xem_exception_dict.clear()
Exemplo n.º 43
0
 def __str__(self):
     return str(self.date) + " " + self.name + " " + str(
         self.season) + "x" + str(self.episode) + " of " + str(
             self.indexerid) + " from " + str(
                 sickbeard.indexerApi(self.indexer).name)
Exemplo n.º 44
0
def fix_xem_numbering(indexer_id, indexer):  # pylint:disable=too-many-locals, too-many-branches, too-many-statements
    """
    Returns a dict of (season, episode) : (sceneSeason, sceneEpisode) mappings
    for an entire show.  Both the keys and values of the dict are tuples.
    Will be empty if there are no scene numbers set in xem
    """
    if indexer_id is None:
        return {}

    indexer_id = int(indexer_id)
    indexer = int(indexer)

    main_db_con = db.DBConnection()
    rows = main_db_con.select(
        'SELECT season, episode, absolute_number, scene_season, scene_episode, scene_absolute_number FROM tv_episodes WHERE indexer = ? and showid = ?',
        [indexer, indexer_id])

    last_absolute_number = None
    last_scene_season = None
    last_scene_episode = None
    last_scene_absolute_number = None

    update_absolute_number = False
    update_scene_season = False
    update_scene_episode = False
    update_scene_absolute_number = False

    logger.log(
        u'Fixing any XEM scene mapping issues for show %s on %s' % (
            indexer_id,
            sickbeard.indexerApi(indexer).name,
        ), logger.DEBUG)

    cl = []
    for row in rows:
        season = int(row['season'])
        episode = int(row['episode'])

        if not int(row['scene_season']) and last_scene_season:
            scene_season = last_scene_season + 1
            update_scene_season = True
        else:
            scene_season = int(row['scene_season'])
            if last_scene_season and scene_season < last_scene_season:
                scene_season = last_scene_season + 1
                update_scene_season = True

        if not int(row['scene_episode']) and last_scene_episode:
            scene_episode = last_scene_episode + 1
            update_scene_episode = True
        else:
            scene_episode = int(row['scene_episode'])
            if last_scene_episode and scene_episode < last_scene_episode:
                scene_episode = last_scene_episode + 1
                update_scene_episode = True

        # check for unset values and correct them
        if not int(row['absolute_number']) and last_absolute_number:
            absolute_number = last_absolute_number + 1
            update_absolute_number = True
        else:
            absolute_number = int(row['absolute_number'])
            if last_absolute_number and absolute_number < last_absolute_number:
                absolute_number = last_absolute_number + 1
                update_absolute_number = True

        if not int(
                row['scene_absolute_number']) and last_scene_absolute_number:
            scene_absolute_number = last_scene_absolute_number + 1
            update_scene_absolute_number = True
        else:
            scene_absolute_number = int(row['scene_absolute_number'])
            if last_scene_absolute_number and scene_absolute_number < last_scene_absolute_number:
                scene_absolute_number = last_scene_absolute_number + 1
                update_scene_absolute_number = True

        # store values for lookup on next iteration
        last_absolute_number = absolute_number
        last_scene_season = scene_season
        last_scene_episode = scene_episode
        last_scene_absolute_number = scene_absolute_number

        if update_absolute_number:
            cl.append([
                "UPDATE tv_episodes SET absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?",
                [absolute_number, indexer_id, season, episode]
            ])
            update_absolute_number = False

        if update_scene_season:
            cl.append([
                "UPDATE tv_episodes SET scene_season = ? WHERE showid = ? AND season = ? AND episode = ?",
                [scene_season, indexer_id, season, episode]
            ])
            update_scene_season = False

        if update_scene_episode:
            cl.append([
                "UPDATE tv_episodes SET scene_episode = ? WHERE showid = ? AND season = ? AND episode = ?",
                [scene_episode, indexer_id, season, episode]
            ])
            update_scene_episode = False

        if update_scene_absolute_number:
            cl.append([
                "UPDATE tv_episodes SET scene_absolute_number = ? WHERE showid = ? AND season = ? AND episode = ?",
                [scene_absolute_number, indexer_id, season, episode]
            ])
            update_scene_absolute_number = False

    if len(cl) > 0:
        main_db_con = db.DBConnection()
        main_db_con.mass_action(cl)
Exemplo n.º 45
0
    def run(self):  # pylint: disable=too-many-branches, too-many-statements

        super(QueueItemUpdate, self).run()

        logger.log('Beginning update of {0}'.format(self.show.name),
                   logger.DEBUG)

        logger.log(
            'Retrieving show info from {0}'.format(
                sickbeard.indexerApi(self.show.indexer).name), logger.DEBUG)
        try:
            self.show.loadFromIndexer(cache=not self.force)
        except sickbeard.indexer_error as error:
            logger.log(
                'Unable to contact {0}, aborting: {1}'.format(
                    sickbeard.indexerApi(self.show.indexer).name, error),
                logger.WARNING)
            super(QueueItemUpdate, self).finish()
            self.finish()
            return
        except sickbeard.indexer_attributenotfound as error:
            logger.log(
                'Data retrieved from {0} was incomplete, aborting: {1}'.format(
                    sickbeard.indexerApi(self.show.indexer).name, error),
                logger.ERROR)
            super(QueueItemUpdate, self).finish()
            self.finish()
            return

        logger.log('Retrieving show info from IMDb', logger.DEBUG)
        try:
            self.show.loadIMDbInfo()
        except imdb_exceptions.IMDbError as error:
            logger.log('Something wrong on IMDb api: {0}'.format(error),
                       logger.WARNING)
        except Exception as error:
            logger.log('Error loading IMDb info: {0}'.format(error),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # have to save show before reading episodes from db
        try:
            self.show.saveToDB()
        except Exception as error:
            logger.log(
                'Error saving show info to the database: {0}'.format(error),
                logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # get episode list from DB
        logger.log('Loading all episodes from the database', logger.DEBUG)
        DBEpList = self.show.loadEpisodesFromDB()

        # get episode list from TVDB
        logger.log(
            'Loading all episodes from {0}'.format(
                sickbeard.indexerApi(self.show.indexer).name), logger.DEBUG)
        try:
            IndexerEpList = self.show.loadEpisodesFromIndexer(
                cache=not self.force)
        except sickbeard.indexer_exception as error:
            logger.log(
                'Unable to get info from {0}, the show info will not be refreshed: {1}'
                .format(sickbeard.indexerApi(self.show.indexer).name,
                        error), logger.ERROR)
            IndexerEpList = None

        if not IndexerEpList:
            logger.log(
                'No data returned from {0}, unable to update this show.'.
                format(sickbeard.indexerApi(self.show.indexer).name),
                logger.ERROR)
        else:
            # for each ep we found on the Indexer delete it from the DB list
            for curSeason in IndexerEpList:
                for curEpisode in IndexerEpList[curSeason]:
                    curEp = self.show.getEpisode(curSeason, curEpisode)
                    curEp.saveToDB()

                    if curSeason in DBEpList and curEpisode in DBEpList[
                            curSeason]:
                        del DBEpList[curSeason][curEpisode]

            # remaining episodes in the DB list are not on the indexer, just delete them from the DB
            for curSeason in DBEpList:
                for curEpisode in DBEpList[curSeason]:
                    logger.log(
                        'Permanently deleting episode {0:02d}E{1:02d} from the database'
                        .format(curSeason, curEpisode), logger.INFO)
                    curEp = self.show.getEpisode(curSeason, curEpisode)
                    try:
                        curEp.deleteEpisode()
                    except EpisodeDeletedException:
                        pass

        #  save show again, in case episodes have changed
        try:
            self.show.saveToDB()
        except Exception as error:
            logger.log(
                'Error saving show info to the database: {0}'.format(error),
                logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        logger.log('Finished update of {0}'.format(self.show.name),
                   logger.DEBUG)

        sickbeard.showQueueScheduler.action.refresh_show(self.show, self.force)
        super(QueueItemUpdate, self).finish()
        self.finish()
Exemplo n.º 46
0
class MediaBrowserMetadata(generic.GenericMetadata):
    """
    Metadata generation class for Media Browser 2.x/3.x - Standard Mode.

    The following file structure is used:

    show_root/series.xml                       (show metadata)
    show_root/folder.jpg                       (poster)
    show_root/backdrop.jpg                     (fanart)
    show_root/Season ##/folder.jpg             (season thumb)
    show_root/Season ##/filename.ext           (*)
    show_root/Season ##/metadata/filename.xml  (episode metadata)
    show_root/Season ##/metadata/filename.jpg  (episode thumb)
    """
    def __init__(self,
                 show_metadata=False,
                 episode_metadata=False,
                 fanart=False,
                 poster=False,
                 banner=False,
                 episode_thumbnails=False,
                 season_posters=False,
                 season_banners=False,
                 season_all_poster=False,
                 season_all_banner=False):

        generic.GenericMetadata.__init__(self, show_metadata, episode_metadata,
                                         fanart, poster, banner,
                                         episode_thumbnails, season_posters,
                                         season_banners, season_all_poster,
                                         season_all_banner)

        self.name = 'MediaBrowser'

        self._ep_nfo_extension = 'xml'
        self._show_metadata_filename = 'series.xml'

        self.fanart_name = "backdrop.jpg"
        self.poster_name = "folder.jpg"

        # web-ui metadata template
        self.eg_show_metadata = "series.xml"
        self.eg_episode_metadata = "Season##\\metadata\\<i>filename</i>.xml"
        self.eg_fanart = "backdrop.jpg"
        self.eg_poster = "folder.jpg"
        self.eg_banner = "banner.jpg"
        self.eg_episode_thumbnails = "Season##\\metadata\\<i>filename</i>.jpg"
        self.eg_season_posters = "Season##\\folder.jpg"
        self.eg_season_banners = "Season##\\banner.jpg"
        self.eg_season_all_poster = "<i>not supported</i>"
        self.eg_season_all_banner = "<i>not supported</i>"

    # Override with empty methods for unsupported features
    def retrieveShowMetadata(self, folder):
        # while show metadata is generated, it is not supported for our lookup
        return (None, None, None)

    def create_season_all_poster(self, show_obj):
        pass

    def create_season_all_banner(self, show_obj):
        pass

    def get_episode_file_path(self, ep_obj):
        """
        Returns a full show dir/metadata/episode.xml path for MediaBrowser
        episode metadata files

        ep_obj: a TVEpisode object to get the path for
        """

        if ek.ek(os.path.isfile, ep_obj.location):
            xml_file_name = helpers.replaceExtension(
                ek.ek(os.path.basename, ep_obj.location),
                self._ep_nfo_extension)
            metadata_dir_name = ek.ek(os.path.join,
                                      ek.ek(os.path.dirname, ep_obj.location),
                                      'metadata')
            xml_file_path = ek.ek(os.path.join, metadata_dir_name,
                                  xml_file_name)
        else:
            logger.log(
                u"Episode location doesn't exist: " + str(ep_obj.location),
                logger.DEBUG)
            return ''

        return xml_file_path

    def get_episode_thumb_path(self, ep_obj):
        """
        Returns a full show dir/metadata/episode.jpg path for MediaBrowser
        episode thumbs.

        ep_obj: a TVEpisode object to get the path from
        """

        if ek.ek(os.path.isfile, ep_obj.location):
            tbn_file_name = helpers.replaceExtension(
                ek.ek(os.path.basename, ep_obj.location), 'jpg')
            metadata_dir_name = ek.ek(os.path.join,
                                      ek.ek(os.path.dirname, ep_obj.location),
                                      'metadata')
            tbn_file_path = ek.ek(os.path.join, metadata_dir_name,
                                  tbn_file_name)
        else:
            return None

        return tbn_file_path

    def get_season_poster_path(self, show_obj, season):
        """
        Season thumbs for MediaBrowser go in Show Dir/Season X/folder.jpg

        If no season folder exists, None is returned
        """

        dir_list = [
            x for x in ek.ek(os.listdir, show_obj.location)
            if ek.ek(os.path.isdir, ek.ek(os.path.join, show_obj.location, x))
        ]

        season_dir_regex = '^Season\s+(\d+)$'

        season_dir = None

        for cur_dir in dir_list:
            # MediaBrowser 1.x only supports 'Specials'
            # MediaBrowser 2.x looks to only support 'Season 0'
            # MediaBrowser 3.x looks to mimic XBMC/Plex support
            if season == 0 and cur_dir == "Specials":
                season_dir = cur_dir
                break

            match = re.match(season_dir_regex, cur_dir, re.I)
            if not match:
                continue

            cur_season = int(match.group(1))

            if cur_season == season:
                season_dir = cur_dir
                break

        if not season_dir:
            logger.log(
                u"Unable to find a season dir for season " + str(season),
                logger.DEBUG)
            return None

        logger.log(
            u"Using " + str(season_dir) +
            "/folder.jpg as season dir for season " + str(season),
            logger.DEBUG)

        return ek.ek(os.path.join, show_obj.location, season_dir, 'folder.jpg')

    def get_season_banner_path(self, show_obj, season):
        """
        Season thumbs for MediaBrowser go in Show Dir/Season X/banner.jpg

        If no season folder exists, None is returned
        """

        dir_list = [
            x for x in ek.ek(os.listdir, show_obj.location)
            if ek.ek(os.path.isdir, ek.ek(os.path.join, show_obj.location, x))
        ]

        season_dir_regex = '^Season\s+(\d+)$'

        season_dir = None

        for cur_dir in dir_list:
            # MediaBrowser 1.x only supports 'Specials'
            # MediaBrowser 2.x looks to only support 'Season 0'
            # MediaBrowser 3.x looks to mimic XBMC/Plex support
            if season == 0 and cur_dir == "Specials":
                season_dir = cur_dir
                break

            match = re.match(season_dir_regex, cur_dir, re.I)
            if not match:
                continue

            cur_season = int(match.group(1))

            if cur_season == season:
                season_dir = cur_dir
                break

        if not season_dir:
            logger.log(
                u"Unable to find a season dir for season " + str(season),
                logger.DEBUG)
            return None

        logger.log(
            u"Using " + str(season_dir) +
            "/banner.jpg as season dir for season " + str(season),
            logger.DEBUG)

        return ek.ek(os.path.join, show_obj.location, season_dir, 'banner.jpg')

    def _show_data(self, show_obj):
        """
        Creates an elementTree XML structure for a MediaBrowser-style series.xml
        returns the resulting data object.

        show_obj: a TVShow instance to create the NFO for
        """

        indexer_lang = show_obj.lang
        # There's gotta be a better way of doing this but we don't wanna
        # change the language value elsewhere
        lINDEXER_API_PARMS = sickbeard.indexerApi(
            show_obj.indexer).api_params.copy()

        lINDEXER_API_PARMS['actors'] = True

        if indexer_lang and not indexer_lang == 'en':
            lINDEXER_API_PARMS['language'] = indexer_lang

        if show_obj.dvdorder != 0:
            lINDEXER_API_PARMS['dvdorder'] = True

        t = sickbeard.indexerApi(
            show_obj.indexer).indexer(**lINDEXER_API_PARMS)

        tv_node = etree.Element("Series")

        try:
            myShow = t[int(show_obj.indexerid)]
        except sickbeard.indexer_shownotfound:
            logger.log(
                u"Unable to find show with id " + str(show_obj.indexerid) +
                " on " + sickbeard.indexerApi(show_obj.indexer).name +
                ", skipping it", logger.ERROR)
            raise

        except sickbeard.indexer_error:
            logger.log(
                u"" + sickbeard.indexerApi(show_obj.indexer).name +
                " is down, can't use its data to make the NFO", logger.ERROR)
            raise

        # check for title and id
        if getattr(myShow, 'seriesname', None) is None or getattr(
                myShow, 'id', None) is None:
            logger.log(
                u"Incomplete info for show with id " +
                str(show_obj.indexerid) + " on " +
                sickbeard.indexerApi(show_obj.indexer).name + ", skipping it",
                logger.ERROR)
            return False

        indexerid = etree.SubElement(tv_node, "id")
        if getattr(myShow, 'id', None) is not None:
            indexerid.text = str(myShow['id'])

        indexer = etree.SubElement(tv_node, "indexer")
        if show_obj.indexer != None:
            indexer.text = str(show_obj.indexer)

        SeriesName = etree.SubElement(tv_node, "SeriesName")
        if getattr(myShow, 'seriesname', None) is not None:
            SeriesName.text = myShow['seriesname']

        Status = etree.SubElement(tv_node, "Status")
        if getattr(myShow, 'status', None) is not None:
            Status.text = myShow['status']

        Network = etree.SubElement(tv_node, "Network")
        if getattr(myShow, 'network', None) is not None:
            Network.text = myShow['network']

        Airs_Time = etree.SubElement(tv_node, "Airs_Time")
        if getattr(myShow, 'airs_time', None) is not None:
            Airs_Time.text = myShow['airs_time']

        Airs_DayOfWeek = etree.SubElement(tv_node, "Airs_DayOfWeek")
        if getattr(myShow, 'airs_dayofweek', None) is not None:
            Airs_DayOfWeek.text = myShow['airs_dayofweek']

        FirstAired = etree.SubElement(tv_node, "FirstAired")
        if getattr(myShow, 'firstaired', None) is not None:
            FirstAired.text = myShow['firstaired']

        ContentRating = etree.SubElement(tv_node, "ContentRating")
        MPAARating = etree.SubElement(tv_node, "MPAARating")
        certification = etree.SubElement(tv_node, "certification")
        if getattr(myShow, 'contentrating', None) is not None:
            ContentRating.text = myShow['contentrating']
            MPAARating.text = myShow['contentrating']
            certification.text = myShow['contentrating']

        MetadataType = etree.SubElement(tv_node, "Type")
        MetadataType.text = "Series"

        Overview = etree.SubElement(tv_node, "Overview")
        if getattr(myShow, 'overview', None) is not None:
            Overview.text = myShow['overview']

        PremiereDate = etree.SubElement(tv_node, "PremiereDate")
        if getattr(myShow, 'firstaired', None) is not None:
            PremiereDate.text = myShow['firstaired']

        Rating = etree.SubElement(tv_node, "Rating")
        if getattr(myShow, 'rating', None) is not None:
            Rating.text = myShow['rating']

        ProductionYear = etree.SubElement(tv_node, "ProductionYear")
        if getattr(myShow, 'firstaired', None) is not None:
            try:
                year_text = str(
                    datetime.datetime.strptime(myShow['firstaired'],
                                               '%Y-%m-%d').year)
                if year_text:
                    ProductionYear.text = year_text
            except:
                pass

        RunningTime = etree.SubElement(tv_node, "RunningTime")
        Runtime = etree.SubElement(tv_node, "Runtime")
        if getattr(myShow, 'runtime', None) is not None:
            RunningTime.text = myShow['runtime']
            Runtime.text = myShow['runtime']

        IMDB_ID = etree.SubElement(tv_node, "IMDB_ID")
        IMDB = etree.SubElement(tv_node, "IMDB")
        IMDbId = etree.SubElement(tv_node, "IMDbId")
        if getattr(myShow, 'imdb_id', None) is not None:
            IMDB_ID.text = myShow['imdb_id']
            IMDB.text = myShow['imdb_id']
            IMDbId.text = myShow['imdb_id']

        Zap2ItId = etree.SubElement(tv_node, "Zap2ItId")
        if getattr(myShow, 'zap2it_id', None) is not None:
            Zap2ItId.text = myShow['zap2it_id']

        Genres = etree.SubElement(tv_node, "Genres")
        for genre in myShow['genre'].split('|'):
            if genre:
                cur_genre = etree.SubElement(Genres, "Genre")
                cur_genre.text = genre

        Genre = etree.SubElement(tv_node, "Genre")
        if getattr(myShow, 'genre', None) is not None:
            Genre.text = "|".join([x for x in myShow["genre"].split('|') if x])

        Studios = etree.SubElement(tv_node, "Studios")
        Studio = etree.SubElement(Studios, "Studio")
        if getattr(myShow, 'network', None) is not None:
            Studio.text = myShow['network']

        Persons = etree.SubElement(tv_node, "Persons")
        if getattr(myShow, 'actors', None) is not None:
            for actor in myShow['_actors']:
                cur_actor = etree.SubElement(Persons, "Person")
                cur_actor_name = etree.SubElement(cur_actor, "Name")
                cur_actor_name.text = actor['name'].strip()
                cur_actor_type = etree.SubElement(cur_actor, "Type")
                cur_actor_type.text = "Actor"
                cur_actor_role = etree.SubElement(cur_actor, "Role")
                cur_actor_role_text = actor['role']
                if cur_actor_role_text != None:
                    cur_actor_role.text = cur_actor_role_text

        helpers.indentXML(tv_node)

        data = etree.ElementTree(tv_node)

        return data

    def _ep_data(self, ep_obj):
        """
        Creates an elementTree XML structure for a MediaBrowser style episode.xml
        and returns the resulting data object.

        show_obj: a TVShow instance to create the NFO for
        """

        eps_to_write = [ep_obj] + ep_obj.relatedEps

        persons_dict = {}
        persons_dict['Director'] = []
        persons_dict['GuestStar'] = []
        persons_dict['Writer'] = []

        indexer_lang = ep_obj.show.lang

        try:
            lINDEXER_API_PARMS = sickbeard.indexerApi(
                ep_obj.show.indexer).api_params.copy()

            lINDEXER_API_PARMS['actors'] = True

            if indexer_lang and not indexer_lang == 'en':
                lINDEXER_API_PARMS['language'] = indexer_lang

            if ep_obj.show.dvdorder != 0:
                lINDEXER_API_PARMS['dvdorder'] = True

            t = sickbeard.indexerApi(
                ep_obj.show.indexer).indexer(**lINDEXER_API_PARMS)

            myShow = t[ep_obj.show.indexerid]
        except sickbeard.indexer_shownotfound, e:
            raise exceptions.ShowNotFoundException(e.message)
        except sickbeard.indexer_error, e:
            logger.log(
                u"Unable to connect to " +
                sickbeard.indexerApi(ep_obj.show.indexer).name +
                " while creating meta files - skipping - " + ex(e),
                logger.ERROR)
            return False
Exemplo n.º 47
0
def retrieve_exceptions():  # pylint:disable=too-many-locals, too-many-branches
    """
    Looks up the exceptions on github, parses them into a dict, and inserts them into the
    scene_exceptions table in cache.db. Also clears the scene name cache.
    """

    do_refresh = False
    for indexer in sickbeard.indexerApi().indexers:
        if shouldRefresh(sickbeard.indexerApi(indexer).name):
            do_refresh = True

    if do_refresh:
        loc = sickbeard.indexerApi(INDEXER_TVDB).config['scene_loc']
        logger.log("Checking for scene exception updates from {0}".format(loc))

        session = sickbeard.indexerApi(INDEXER_TVDB).session
        proxy = sickbeard.PROXY_SETTING
        if proxy and sickbeard.PROXY_INDEXERS:
            session.proxies = {
                "http": proxy,
                "https": proxy,
            }

        try:
            jdata = helpers.getURL(loc, session=session, returns='json')
        except Exception:
            jdata = None

        if not jdata:
            # When jdata is None, trouble connecting to github, or reading file failed
            logger.log(
                "Check scene exceptions update failed. Unable to update from {0}"
                .format(loc), logger.DEBUG)
        else:
            for indexer in sickbeard.indexerApi().indexers:
                try:
                    setLastRefresh(sickbeard.indexerApi(indexer).name)
                    for indexer_id in jdata[sickbeard.indexerApi(
                            indexer).config['xem_origin']]:
                        alias_list = [
                            {
                                scene_exception: int(scene_season)
                            } for scene_season in jdata[sickbeard.indexerApi(
                                indexer).config['xem_origin']][indexer_id]
                            for scene_exception in jdata[sickbeard.indexerApi(
                                indexer).config['xem_origin']][indexer_id]
                            [scene_season]
                        ]
                        exception_dict[indexer_id] = alias_list
                except Exception:
                    continue

    # XEM scene exceptions
    _xem_exceptions_fetcher()
    for xem_ex in xem_exception_dict:
        if xem_ex in exception_dict:
            exception_dict[xem_ex] += exception_dict[xem_ex]
        else:
            exception_dict[xem_ex] = xem_exception_dict[xem_ex]

    # AniDB scene exceptions
    _anidb_exceptions_fetcher()
    for anidb_ex in anidb_exception_dict:
        if anidb_ex in exception_dict:
            exception_dict[anidb_ex] += anidb_exception_dict[anidb_ex]
        else:
            exception_dict[anidb_ex] = anidb_exception_dict[anidb_ex]

    queries = []
    cache_db_con = db.DBConnection('cache.db')
    for cur_indexer_id in exception_dict:
        sql_ex = cache_db_con.select(
            "SELECT show_name FROM scene_exceptions WHERE indexer_id = ?;",
            [cur_indexer_id])
        existing_exceptions = [x[b"show_name"] for x in sql_ex]
        if cur_indexer_id not in exception_dict:
            continue

        for cur_exception_dict in exception_dict[cur_indexer_id]:
            for ex in six.iteritems(cur_exception_dict):
                cur_exception, curSeason = ex
                if cur_exception not in existing_exceptions:
                    queries.append([
                        "INSERT OR IGNORE INTO scene_exceptions (indexer_id, show_name, season) VALUES (?,?,?);",
                        [cur_indexer_id, cur_exception, curSeason]
                    ])
    if queries:
        cache_db_con.mass_action(queries)
        logger.log("Updated scene exceptions", logger.DEBUG)

    # cleanup
    exception_dict.clear()
    anidb_exception_dict.clear()
    xem_exception_dict.clear()
Exemplo n.º 48
0
    def run(self):

        ShowQueueItem.run(self)

        if not sickbeard.indexerApi(self.show.indexer).config['active']:
            logger.log(
                'Indexer %s is marked inactive, aborting update for show %s and continue with refresh.'
                % (sickbeard.indexerApi(
                    self.show.indexer).config['name'], self.show.name))
            sickbeard.showQueueScheduler.action.refreshShow(
                self.show,
                self.force,
                self.scheduled_update,
                after_update=True)
            return

        logger.log('Beginning update of %s' % self.show.name)

        logger.log(
            'Retrieving show info from %s' %
            sickbeard.indexerApi(self.show.indexer).name, logger.DEBUG)
        try:
            result = self.show.loadFromIndexer(cache=not self.force)
            if None is not result:
                return
        except sickbeard.indexer_error as e:
            logger.log(
                'Unable to contact %s, aborting: %s' %
                (sickbeard.indexerApi(self.show.indexer).name, ex(e)),
                logger.WARNING)
            return
        except sickbeard.indexer_attributenotfound as e:
            logger.log(
                'Data retrieved from %s was incomplete, aborting: %s' %
                (sickbeard.indexerApi(self.show.indexer).name, ex(e)),
                logger.ERROR)
            return

        if self.force_web:
            self.show.load_imdb_info()

        try:
            self.show.saveToDB()
        except Exception as e:
            logger.log('Error saving the show to the database: %s' % ex(e),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.ERROR)

        # get episode list from DB
        logger.log('Loading all episodes from the database', logger.DEBUG)
        DBEpList = self.show.loadEpisodesFromDB(update=True)

        # get episode list from TVDB
        logger.log(
            'Loading all episodes from %s' %
            sickbeard.indexerApi(self.show.indexer).name, logger.DEBUG)
        try:
            IndexerEpList = self.show.loadEpisodesFromIndexer(
                cache=not self.force, update=True)
        except sickbeard.indexer_exception as e:
            logger.log(
                'Unable to get info from %s, the show info will not be refreshed: %s'
                % (sickbeard.indexerApi(self.show.indexer).name, ex(e)),
                logger.ERROR)
            IndexerEpList = None

        if None is IndexerEpList:
            logger.log(
                'No data returned from %s, unable to update episodes for show: %s'
                %
                (sickbeard.indexerApi(self.show.indexer).name, self.show.name),
                logger.ERROR)
        elif not IndexerEpList or 0 == len(IndexerEpList):
            logger.log(
                'No episodes returned from %s for show: %s' %
                (sickbeard.indexerApi(self.show.indexer).name, self.show.name),
                logger.WARNING)
        else:
            # for each ep we found on TVDB delete it from the DB list
            for curSeason in IndexerEpList:
                for curEpisode in IndexerEpList[curSeason]:
                    logger.log(
                        'Removing %sx%s from the DB list' %
                        (curSeason, curEpisode), logger.DEBUG)
                    if curSeason in DBEpList and curEpisode in DBEpList[
                            curSeason]:
                        del DBEpList[curSeason][curEpisode]

            # for the remaining episodes in the DB list just delete them from the DB
            for curSeason in DBEpList:
                for curEpisode in DBEpList[curSeason]:
                    curEp = self.show.getEpisode(curSeason, curEpisode)
                    status = sickbeard.common.Quality.splitCompositeStatus(
                        curEp.status)[0]
                    if should_delete_episode(status):
                        logger.log(
                            'Permanently deleting episode %sx%s from the database'
                            % (curSeason, curEpisode), logger.MESSAGE)
                        try:
                            curEp.deleteEpisode()
                        except exceptions.EpisodeDeletedException:
                            pass
                    else:
                        logger.log(
                            'Not deleting episode %sx%s from the database because status is: %s'
                            % (curSeason, curEpisode, statusStrings[status]),
                            logger.MESSAGE)

        if self.priority != generic_queue.QueuePriorities.NORMAL:
            self.kwargs['priority'] = self.priority
        sickbeard.showQueueScheduler.action.refreshShow(
            self.show,
            self.force,
            self.scheduled_update,
            after_update=True,
            force_image_cache=self.force_web,
            **self.kwargs)
Exemplo n.º 49
0
class QueueItemAdd(ShowQueueItem):
    def __init__(self, indexer, indexer_id, showDir, default_status, quality, flatten_folders, lang, subtitles, anime, scene):

        self.indexer = indexer
        self.indexer_id = indexer_id
        self.showDir = showDir
        self.default_status = default_status
        self.quality = quality
        self.flatten_folders = flatten_folders
        self.lang = lang
        self.subtitles = subtitles
        self.anime = anime
        self.scene = scene

        self.show = None

        # this will initialize self.show to None
        ShowQueueItem.__init__(self, ShowQueueActions.ADD, self.show)

    def _getName(self):
        """
        Returns the show name if there is a show object created, if not returns
        the dir that the show is being added to.
        """
        if self.show == None:
            return self.showDir
        return self.show.name

    show_name = property(_getName)

    def _isLoading(self):
        """
        Returns True if we've gotten far enough to have a show object, or False
        if we still only know the folder name.
        """
        if self.show == None:
            return True
        return False

    isLoading = property(_isLoading)

    def execute(self):

        ShowQueueItem.execute(self)

        logger.log(u"Starting to add show " + self.showDir)
        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy()
            if self.lang:
                lINDEXER_API_PARMS['language'] = self.lang

            logger.log(u"" + str(sickbeard.indexerApi(self.indexer).name) + ": " + repr(lINDEXER_API_PARMS))

            t = sickbeard.indexerApi(self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id]

            # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that has no proper english version of the show
            if getattr(s, 'seriesname', None) is None:
                logger.log(u"Show in " + self.showDir + " has no name on " + str(sickbeard.indexerApi(self.indexer).name) + ", probably the wrong language used to search with.", logger.ERROR)
                ui.notifications.error("Unable to add show",
                                       "Show in " + self.showDir + " has no name on " + str(sickbeard.indexerApi(
                                           self.indexer).name) + ", probably the wrong language. Delete .nfo and add manually in the correct language.")
                self._finishEarly()
                return
            # if the show has no episodes/seasons
            if not s:
                logger.log(u"Show " + str(s['seriesname']) + " is on " + str(sickbeard.indexerApi(self.indexer).name) + " but contains no season/episode data.", logger.ERROR)
                ui.notifications.error("Unable to add show",
                                       "Show " + str(s['seriesname']) + " is on " + str(sickbeard.indexerApi(
                                           self.indexer).name) + " but contains no season/episode data.")
                self._finishEarly()
                return
        except Exception, e:
            logger.log(u"Unable to find show ID:" + str(self.indexer_id) + " on Indexer: " + str(sickbeard.indexerApi(self.indexer).name), logger.ERROR)
            ui.notifications.error("Unable to add show",
                                   "Unable to look up the show in " + self.showDir + " on " + str(sickbeard.indexerApi(
                                       self.indexer).name) + " using ID " + str(
                                       self.indexer_id) + ", not using the NFO. Delete .nfo and try adding manually again.")
            self._finishEarly()
            return

        try:
            # clear the name cache
            name_cache.clearCache()

            newShow = TVShow(self.indexer, self.indexer_id, self.lang)
            newShow.loadFromIndexer()

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles if self.subtitles != None else sickbeard.SUBTITLES_DEFAULT
            self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
            self.show.flatten_folders = self.flatten_folders if self.flatten_folders != None else sickbeard.FLATTEN_FOLDERS_DEFAULT
            self.show.anime = self.anime if self.anime != None else sickbeard.ANIME_DEFAULT
            self.show.scene = self.scene if self.scene != None else sickbeard.SCENE_DEFAULT
            self.show.paused = False

            # be smartish about this
            if self.show.genre and "talk show" in self.show.genre.lower():
                self.show.air_by_date = 1
            if self.show.genre and "documentary" in self.show.genre.lower():
                self.show.air_by_date = 0
            if self.show.classification and "sports" in self.show.classification.lower():
                self.show.sports = 1

        except sickbeard.indexer_exception, e:
            logger.log(
                u"Unable to add show due to an error with " + sickbeard.indexerApi(self.indexer).name + ": " + ex(e),
                logger.ERROR)
            if self.show:
                ui.notifications.error(
                    "Unable to add " + str(self.show.name) + " due to an error with " + sickbeard.indexerApi(
                        self.indexer).name + "")
            else:
                ui.notifications.error(
                    "Unable to add show due to an error with " + sickbeard.indexerApi(self.indexer).name + "")
            self._finishEarly()
            return
Exemplo n.º 50
0
    def run(self):

        ShowQueueItem.run(self)

        logger.log(u"Starting to add show {0}".format("by ShowDir: {0}".format(self.showDir) if self.showDir else "by Indexer Id: {0}".format(self.indexer_id)))
        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy()
            if self.lang:
                lINDEXER_API_PARMS['language'] = self.lang

            logger.log(u"" + str(sickbeard.indexerApi(self.indexer).name) + ": " + repr(lINDEXER_API_PARMS))

            t = sickbeard.indexerApi(self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id]

            # Let's try to create the show Dir if it's not provided. This way we force the show dir to build build using the
            # Indexers provided series name
            if not self.showDir and self.root_dir:
                show_name = get_showname_from_indexer(self.indexer, self.indexer_id, self.lang)
                if show_name:
                    self.showDir = ek(os.path.join, self.root_dir, sanitize_filename(show_name))
                    dir_exists = makeDir(self.showDir)
                    if not dir_exists:
                        logger.log(u"Unable to create the folder {0}, can't add the show".format(self.showDir))
                        return

                    chmodAsParent(self.showDir)
                else:
                    logger.log(u"Unable to get a show {0}, can't add the show".format(self.showDir))
                    return

            # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that has no proper english version of the show
            if getattr(s, 'seriesname', None) is None:
                logger.log(u"Show in {} has no name on {}, probably searched with the wrong language.".format
                           (self.showDir, sickbeard.indexerApi(self.indexer).name), logger.ERROR)

                ui.notifications.error("Unable to add show",
                                       "Show in " + self.showDir + " has no name on " + str(sickbeard.indexerApi(
                                           self.indexer).name) + ", probably the wrong language. Delete .nfo and add manually in the correct language.")
                self._finishEarly()
                return
            # if the show has no episodes/seasons
            if not s:
                logger.log(u"Show " + str(s['seriesname']) + " is on " + str(
                    sickbeard.indexerApi(self.indexer).name) + " but contains no season/episode data.")
                ui.notifications.error("Unable to add show",
                                       "Show " + str(s['seriesname']) + " is on " + str(sickbeard.indexerApi(
                                           self.indexer).name) + " but contains no season/episode data.")
                self._finishEarly()
                return
        except Exception as e:
            logger.log(u"%s Error while loading information from indexer %s. Error: %r" % (self.indexer_id, sickbeard.indexerApi(self.indexer).name, ex(e)), logger.ERROR)
            # logger.log(u"Show name with ID %s doesn't exist on %s anymore. If you are using trakt, it will be removed from your TRAKT watchlist. If you are adding manually, try removing the nfo and adding again" %
            #            (self.indexer_id, sickbeard.indexerApi(self.indexer).name), logger.WARNING)

            ui.notifications.error(
                "Unable to add show",
                "Unable to look up the show in %s on %s using ID %s, not using the NFO. Delete .nfo and try adding manually again." %
                (self.showDir, sickbeard.indexerApi(self.indexer).name, self.indexer_id)
            )

            if sickbeard.USE_TRAKT:

                trakt_id = sickbeard.indexerApi(self.indexer).config['trakt_id']
                trakt_api = TraktAPI(sickbeard.SSL_VERIFY, sickbeard.TRAKT_TIMEOUT)

                title = self.showDir.split("/")[-1]
                data = {
                    'shows': [
                        {
                            'title': title,
                            'ids': {}
                        }
                    ]
                }
                if trakt_id == 'tvdb_id':
                    data['shows'][0]['ids']['tvdb'] = self.indexer_id
                else:
                    data['shows'][0]['ids']['tvrage'] = self.indexer_id

                trakt_api.traktRequest("sync/watchlist/remove", data, method='POST')

            self._finishEarly()
            return

        try:
            newShow = TVShow(self.indexer, self.indexer_id, self.lang)
            newShow.loadFromIndexer()

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles if self.subtitles is not None else sickbeard.SUBTITLES_DEFAULT
            self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
            self.show.flatten_folders = self.flatten_folders if self.flatten_folders is not None else sickbeard.FLATTEN_FOLDERS_DEFAULT
            self.show.anime = self.anime if self.anime is not None else sickbeard.ANIME_DEFAULT
            self.show.scene = self.scene if self.scene is not None else sickbeard.SCENE_DEFAULT
            self.show.paused = self.paused if self.paused is not None else False
            self.show.frenchsearch = 0

            # set up default new/missing episode status
            logger.log(u"Setting all episodes to the specified default status: " + str(self.show.default_ep_status))
            self.show.default_ep_status = self.default_status

            if self.show.anime:
                self.show.release_groups = BlackAndWhiteList(self.show.indexerid)
                if self.blacklist:
                    self.show.release_groups.set_black_keywords(self.blacklist)
                if self.whitelist:
                    self.show.release_groups.set_white_keywords(self.whitelist)

            # # be smartish about this
            # if self.show.genre and "talk show" in self.show.genre.lower():
            #     self.show.air_by_date = 1
            # if self.show.genre and "documentary" in self.show.genre.lower():
            #     self.show.air_by_date = 0
            # if self.show.classification and "sports" in self.show.classification.lower():
            #     self.show.sports = 1

        except sickbeard.indexer_exception as e:
            logger.log(
                u"Unable to add show due to an error with " + sickbeard.indexerApi(self.indexer).name + ": " + ex(e),
                logger.ERROR)
            if self.show:
                ui.notifications.error(
                    "Unable to add " + str(self.show.name) + " due to an error with " + sickbeard.indexerApi(
                        self.indexer).name + "")
            else:
                ui.notifications.error(
                    "Unable to add show due to an error with " + sickbeard.indexerApi(self.indexer).name + "")
            self._finishEarly()
            return

        except MultipleShowObjectsException:
            logger.log(u"The show in " + self.showDir + " is already in your show list, skipping", logger.WARNING)
            ui.notifications.error('Show skipped', "The show in " + self.showDir + " is already in your show list")
            self._finishEarly()
            return

        except Exception as e:
            logger.log(u"Error trying to add show: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finishEarly()
            raise

        logger.log(u"Retrieving show info from IMDb", logger.DEBUG)
        try:
            self.show.loadIMDbInfo()
        except imdb_exceptions.IMDbError as e:
            logger.log(u" Something wrong on IMDb api: " + ex(e), logger.WARNING)
        except Exception as e:
            logger.log(u"Error loading IMDb info: " + ex(e), logger.ERROR)

        try:
            self.show.saveToDB()
        except Exception as e:
            logger.log(u"Error saving the show to the database: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finishEarly()
            raise

        # add it to the show list
        sickbeard.showList.append(self.show)

        try:
            self.show.loadEpisodesFromIndexer()
        except Exception as e:
            logger.log(
                u"Error with " + sickbeard.indexerApi(self.show.indexer).name + ", not creating episode list: " + ex(e),
                logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # update internal name cache
        name_cache.buildNameCache(self.show)

        try:
            self.show.loadEpisodesFromDir()
        except Exception as e:
            logger.log(u"Error searching dir for episodes: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # if they set default ep status to WANTED then run the backlog to search for episodes
        # FIXME: This needs to be a backlog queue item!!!
        if self.show.default_ep_status == WANTED:
            logger.log(u"Launching backlog for this show since its episodes are WANTED")
            sickbeard.backlogSearchScheduler.action.searchBacklog([self.show])

        self.show.writeMetadata()
        self.show.updateMetadata()
        self.show.populateCache()

        self.show.flushEpisodes()

        if sickbeard.USE_TRAKT:
            # if there are specific episodes that need to be added by trakt
            sickbeard.traktCheckerScheduler.action.manageNewShow(self.show)

            # add show to trakt.tv library
            if sickbeard.TRAKT_SYNC:
                sickbeard.traktCheckerScheduler.action.addShowToTraktLibrary(self.show)

            if sickbeard.TRAKT_SYNC_WATCHLIST:
                logger.log(u"update watchlist")
                notifiers.trakt_notifier.update_watchlist(show_obj=self.show)

        # Load XEM data to DB for show
        sickbeard.scene_numbering.xem_refresh(self.show.indexerid, self.show.indexer, force=True)

        # check if show has XEM mapping so we can determin if searches should go by scene numbering or indexer numbering.
        if not self.scene and sickbeard.scene_numbering.get_xem_numbering_for_show(self.show.indexerid,
                                                                                   self.show.indexer):
            self.show.scene = 1

        # After initial add, set to default_status_after.
        self.show.default_ep_status = self.default_status_after

        self.finish()
Exemplo n.º 51
0
def mapIndexersToShow(showObj):
    mapped = {}

    # init mapped indexers object
    for indexer in sickbeard.indexerApi().indexers:
        mapped[indexer] = showObj.indexerid if int(indexer) == int(
            showObj.indexer) else 0

    myDB = db.DBConnection()
    sqlResults = myDB.select(
        "SELECT * FROM indexer_mapping WHERE indexer_id = ? AND indexer = ?",
        [showObj.indexerid, showObj.indexer])

    # for each mapped entry
    for curResult in sqlResults:
        nlist = [i for i in curResult if i is not None]
        # Check if its mapped with both tvdb and tvrage.
        if len(nlist) >= 4:
            logger.log(
                u"Found indexer mapping in cache for show: " + showObj.name,
                logger.DEBUG)
            mapped[int(curResult['mindexer'])] = int(curResult['mindexer_id'])
            return mapped
    else:
        sql_l = []
        for indexer in sickbeard.indexerApi().indexers:
            if indexer == showObj.indexer:
                mapped[indexer] = showObj.indexerid
                continue

            lINDEXER_API_PARMS = sickbeard.indexerApi(
                indexer).api_params.copy()
            lINDEXER_API_PARMS['custom_ui'] = classes.ShowListUI
            t = sickbeard.indexerApi(indexer).indexer(**lINDEXER_API_PARMS)

            try:
                mapped_show = t[showObj.name]
            except Exception:
                logger.log(
                    u"Unable to map " +
                    sickbeard.indexerApi(showObj.indexer).name + "->" +
                    sickbeard.indexerApi(indexer).name + " for show: " +
                    showObj.name + ", skipping it", logger.DEBUG)
                continue

            if mapped_show and len(mapped_show) == 1:
                logger.log(
                    u"Mapping " + sickbeard.indexerApi(showObj.indexer).name +
                    "->" + sickbeard.indexerApi(indexer).name + " for show: " +
                    showObj.name, logger.DEBUG)

                mapped[indexer] = int(mapped_show[0]['id'])

                logger.log(
                    u"Adding indexer mapping to DB for show: " + showObj.name,
                    logger.DEBUG)

                sql_l.append([
                    "INSERT OR IGNORE INTO indexer_mapping (indexer_id, indexer, mindexer_id, mindexer) VALUES (?,?,?,?)",
                    [
                        showObj.indexerid, showObj.indexer,
                        int(mapped_show[0]['id']), indexer
                    ]
                ])

        if len(sql_l) > 0:
            myDB = db.DBConnection()
            myDB.mass_action(sql_l)

    return mapped
Exemplo n.º 52
0
    def run(self):

        ShowQueueItem.run(self)

        logger.log('Starting to add show %s' % self.showDir)
        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = sickbeard.indexerApi(
                self.indexer).api_params.copy()
            if self.lang:
                lINDEXER_API_PARMS['language'] = self.lang

            logger.log(u'' + str(sickbeard.indexerApi(self.indexer).name) +
                       ': ' + repr(lINDEXER_API_PARMS))

            t = sickbeard.indexerApi(
                self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id, False]

            if getattr(t, 'show_not_found', False):
                logger.log(
                    'Show %s was not found on %s, maybe show was deleted' %
                    (self.show_name, sickbeard.indexerApi(self.indexer).name),
                    logger.ERROR)
                self._finishEarly()
                return

            # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that has no proper english version of the show
            if getattr(s, 'seriesname', None) is None:
                logger.log(
                    'Show in %s has no name on %s, probably the wrong language used to search with.'
                    % (self.showDir, sickbeard.indexerApi(self.indexer).name),
                    logger.ERROR)
                ui.notifications.error(
                    'Unable to add show',
                    'Show in %s has no name on %s, probably the wrong language. Delete .nfo and add manually in the correct language.'
                    % (self.showDir, sickbeard.indexerApi(self.indexer).name))
                self._finishEarly()
                return
        except Exception as e:
            logger.log(
                'Unable to find show ID:%s on Indexer: %s' %
                (self.indexer_id, sickbeard.indexerApi(self.indexer).name),
                logger.ERROR)
            ui.notifications.error(
                'Unable to add show',
                'Unable to look up the show in %s on %s using ID %s, not using the NFO. Delete .nfo and try adding manually again.'
                % (self.showDir, sickbeard.indexerApi(
                    self.indexer).name, self.indexer_id))
            self._finishEarly()
            return

        try:
            newShow = TVShow(self.indexer, self.indexer_id, self.lang)
            newShow.loadFromIndexer()

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles if None is not self.subtitles else sickbeard.SUBTITLES_DEFAULT
            self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
            self.show.upgrade_once = self.upgrade_once
            self.show.flatten_folders = self.flatten_folders if None is not self.flatten_folders else sickbeard.FLATTEN_FOLDERS_DEFAULT
            self.show.anime = self.anime if None is not self.anime else sickbeard.ANIME_DEFAULT
            self.show.scene = self.scene if None is not self.scene else sickbeard.SCENE_DEFAULT
            self.show.paused = self.paused if None is not self.paused else False
            self.show.prune = self.prune if None is not self.prune else 0
            self.show.tag = self.tag if None is not self.tag else 'Show List'

            if self.show.anime:
                self.show.release_groups = BlackAndWhiteList(
                    self.show.indexerid)
                if self.blacklist:
                    self.show.release_groups.set_black_keywords(self.blacklist)
                if self.whitelist:
                    self.show.release_groups.set_white_keywords(self.whitelist)

            # be smartish about this
            if self.show.genre and 'talk show' in self.show.genre.lower():
                self.show.air_by_date = 1
            if self.show.genre and 'documentary' in self.show.genre.lower():
                self.show.air_by_date = 0
            if self.show.classification and 'sports' in self.show.classification.lower(
            ):
                self.show.sports = 1

        except sickbeard.indexer_exception as e:
            logger.log(
                'Unable to add show due to an error with %s: %s' %
                (sickbeard.indexerApi(self.indexer).name, ex(e)), logger.ERROR)
            if self.show:
                ui.notifications.error(
                    'Unable to add %s due to an error with %s' %
                    (self.show.name, sickbeard.indexerApi(self.indexer).name))
            else:
                ui.notifications.error(
                    'Unable to add show due to an error with %s' %
                    sickbeard.indexerApi(self.indexer).name)
            self._finishEarly()
            return

        except exceptions.MultipleShowObjectsException:
            logger.log(
                'The show in %s is already in your show list, skipping' %
                self.showDir, logger.ERROR)
            ui.notifications.error(
                'Show skipped',
                'The show in %s is already in your show list' % self.showDir)
            self._finishEarly()
            return

        except Exception as e:
            logger.log('Error trying to add show: %s' % ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.ERROR)
            self._finishEarly()
            raise

        self.show.load_imdb_info()

        try:
            self.show.saveToDB()
        except Exception as e:
            logger.log('Error saving the show to the database: %s' % ex(e),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.ERROR)
            self._finishEarly()
            raise

        # add it to the show list
        sickbeard.showList.append(self.show)

        try:
            self.show.loadEpisodesFromIndexer()
        except Exception as e:
            logger.log(
                'Error with %s, not creating episode list: %s' %
                (sickbeard.indexerApi(self.show.indexer).name, ex(e)),
                logger.ERROR)
            logger.log(traceback.format_exc(), logger.ERROR)

        try:
            self.show.loadEpisodesFromDir()
        except Exception as e:
            logger.log('Error searching directory for episodes: %s' % ex(e),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.ERROR)

        # if they gave a custom status then change all the eps to it
        my_db = db.DBConnection()
        if self.default_status != SKIPPED:
            logger.log(
                'Setting all episodes to the specified default status: %s' %
                sickbeard.common.statusStrings[self.default_status])
            my_db.action(
                'UPDATE tv_episodes SET status = ? WHERE status = ? AND showid = ? AND season != 0',
                [self.default_status, SKIPPED, self.show.indexerid])

        # if they gave a number to start or number to end as wanted, then change those eps to it
        def get_wanted(db_obj, wanted_max, latest):
            actual = 0
            if wanted_max:
                select_id = 'FROM [tv_episodes] t5 JOIN (SELECT t3.indexerid, t3.status, t3.season*1000000+t3.episode AS t3_se, t2.start_season FROM [tv_episodes] t3'\
                            + ' JOIN (SELECT t1.showid, M%s(t1.season) AS start_season' % ('IN', 'AX')[latest]\
                            + ', MAX(t1.airdate) AS airdate, t1.episode, t1.season*1000000+t1.episode AS se FROM [tv_episodes] t1'\
                            + ' WHERE %s=t1.showid' % self.show.indexerid\
                            + ' AND 0<t1.season AND t1.status NOT IN (%s)) AS t2' % UNAIRED\
                            + ' ON t2.showid=t3.showid AND 0<t3.season AND t2.se>=t3_se ORDER BY t3_se %sSC' % ('A', 'DE')[latest]\
                            + ' %s) as t4' % (' LIMIT %s' % wanted_max, '')[-1 == wanted_max]\
                            + ' ON t4.indexerid=t5.indexerid'\
                            + '%s' % ('', ' AND t4.start_season=t5.season')[-1 == wanted_max]\
                            + ' AND t4.status NOT IN (%s)' % ','.join([str(x) for x in sickbeard.common.Quality.DOWNLOADED + [WANTED]])
                select = 'SELECT t5.indexerid as indexerid, t5.season as season, t5.episode as episode, t5.status as status ' + select_id
                update = 'UPDATE [tv_episodes] SET status=%s WHERE indexerid IN (SELECT t5.indexerid %s)' % (
                    WANTED, select_id)

                wanted_updates = db_obj.select(select)
                db_obj.action(update)
                result = db_obj.select(
                    'SELECT changes() as last FROM [tv_episodes]')
                for cur_result in result:
                    actual = cur_result['last']
                    break

                action_log = 'didn\'t find any episodes that need to be set wanted'
                if actual:
                    action_log = ('updated %s %s episodes > %s' % (
                        (((('%s of %s' % (actual, wanted_max)),
                           ('%s of max %s limited' %
                            (actual, wanted_max)))[10 == wanted_max]),
                         ('max %s available' % actual))[-1 == wanted_max],
                        ('first season', 'latest')[latest], ','.join(
                            [('S%02dE%02d=%d' %
                              (a['season'], a['episode'], a['status']))
                             for a in wanted_updates])))
                logger.log('Get wanted ' + action_log)
            return actual

        items_wanted = get_wanted(my_db,
                                  self.default_wanted_begin,
                                  latest=False)
        items_wanted += get_wanted(my_db,
                                   self.default_wanted_latest,
                                   latest=True)

        self.show.writeMetadata()
        self.show.updateMetadata()
        self.show.populateCache()

        self.show.flushEpisodes()

        # load ids
        self.show.ids

        # if sickbeard.USE_TRAKT:
        #     # if there are specific episodes that need to be added by trakt
        #     sickbeard.traktCheckerScheduler.action.manageNewShow(self.show)
        #
        #     # add show to trakt.tv library
        #     if sickbeard.TRAKT_SYNC:
        #         sickbeard.traktCheckerScheduler.action.addShowToTraktLibrary(self.show)

        # Load XEM data to DB for show
        sickbeard.scene_numbering.xem_refresh(self.show.indexerid,
                                              self.show.indexer,
                                              force=True)
        if self.show.scene:
            # enable/disable scene flag based on if show has an explicit _scene_ mapping at XEM
            self.show.scene = sickbeard.scene_numbering.has_xem_scene_mapping(
                self.show.indexerid, self.show.indexer)
        # if "scene" numbering is disabled during add show, output availability to log
        if None is not self.scene and not self.show.scene and \
                self.show.indexerid in sickbeard.scene_exceptions.xem_ids_list[self.show.indexer]:
            logger.log(
                'No scene number mappings found at TheXEM. Therefore, episode scene numbering disabled, '
                'edit show and enable it to manually add custom numbers for search and media processing.'
            )
        try:
            self.show.saveToDB()
        except Exception as e:
            logger.log('Error saving the show to the database: %s' % ex(e),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.ERROR)
            self._finishEarly()
            raise

        # update internal name cache
        name_cache.buildNameCache(self.show)

        self.show.loadEpisodesFromDB()

        msg = ' the specified show into ' + self.showDir
        # if started with WANTED eps then run the backlog
        if WANTED == self.default_status or items_wanted:
            logger.log(
                'Launching backlog for this show since episodes are WANTED')
            sickbeard.backlogSearchScheduler.action.search_backlog(
                [self.show])  #@UndefinedVariable
            ui.notifications.message(
                'Show added/search',
                'Adding and searching for episodes of' + msg)
        else:
            ui.notifications.message('Show added', 'Adding' + msg)

        self.finish()
Exemplo n.º 53
0
    def _ep_data(self, ep_obj):
        """
        Creates an elementTree XML structure for a MediaBrowser style episode.xml
        and returns the resulting data object.

        show_obj: a TVShow instance to create the NFO for
        """

        eps_to_write = [ep_obj] + ep_obj.relatedEps

        indexer_lang = ep_obj.show.lang

        try:
            # There's gotta be a better way of doing this but we don't wanna
            # change the language value elsewhere
            lINDEXER_API_PARMS = sickbeard.indexerApi(
                ep_obj.show.indexer).api_params.copy()

            if indexer_lang and not indexer_lang == 'en':
                lINDEXER_API_PARMS['language'] = indexer_lang

            if ep_obj.show.dvdorder != 0:
                lINDEXER_API_PARMS['dvdorder'] = True

            t = sickbeard.indexerApi(
                ep_obj.show.indexer).indexer(**lINDEXER_API_PARMS)
            myShow = t[ep_obj.show.indexerid]
        except sickbeard.indexer_shownotfound as e:
            raise exceptions.ShowNotFoundException(e.message)
        except sickbeard.indexer_error as e:
            logger.log(
                u"Unable to connect to TVDB while creating meta files - skipping - "
                + ex(e), logger.ERROR)
            return False

        if not self._valid_show(myShow, ep_obj.show):
            return

        rootNode = etree.Element("details")
        movie = etree.SubElement(rootNode, "movie")

        movie.attrib["isExtra"] = "false"
        movie.attrib["isSet"] = "false"
        movie.attrib["isTV"] = "true"

        # write an MediaBrowser XML containing info for all matching episodes
        for curEpToWrite in eps_to_write:

            try:
                myEp = myShow[curEpToWrite.season][curEpToWrite.episode]
            except (StandardError, Exception):
                logger.log(
                    u"Unable to find episode " + str(curEpToWrite.season) +
                    "x" + str(curEpToWrite.episode) +
                    " on tvdb... has it been removed? Should I delete from db?"
                )
                return None

            if curEpToWrite == ep_obj:
                # root (or single) episode

                # default to today's date for specials if firstaired is not set
                if myEp['firstaired'] == None and ep_obj.season == 0:
                    myEp['firstaired'] = str(datetime.date.fromordinal(1))

                if myEp['episodename'] == None or myEp['firstaired'] == None:
                    return None

                episode = movie

                EpisodeName = etree.SubElement(episode, "title")
                if curEpToWrite.name != None:
                    EpisodeName.text = curEpToWrite.name
                else:
                    EpisodeName.text = ""

                SeasonNumber = etree.SubElement(episode, "season")
                SeasonNumber.text = str(curEpToWrite.season)

                EpisodeNumber = etree.SubElement(episode, "episode")
                EpisodeNumber.text = str(ep_obj.episode)

                year = etree.SubElement(episode, "year")
                if myShow["firstaired"] != None:
                    try:
                        year_text = str(
                            datetime.datetime.strptime(myShow["firstaired"],
                                                       '%Y-%m-%d').year)
                        if year_text:
                            year.text = year_text
                    except:
                        pass

                plot = etree.SubElement(episode, "plot")
                if myShow["overview"] != None:
                    plot.text = myShow["overview"]

                Overview = etree.SubElement(episode, "episodeplot")
                if curEpToWrite.description != None:
                    Overview.text = curEpToWrite.description
                else:
                    Overview.text = ""

                mpaa = etree.SubElement(episode, "mpaa")
                if myShow["contentrating"] != None:
                    mpaa.text = myShow["contentrating"]

                if not ep_obj.relatedEps:
                    if myEp["rating"] != None:
                        try:
                            rating = int((float(myEp['rating']) * 10))
                        except ValueError:
                            rating = 0
                        Rating = etree.SubElement(episode, "rating")
                        rating_text = str(rating)
                        if rating_text != None:
                            Rating.text = rating_text

                director = etree.SubElement(episode, "director")
                director_text = myEp['director']
                if director_text != None:
                    director.text = director_text

                credits = etree.SubElement(episode, "credits")
                credits_text = myEp['writer']
                if credits_text != None:
                    credits.text = credits_text

                cast = etree.SubElement(episode, "cast")
                self.add_actor_element(myShow, etree, cast)

            else:
                # append data from (if any) related episodes

                if curEpToWrite.name:
                    if not EpisodeName.text:
                        EpisodeName.text = curEpToWrite.name
                    else:
                        EpisodeName.text = EpisodeName.text + ", " + curEpToWrite.name

                if curEpToWrite.description:
                    if not Overview.text:
                        Overview.text = curEpToWrite.description
                    else:
                        Overview.text = Overview.text + "\r" + curEpToWrite.description

        helpers.indentXML(rootNode)
        data = etree.ElementTree(rootNode)

        return data
Exemplo n.º 54
0
        try:
            self.show.saveToDB()
        except Exception, e:
            logger.log(u"Error saving the show to the database: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finishEarly()
            raise

        # add it to the show list
        sickbeard.showList.append(self.show)

        try:
            self.show.loadEpisodesFromIndexer()
        except Exception, e:
            logger.log(
                u"Error with " + sickbeard.indexerApi(self.show.indexer).name + ", not creating episode list: " + ex(e),
                logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # before we parse local files lets update exceptions
        sickbeard.scene_exceptions.retrieve_exceptions()

        try:
            self.show.loadEpisodesFromDir()
        except Exception, e:
            logger.log(u"Error searching dir for episodes: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # if they gave a custom status then change all the eps to it
        if self.default_status != SKIPPED:
            logger.log(u"Setting all episodes to the specified default status: " + str(self.default_status))
Exemplo n.º 55
0
    def _show_data(self, show_obj):
        """
        Creates an elementTree XML structure for a MediaBrowser-style series.xml
        returns the resulting data object.

        show_obj: a TVShow instance to create the NFO for
        """

        indexer_lang = show_obj.lang
        lINDEXER_API_PARMS = sickbeard.indexerApi(
            show_obj.indexer).api_params.copy()

        lINDEXER_API_PARMS['actors'] = True

        if indexer_lang and not indexer_lang == 'en':
            lINDEXER_API_PARMS['language'] = indexer_lang

        if show_obj.dvdorder != 0:
            lINDEXER_API_PARMS['dvdorder'] = True

        t = sickbeard.indexerApi(
            show_obj.indexer).indexer(**lINDEXER_API_PARMS)

        rootNode = etree.Element("details")
        tv_node = etree.SubElement(rootNode, "movie")
        tv_node.attrib["isExtra"] = "false"
        tv_node.attrib["isSet"] = "false"
        tv_node.attrib["isTV"] = "true"

        try:
            myShow = t[int(show_obj.indexerid)]
        except sickbeard.indexer_shownotfound:
            logger.log(
                u"Unable to find show with id " + str(show_obj.indexerid) +
                " on tvdb, skipping it", logger.ERROR)
            raise

        except sickbeard.indexer_error:
            logger.log(u"TVDB is down, can't use its data to make the NFO",
                       logger.ERROR)
            raise

        if not self._valid_show(myShow, show_obj):
            return

        # check for title and id
        try:
            if myShow['seriesname'] == None or myShow[
                    'seriesname'] == "" or myShow['id'] == None or myShow[
                        'id'] == "":
                logger.log(
                    u"Incomplete info for show with id " +
                    str(show_obj.indexerid) + " on tvdb, skipping it",
                    logger.ERROR)
                return False
        except sickbeard.indexer_attributenotfound:
            logger.log(
                u"Incomplete info for show with id " +
                str(show_obj.indexerid) + " on tvdb, skipping it",
                logger.ERROR)
            return False

        SeriesName = etree.SubElement(tv_node, "title")
        if myShow['seriesname'] != None:
            SeriesName.text = myShow['seriesname']
        else:
            SeriesName.text = ""

        Genres = etree.SubElement(tv_node, "genres")
        if myShow["genre"] != None:
            for genre in myShow['genre'].split('|'):
                if genre and genre.strip():
                    cur_genre = etree.SubElement(Genres, "Genre")
                    cur_genre.text = genre.strip()

        FirstAired = etree.SubElement(tv_node, "premiered")
        if myShow['firstaired'] != None:
            FirstAired.text = myShow['firstaired']

        year = etree.SubElement(tv_node, "year")
        if myShow["firstaired"] != None:
            try:
                year_text = str(
                    datetime.datetime.strptime(myShow["firstaired"],
                                               '%Y-%m-%d').year)
                if year_text:
                    year.text = year_text
            except:
                pass

        if myShow['rating'] != None:
            try:
                rating = int((float(myShow['rating']) * 10))
            except ValueError:
                rating = 0
            Rating = etree.SubElement(tv_node, "rating")
            rating_text = str(rating)
            if rating_text != None:
                Rating.text = rating_text

        Status = etree.SubElement(tv_node, "status")
        if myShow['status'] != None:
            Status.text = myShow['status']

        mpaa = etree.SubElement(tv_node, "mpaa")
        if myShow["contentrating"] != None:
            mpaa.text = myShow["contentrating"]

        IMDB_ID = etree.SubElement(tv_node, "id")
        if myShow['imdb_id'] != None:
            IMDB_ID.attrib["moviedb"] = "imdb"
            IMDB_ID.text = myShow['imdb_id']

        indexerid = etree.SubElement(tv_node, "indexerid")
        if myShow['id'] != None:
            indexerid.text = myShow['id']

        Runtime = etree.SubElement(tv_node, "runtime")
        if myShow['runtime'] != None:
            Runtime.text = myShow['runtime']

        cast = etree.SubElement(tv_node, "cast")
        self.add_actor_element(myShow, etree, cast)

        helpers.indentXML(rootNode)

        data = etree.ElementTree(rootNode)

        return data
Exemplo n.º 56
0
    def _ep_data(self, ep_obj):
        """
        Creates an elementTree XML structure for a MediaBrowser style episode.xml
        and returns the resulting data object.

        show_obj: a TVShow instance to create the NFO for
        """

        eps_to_write = [ep_obj] + ep_obj.relatedEps

        persons_dict = {'Director': [], 'GuestStar': [], 'Writer': []}

        indexer_lang = ep_obj.show.lang

        try:
            lINDEXER_API_PARMS = sickbeard.indexerApi(
                ep_obj.show.indexer).api_params.copy()

            lINDEXER_API_PARMS['actors'] = True

            if indexer_lang and not indexer_lang == sickbeard.INDEXER_DEFAULT_LANGUAGE:
                lINDEXER_API_PARMS['language'] = indexer_lang

            if ep_obj.show.dvdorder != 0:
                lINDEXER_API_PARMS['dvdorder'] = True

            t = sickbeard.indexerApi(
                ep_obj.show.indexer).indexer(**lINDEXER_API_PARMS)

            myShow = t[ep_obj.show.indexerid]
        except sickbeard.indexer_shownotfound as e:
            raise ShowNotFoundException(e.message)
        except sickbeard.indexer_error as e:
            logger.log(
                u"Unable to connect to " +
                sickbeard.indexerApi(ep_obj.show.indexer).name +
                " while creating meta files - skipping - {}".format(ex(e)),
                logger.ERROR)
            return False

        rootNode = etree.Element("Item")

        # write an MediaBrowser XML containing info for all matching episodes
        for curEpToWrite in eps_to_write:

            try:
                myEp = myShow[curEpToWrite.season][curEpToWrite.episode]
            except (sickbeard.indexer_episodenotfound,
                    sickbeard.indexer_seasonnotfound):
                logger.log(
                    u"Unable to find episode %dx%d on %s... has it been removed? Should I delete from db?"
                    % (curEpToWrite.season, curEpToWrite.episode,
                       sickbeard.indexerApi(ep_obj.show.indexer).name))
                return None

            if curEpToWrite == ep_obj:
                # root (or single) episode

                # default to today's date for specials if firstaired is not set
                if ep_obj.season == 0 and not getattr(myEp, 'firstaired',
                                                      None):
                    myEp['firstaired'] = str(datetime.date.fromordinal(1))

                if not (getattr(myEp, 'episodename', None)
                        and getattr(myEp, 'firstaired', None)):
                    return None

                episode = rootNode

                if curEpToWrite.name:
                    EpisodeName = etree.SubElement(episode, "EpisodeName")
                    EpisodeName.text = curEpToWrite.name

                EpisodeNumber = etree.SubElement(episode, "EpisodeNumber")
                EpisodeNumber.text = str(ep_obj.episode)

                if ep_obj.relatedEps:
                    EpisodeNumberEnd = etree.SubElement(
                        episode, "EpisodeNumberEnd")
                    EpisodeNumberEnd.text = str(curEpToWrite.episode)

                SeasonNumber = etree.SubElement(episode, "SeasonNumber")
                SeasonNumber.text = str(curEpToWrite.season)

                if not ep_obj.relatedEps and getattr(myEp, 'absolute_number',
                                                     None):
                    absolute_number = etree.SubElement(episode,
                                                       "absolute_number")
                    absolute_number.text = str(myEp['absolute_number'])

                if curEpToWrite.airdate != datetime.date.fromordinal(1):
                    FirstAired = etree.SubElement(episode, "FirstAired")
                    FirstAired.text = str(curEpToWrite.airdate)

                MetadataType = etree.SubElement(episode, "Type")
                MetadataType.text = "Episode"

                if curEpToWrite.description:
                    Overview = etree.SubElement(episode, "Overview")
                    Overview.text = curEpToWrite.description

                if not ep_obj.relatedEps:
                    if getattr(myEp, 'rating', None):
                        Rating = etree.SubElement(episode, "Rating")
                        Rating.text = myEp['rating']

                    if getattr(myShow, 'imdb_id', None):
                        IMDB_ID = etree.SubElement(episode, "IMDB_ID")
                        IMDB_ID.text = myShow['imdb_id']

                        IMDB = etree.SubElement(episode, "IMDB")
                        IMDB.text = myShow['imdb_id']

                        IMDbId = etree.SubElement(episode, "IMDbId")
                        IMDbId.text = myShow['imdb_id']

                indexerid = etree.SubElement(episode, "id")
                indexerid.text = str(curEpToWrite.indexerid)

                Persons = etree.SubElement(episode, "Persons")

                if getattr(myShow, '_actors', None):
                    for actor in myShow['_actors']:
                        if not ('name' in actor and actor['name'].strip()):
                            continue

                        cur_actor = etree.SubElement(Persons, "Person")

                        cur_actor_name = etree.SubElement(cur_actor, "Name")
                        cur_actor_name.text = actor['name'].strip()

                        cur_actor_type = etree.SubElement(cur_actor, "Type")
                        cur_actor_type.text = "Actor"

                        if 'role' in actor and actor['role'].strip():
                            cur_actor_role = etree.SubElement(
                                cur_actor, "Role")
                            cur_actor_role.text = actor['role'].strip()

                Language = etree.SubElement(episode, "Language")
                try:
                    Language.text = myEp['language']
                except Exception:
                    Language.text = sickbeard.INDEXER_DEFAULT_LANGUAGE  # tvrage api doesn't provide language so we must assume a value here

                thumb = etree.SubElement(episode, "filename")
                # TODO: See what this is needed for.. if its still needed
                # just write this to the NFO regardless of whether it actually exists or not
                # note: renaming files after nfo generation will break this, tough luck
                thumb_text = self.get_episode_thumb_path(ep_obj)
                if thumb_text:
                    thumb.text = thumb_text

            else:
                # append data from (if any) related episodes
                EpisodeNumberEnd.text = str(curEpToWrite.episode)

                if curEpToWrite.name:
                    if not EpisodeName.text:
                        EpisodeName.text = curEpToWrite.name
                    else:
                        EpisodeName.text = EpisodeName.text + ", " + curEpToWrite.name

                if curEpToWrite.description:
                    if not Overview.text:
                        Overview.text = curEpToWrite.description
                    else:
                        Overview.text = Overview.text + "\r" + curEpToWrite.description

            # collect all directors, guest stars and writers
            if getattr(myEp, 'director', None):
                persons_dict['Director'] += [
                    x.strip() for x in myEp['director'].split('|')
                    if x.strip()
                ]
            if getattr(myEp, 'gueststars', None):
                persons_dict['GuestStar'] += [
                    x.strip() for x in myEp['gueststars'].split('|')
                    if x.strip()
                ]
            if getattr(myEp, 'writer', None):
                persons_dict['Writer'] += [
                    x.strip() for x in myEp['writer'].split('|') if x.strip()
                ]

        # fill in Persons section with collected directors, guest starts and writers
        for person_type, names in persons_dict.iteritems():
            # remove doubles
            names = list(set(names))
            for cur_name in names:
                Person = etree.SubElement(Persons, "Person")
                cur_person_name = etree.SubElement(Person, "Name")
                cur_person_name.text = cur_name
                cur_person_type = etree.SubElement(Person, "Type")
                cur_person_type.text = person_type

        helpers.indentXML(rootNode)
        data = etree.ElementTree(rootNode)

        return data
Exemplo n.º 57
0
            raise exceptions.ShowNotFoundException(e.message)
        except sickbeard.indexer_error, e:
            logger.log(u"Unable to connect to " + sickbeard.indexerApi(
                ep_obj.show.indexer).name + " while creating meta files - skipping - " + ex(e), logger.ERROR)
            return False

        rootNode = etree.Element("Item")

        # write an MediaBrowser XML containing info for all matching episodes
        for curEpToWrite in eps_to_write:

            try:
                myEp = myShow[curEpToWrite.season][curEpToWrite.episode]
            except (sickbeard.indexer_episodenotfound, sickbeard.indexer_seasonnotfound):
                logger.log(u"Unable to find episode " + str(curEpToWrite.season) + "x" + str(
                    curEpToWrite.episode) + " on " + sickbeard.indexerApi(
                    ep_obj.show.indexer).name + ".. has it been removed? Should I delete from db?")
                return None

            if curEpToWrite == ep_obj:
                # root (or single) episode

                # default to today's date for specials if firstaired is not set
                if getattr(myEp, 'firstaired', None) is None and ep_obj.season == 0:
                    myEp['firstaired'] = str(datetime.date.fromordinal(1))

                if getattr(myEp, 'episodename', None) is None or getattr(myEp, 'firstaired', None) is None:
                    return None

                episode = rootNode

                EpisodeName = etree.SubElement(episode, "EpisodeName")
Exemplo n.º 58
0
    def _parse_string(self, name):
        if not name:
            return

        matches = []
        bestResult = None

        for (cur_regex_num, cur_regex_name,
             cur_regex) in self.compiled_regexes:
            match = cur_regex.match(name)

            if not match:
                continue

            result = ParseResult(name)
            result.which_regex = [cur_regex_name]
            result.score = 0 - cur_regex_num

            named_groups = match.groupdict().keys()

            if 'series_name' in named_groups:
                result.series_name = match.group('series_name')
                if result.series_name:
                    result.series_name = self.clean_series_name(
                        result.series_name)
                    result.score += 1

            if 'series_num' in named_groups and match.group('series_num'):
                result.score += 1

            if 'season_num' in named_groups:
                tmp_season = int(match.group('season_num'))
                if cur_regex_name == 'bare' and tmp_season in (19, 20):
                    continue
                result.season_number = tmp_season
                result.score += 1

            if 'ep_num' in named_groups:
                ep_num = self._convert_number(match.group('ep_num'))
                if 'extra_ep_num' in named_groups and match.group(
                        'extra_ep_num'):
                    result.episode_numbers = range(
                        ep_num,
                        self._convert_number(match.group('extra_ep_num')) + 1)
                    result.score += 1
                else:
                    result.episode_numbers = [ep_num]
                result.score += 1

            if 'ep_ab_num' in named_groups:
                ep_ab_num = self._convert_number(match.group('ep_ab_num'))
                if 'extra_ab_ep_num' in named_groups and match.group(
                        'extra_ab_ep_num'):
                    result.ab_episode_numbers = range(
                        ep_ab_num,
                        self._convert_number(match.group('extra_ab_ep_num')) +
                        1)
                    result.score += 1
                else:
                    result.ab_episode_numbers = [ep_ab_num]
                result.score += 1

            if 'air_date' in named_groups:
                air_date = match.group('air_date')
                try:
                    result.air_date = parser.parse(air_date, fuzzy=True).date()
                    result.score += 1
                except:
                    continue

            if 'extra_info' in named_groups:
                tmp_extra_info = match.group('extra_info')

                # Show.S04.Special or Show.S05.Part.2.Extras is almost certainly not every episode in the season
                if tmp_extra_info and cur_regex_name == 'season_only' and re.search(
                        r'([. _-]|^)(special|extra)s?\w*([. _-]|$)',
                        tmp_extra_info, re.I):
                    continue
                result.extra_info = tmp_extra_info
                result.score += 1

            if 'release_group' in named_groups:
                result.release_group = match.group('release_group')
                result.score += 1

            if 'version' in named_groups:
                # assigns version to anime file if detected using anime regex. Non-anime regex receives -1
                version = match.group('version')
                if version:
                    result.version = version
                else:
                    result.version = 1
            else:
                result.version = -1

            matches.append(result)

        if len(matches):
            # pick best match with highest score based on placement
            bestResult = max(sorted(matches,
                                    reverse=True,
                                    key=lambda x: x.which_regex),
                             key=lambda x: x.score)

            show = None
            if not self.naming_pattern:
                # try and create a show object for this result
                show = helpers.get_show(bestResult.series_name,
                                        self.tryIndexers)

            # confirm passed in show object indexer id matches result show object indexer id
            if show:
                if self.showObj and show.indexerid != self.showObj.indexerid:
                    show = None
                bestResult.show = show
            elif not show and self.showObj:
                bestResult.show = self.showObj

            # if this is a naming pattern test or result doesn't have a show object then return best result
            if not bestResult.show or self.naming_pattern:
                return bestResult

            # get quality
            bestResult.quality = common.Quality.nameQuality(
                name, bestResult.show.is_anime)

            new_episode_numbers = []
            new_season_numbers = []
            new_absolute_numbers = []

            # if we have an air-by-date show then get the real season/episode numbers
            if bestResult.is_air_by_date:
                airdate = bestResult.air_date.toordinal()
                myDB = db.DBConnection()
                sql_result = myDB.select(
                    "SELECT season, episode FROM tv_episodes WHERE showid = ? and indexer = ? and airdate = ?",
                    [
                        bestResult.show.indexerid, bestResult.show.indexer,
                        airdate
                    ])

                season_number = None
                episode_numbers = []

                if sql_result:
                    season_number = int(sql_result[0][0])
                    episode_numbers = [int(sql_result[0][1])]

                if not season_number or not len(episode_numbers):
                    try:
                        lINDEXER_API_PARMS = sickbeard.indexerApi(
                            bestResult.show.indexer).api_params.copy()

                        if bestResult.show.lang:
                            lINDEXER_API_PARMS[
                                'language'] = bestResult.show.lang

                        t = sickbeard.indexerApi(
                            bestResult.show.indexer).indexer(
                                **lINDEXER_API_PARMS)

                        epObj = t[bestResult.show.indexerid].airedOn(
                            bestResult.air_date)[0]

                        season_number = int(epObj["seasonnumber"])
                        episode_numbers = [int(epObj["episodenumber"])]
                    except sickbeard.indexer_episodenotfound:
                        logger.log(
                            u"Unable to find episode with date " +
                            str(bestResult.air_date) + " for show " +
                            bestResult.show.name + ", skipping",
                            logger.WARNING)
                        episode_numbers = []
                    except sickbeard.indexer_error, e:
                        logger.log(
                            u"Unable to contact " + sickbeard.indexerApi(
                                bestResult.show.indexer).name + ": " + ex(e),
                            logger.WARNING)
                        episode_numbers = []

                for epNo in episode_numbers:
                    s = season_number
                    e = epNo

                    if self.convert:
                        (s, e) = scene_numbering.get_indexer_numbering(
                            bestResult.show.indexerid, bestResult.show.indexer,
                            season_number, epNo)
                    new_episode_numbers.append(e)
                    new_season_numbers.append(s)

            elif bestResult.show.is_anime and len(
                    bestResult.ab_episode_numbers):
                scene_season = scene_exceptions.get_scene_exception_by_name(
                    bestResult.series_name)[1]
                for epAbsNo in bestResult.ab_episode_numbers:
                    a = epAbsNo

                    if self.convert:
                        a = scene_numbering.get_indexer_absolute_numbering(
                            bestResult.show.indexerid, bestResult.show.indexer,
                            epAbsNo, True, scene_season)

                    (s, e) = helpers.get_all_episodes_from_absolute_number(
                        bestResult.show, [a])

                    new_absolute_numbers.append(a)
                    new_episode_numbers.extend(e)
                    new_season_numbers.append(s)

            elif bestResult.season_number and len(bestResult.episode_numbers):
                for epNo in bestResult.episode_numbers:
                    s = bestResult.season_number
                    e = epNo

                    if self.convert:
                        (s, e) = scene_numbering.get_indexer_numbering(
                            bestResult.show.indexerid, bestResult.show.indexer,
                            bestResult.season_number, epNo)
                    if bestResult.show.is_anime:
                        a = helpers.get_absolute_number_from_season_and_episode(
                            bestResult.show, s, e)
                        if a:
                            new_absolute_numbers.append(a)

                    new_episode_numbers.append(e)
                    new_season_numbers.append(s)

            # need to do a quick sanity check heregex.  It's possible that we now have episodes
            # from more than one season (by tvdb numbering), and this is just too much
            # for sickbeard, so we'd need to flag it.
            new_season_numbers = list(
                set(new_season_numbers))  # remove duplicates
            if len(new_season_numbers) > 1:
                raise InvalidNameException(
                    "Scene numbering results episodes from "
                    "seasons %s, (i.e. more than one) and "
                    "SickGear does not support this.  "
                    "Sorry." % (str(new_season_numbers)))

            # I guess it's possible that we'd have duplicate episodes too, so lets
            # eliminate them
            new_episode_numbers = list(set(new_episode_numbers))
            new_episode_numbers.sort()

            # maybe even duplicate absolute numbers so why not do them as well
            new_absolute_numbers = list(set(new_absolute_numbers))
            new_absolute_numbers.sort()

            if len(new_absolute_numbers):
                bestResult.ab_episode_numbers = new_absolute_numbers

            if len(new_season_numbers) and len(new_episode_numbers):
                bestResult.episode_numbers = new_episode_numbers
                bestResult.season_number = new_season_numbers[0]

            if self.convert:
                logger.log(
                    u"Converted parsed result " + bestResult.original_name +
                    " into " +
                    str(bestResult).decode('utf-8', 'xmlcharrefreplace'),
                    logger.DEBUG)
Exemplo n.º 59
0
    def run(self):

        ShowQueueItem.run(self)

        logger.log(u"Beginning update of " + self.show.name, logger.DEBUG)

        logger.log(u"Retrieving show info from " + sickbeard.indexerApi(self.show.indexer).name + "", logger.DEBUG)
        try:
            self.show.loadFromIndexer(cache=not self.force)
        except sickbeard.indexer_error as e:
            logger.log(u"Unable to contact " + sickbeard.indexerApi(self.show.indexer).name + ", aborting: " + ex(e),
                       logger.WARNING)
            return
        except sickbeard.indexer_attributenotfound as e:
            logger.log(u"Data retrieved from " + sickbeard.indexerApi(
                self.show.indexer).name + " was incomplete, aborting: " + ex(e), logger.ERROR)
            return

        logger.log(u"Retrieving show info from IMDb", logger.DEBUG)
        try:
            self.show.loadIMDbInfo()
        except imdb_exceptions.IMDbError as e:
            logger.log(u" Something wrong on IMDb api: " + ex(e), logger.WARNING)
        except Exception as e:
            logger.log(u"Error loading IMDb info: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # have to save show before reading episodes from db
        try:
            self.show.saveToDB()
        except Exception as e:
            logger.log(u"Error saving show info to the database: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # get episode list from DB
        logger.log(u"Loading all episodes from the database", logger.DEBUG)
        DBEpList = self.show.loadEpisodesFromDB()

        # get episode list from TVDB
        logger.log(u"Loading all episodes from " + sickbeard.indexerApi(self.show.indexer).name + "", logger.DEBUG)
        try:
            IndexerEpList = self.show.loadEpisodesFromIndexer(cache=not self.force)
        except sickbeard.indexer_exception as e:
            logger.log(u"Unable to get info from " + sickbeard.indexerApi(
                self.show.indexer).name + ", the show info will not be refreshed: " + ex(e), logger.ERROR)
            IndexerEpList = None

        if IndexerEpList is None:
            logger.log(u"No data returned from " + sickbeard.indexerApi(
                self.show.indexer).name + ", unable to update this show", logger.ERROR)
        else:
            # for each ep we found on the Indexer delete it from the DB list
            for curSeason in IndexerEpList:
                for curEpisode in IndexerEpList[curSeason]:
                    curEp = self.show.getEpisode(curSeason, curEpisode)
                    curEp.saveToDB()

                    if curSeason in DBEpList and curEpisode in DBEpList[curSeason]:
                        del DBEpList[curSeason][curEpisode]

            # remaining episodes in the DB list are not on the indexer, just delete them from the DB
            for curSeason in DBEpList:
                for curEpisode in DBEpList[curSeason]:
                    logger.log(u"Permanently deleting episode " + str(curSeason) + "x" + str(
                        curEpisode) + " from the database", logger.INFO)
                    curEp = self.show.getEpisode(curSeason, curEpisode)
                    try:
                        curEp.deleteEpisode()
                    except EpisodeDeletedException:
                        pass

        # save show again, in case episodes have changed
        try:
            self.show.saveToDB()
        except Exception as e:
            logger.log(u"Error saving show info to the database: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        logger.log(u"Finished update of " + self.show.name, logger.DEBUG)

        sickbeard.showQueueScheduler.action.refreshShow(self.show, self.force)
        self.finish()
Exemplo n.º 60
0
            t = sickbeard.indexerApi(
                show_obj.indexer).indexer(**lINDEXER_API_PARMS)
            indexer_show_obj = t[show_obj.indexerid]
        except (sickbeard.indexer_error, IOError), e:
            logger.log(
                u"Unable to look up show on " +
                sickbeard.indexerApi(show_obj.indexer).name +
                ", not downloading images: " + ex(e), logger.ERROR)
            return None

        if image_type not in ('fanart', 'poster', 'banner', 'poster_thumb',
                              'banner_thumb'):
            logger.log(
                u"Invalid image type " + str(image_type) +
                ", couldn't find it in the " +
                sickbeard.indexerApi(show_obj.indexer).name + " object",
                logger.ERROR)
            return None

        if image_type == 'poster_thumb':
            if getattr(indexer_show_obj, 'poster', None) is not None:
                image_url = re.sub('posters', '_cache/posters',
                                   indexer_show_obj['poster'])
        elif image_type == 'banner_thumb':
            if getattr(indexer_show_obj, 'banner', None) is not None:
                image_url = re.sub('graphical', '_cache/graphical',
                                   indexer_show_obj['banner'])
        else:
            if getattr(indexer_show_obj, image_type, None) is not None:
                image_url = indexer_show_obj[image_type]