Beispiel #1
0
def makeShowNFO(showID, showDir):

    logger.log(u"Making NFO for show "+str(showID)+" in dir "+showDir, logger.DEBUG)

    if not makeDir(showDir):
        logger.log(u"Unable to create show dir, can't make NFO", logger.ERROR)
        return False

    showObj = findCertainShow(sickbeard.showList, showID)
    if not showObj:
        logger.log(u"This should never have happened, post a bug about this!", logger.ERROR)
        raise Exception("BAD STUFF HAPPENED")

    tvdb_lang = showObj.lang
    # There's gotta be a better way of doing this but we don't wanna
    # change the language value elsewhere
    ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

    if tvdb_lang and not tvdb_lang == 'en':
        ltvdb_api_parms['language'] = tvdb_lang

    t = tvdb_api.Tvdb(actors=True, **ltvdb_api_parms)

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

    except tvdb_exceptions.tvdb_error:
        logger.log(u"TVDB is down, can't use its data to add this show", logger.ERROR)
        raise

    # 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(showID) + " on tvdb, skipping it", logger.ERROR)

            return False
    except tvdb_exceptions.tvdb_attributenotfound:
        logger.log(u"Incomplete info for show with id " + str(showID) + " on tvdb, skipping it", logger.ERROR)

        return False

    tvNode = buildNFOXML(myShow)
    # Make it purdy
    indentXML( tvNode )
    nfo = etree.ElementTree( tvNode )

    logger.log(u"Writing NFO to "+os.path.join(showDir, "tvshow.nfo"), logger.DEBUG)
    nfo_filename = os.path.join(showDir, "tvshow.nfo").encode('utf-8')
    nfo_fh = open(nfo_filename, 'w')
    nfo.write( nfo_fh, encoding="utf-8" )

    return True
Beispiel #2
0
def getTVDBIDFromNFO(dir):

    if not ek.ek(os.path.isdir, dir):
        logger.log(u"Show dir doesn't exist, can't load NFO")
        raise exceptions.NoNFOException(
            "The show dir doesn't exist, no NFO could be loaded")

    logger.log(u"Loading show info from NFO")

    xmlFile = ek.ek(os.path.join, dir, "tvshow.nfo")

    try:
        xmlFileObj = ek.ek(open, xmlFile, 'r')
        showXML = etree.ElementTree(file=xmlFileObj)

        if showXML.findtext('title') == None or (
                showXML.findtext('tvdbid') == None
                and showXML.findtext('id') == None):
            raise exceptions.NoNFOException("Invalid info in tvshow.nfo (missing name or id):" \
                + str(showXML.findtext('title')) + " " \
                + str(showXML.findtext('tvdbid')) + " " \
                + str(showXML.findtext('id')))

        if showXML.findtext('tvdbid') != None:
            tvdb_id = int(showXML.findtext('tvdbid'))
        elif showXML.findtext('id'):
            tvdb_id = int(showXML.findtext('id'))
        else:
            raise exceptions.NoNFOException(
                "Empty <id> or <tvdbid> field in NFO")

        try:
            t = tvdb_api.Tvdb(search_all_languages=True,
                              **sickbeard.TVDB_API_PARMS)
            s = t[int(tvdb_id)]
            if not s or not s['seriesname']:
                raise exceptions.NoNFOException(
                    "Show has no name on TVDB, probably the wrong language")
        except tvdb_exceptions.tvdb_exception, e:
            raise exceptions.NoNFOException(
                "Unable to look up the show on TVDB, not using the NFO")

    except (exceptions.NoNFOException, SyntaxError, ValueError), e:
        logger.log(
            u"There was an error parsing your existing tvshow.nfo file: " +
            ex(e), logger.ERROR)
        logger.log(u"Attempting to rename it to tvshow.nfo.old", logger.DEBUG)

        try:
            xmlFileObj.close()
            ek.ek(os.rename, xmlFile, xmlFile + ".old")
        except Exception, e:
            logger.log(
                u"Failed to rename your tvshow.nfo file - you need to delete it or fix it: "
                + ex(e), logger.ERROR)
Beispiel #3
0
    def execute(self):

        ShowQueueItem.execute(self)

        logger.log(u"Starting to add show " + self.showDir)

        try:
            # make sure the tvdb ids are valid
            try:
                ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()
                if self.lang:
                    ltvdb_api_parms['language'] = self.lang

                logger.log(u"TVDB: " + repr(ltvdb_api_parms))

                t = tvdb_api.Tvdb(**ltvdb_api_parms)
                s = t[self.tvdb_id]

                # this usually only happens if they have an NFO in their show dir which gave us a TVDB ID that has no
                # proper english version of the show
                if not s or not s['seriesname']:
                    ui.notifications.error(
                        "Unable to add show", "Show in " + self.showDir +
                        " has no name on TVDB, probably the wrong language. Delete .nfo and add manually in the correct language."
                    )
                    self._finishEarly()
                    return
            except tvdb_exceptions.tvdb_exception, e:
                logger.log(u"Error contacting TVDB: " + str(e), logger.ERROR)
                ui.notifications.error(
                    "Unable to add show",
                    "Unable to look up the show in " + self.showDir +
                    " on TVDB, not using the NFO. Delete .nfo and add manually in the correct language."
                )
                self._finishEarly()
                return

            # clear the name cache
            name_cache.clearCache()

            newShow = TVShow(self.tvdb_id, self.lang)
            newShow.loadFromTVDB()

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
            self.show.seasonfolders = self.season_folders if self.season_folders != None else sickbeard.SEASON_FOLDERS_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
Beispiel #4
0
def get_show_by_name(name, showList, useTvdb=False):
    logger.log(u"Trying to get the tvdbid 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 useTvdb:
        try:
            t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI,
                              **sickbeard.TVDB_API_PARMS)
            showObj = t[name]
        except (tvdb_exceptions.tvdb_exception):
            # if none found, search on all languages
            try:
                # There's gotta be a better way of doing this but we don't wanna
                # change the language value elsewhere
                ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

                ltvdb_api_parms['search_all_languages'] = True
                t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI,
                                  **ltvdb_api_parms)
                showObj = t[name]
            except (tvdb_exceptions.tvdb_exception, IOError):
                pass

            return None
        except (IOError):
            return None
        else:
            show = findCertainShow(sickbeard.showList, int(showObj["id"]))
            if show:
                return show

    return None
Beispiel #5
0
    def checkSync(self, info=None):

        logger.log(u"Checking the last aired episode to see if the dates match between TVDB and TVRage")

        if self.lastEpInfo == None or self.nextEpInfo == None:
            self._saveLatestInfo(info)

        if self.nextEpInfo['season'] == 0 or self.nextEpInfo['episode'] == 0:
            return None

        try:

            airdate = None

            tvdb_lang = self.show.lang
            # There's gotta be a better way of doing this but we don't wanna
            # change the language value elsewhere
            ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

            if tvdb_lang and not tvdb_lang == 'en':
                ltvdb_api_parms['language'] = tvdb_lang

            # make sure the last TVDB episode matches our last episode
            try:
                t = tvdb_api.Tvdb(**ltvdb_api_parms)
                ep = t[self.show.tvdbid][self.lastEpInfo['season']][self.lastEpInfo['episode']]

                if ep["firstaired"] == "" or ep["firstaired"] == None:
                    return None

                rawAirdate = [int(x) for x in ep["firstaired"].split("-")]
                airdate = datetime.date(rawAirdate[0], rawAirdate[1], rawAirdate[2])

            except tvdb_exceptions.tvdb_exception, e:
                logger.log(u"Unable to check TVRage info against TVDB: "+ex(e))

                logger.log(u"Trying against DB instead", logger.DEBUG)

                myDB = db.DBConnection()
                sqlResults = myDB.select("SELECT * FROM tv_episodes WHERE showid = ? AND season = ? and episode = ?", [self.show.tvdbid, self.lastEpInfo['season'], self.lastEpInfo['episode']])

                if len(sqlResults) == 0:
                    raise exceptions.EpisodeNotFoundException("Unable to find episode in DB")
                else:
                    airdate = datetime.date.fromordinal(int(sqlResults[0]["airdate"]))

            logger.log(u"Date from TVDB for episode " + str(self.lastEpInfo['season']) + "x" + str(self.lastEpInfo['episode']) + ": " + str(airdate), logger.DEBUG)
            logger.log(u"Date from TVRage for episode " + str(self.lastEpInfo['season']) + "x" + str(self.lastEpInfo['episode']) + ": " + str(self.lastEpInfo['airdate']), logger.DEBUG)

            if self.lastEpInfo['airdate'] == airdate:
                return True
Beispiel #6
0
    def _retrieve_show_image(self, image_type, show_obj, which=None):
        """
        Gets an image URL from theTVDB.com, downloads it and returns the data.
        
        image_type: type of image to retrieve (currently supported: poster, fanart)
        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
        """

        if sickbeard.USE_ANIDB_POSTERS and show_obj.anime and show_obj.anidb_picname and image_type in (
                'poster', 'poster_thumb'):
            image_url = "http://img7.anidb.net/pics/anime/" + show_obj.anidb_picname
        else:
            tvdb_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
                ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

                if tvdb_lang and not tvdb_lang == 'en':
                    ltvdb_api_parms['language'] = tvdb_lang

                t = tvdb_api.Tvdb(banners=True, **ltvdb_api_parms)
                tvdb_show_obj = t[show_obj.tvdbid]
            except (tvdb_exceptions.tvdb_error, IOError), e:
                logger.log(
                    u"Unable to look up show on TVDB, 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 TVDB object", logger.ERROR)
                return None

            try:
                if image_type == 'poster_thumb':
                    image_url = re.sub('posters', '_cache/posters',
                                       tvdb_show_obj['poster'])
                elif image_type == 'banner_thumb':
                    image_url = re.sub('graphical', '_cache/graphical',
                                       tvdb_show_obj['banner'])
                else:
                    image_url = tvdb_show_obj[image_type]
            except:
                return None
Beispiel #7
0
    def execute(self):

        ShowQueueItem.execute(self)

        logger.log(u"Starting to add show " + self.showDir)

        try:
            # make sure the tvdb ids are valid
            try:
                ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()
                if self.lang:
                    ltvdb_api_parms['language'] = self.lang

                t = tvdb_api.Tvdb(**ltvdb_api_parms)
                s = t[self.tvdb_id]
                if not s or not s['seriesname']:
                    ui.flash.error(
                        "Unable to add show", "Show in " + str(self.showDir) +
                        " has no name on TVDB, probably the wrong language. Delete .nfo and add manually in the correct language."
                    )
                    self._finishEarly()
                    return
            except tvdb_exceptions.tvdb_exception, e:
                ui.flash.error(
                    "Unable to add show",
                    "Unable to look up the show in " + str(self.showDir) +
                    " on TVDB, not using the NFO. Delete .nfo and add manually in the correct language."
                )
                self._finishEarly()
                return

            newShow = TVShow(self.tvdb_id, self.lang)
            newShow.loadFromTVDB()

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
            self.show.seasonfolders = self.season_folders if self.season_folders != None else sickbeard.SEASON_FOLDERS_DEFAULT
            self.show.paused = False
Beispiel #8
0
    def _convertADB(self, show, adb_part):
        self._log(
            "Getting season and episodes for ADB episode: " + str(adb_part),
            logger.DEBUG)
        if not show:
            return (None, None)

        myDB = db.DBConnection()
        sql_results = myDB.select(
            "SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
            [show.tvdbid, adb_part.toordinal()])
        if len(sql_results) == 1:
            return (int(sql_results[0]["season"]),
                    [int(sql_results[0]["episode"])])

        if self.tvdbActiveLookUp:
            try:
                # There's gotta be a better way of doing this but we don't wanna
                # change the cache value elsewhere
                ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

                if show.lang:
                    ltvdb_api_parms['language'] = self.lang

                t = tvdb_api.Tvdb(**ltvdb_api_parms)

                epObj = t[show.tvdbid].airedOn(adb_part)[0]
                season = int(epObj["seasonnumber"])
                episodes = [int(epObj["episodenumber"])]
            except tvdb_exceptions.tvdb_episodenotfound:
                self._log(
                    u"Unable to find episode with date " + str(episodes[0]) +
                    " for show " + self.name_to_parse + ", skipping",
                    logger.WARNING)
                return (None, None)
            except tvdb_exceptions.tvdb_error, e:
                self._log(u"Unable to contact TVDB: " + ex(e), logger.WARNING)
                return (None, None)
            else:
                return (season, episodes)
Beispiel #9
0
    def _ep_data(self, ep_obj):
        """
        Creates an elementTree XML structure for an XBMC-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

        tvdb_lang = ep_obj.show.lang
        # There's gotta be a better way of doing this but we don't wanna
        # change the language value elsewhere
        ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

        if tvdb_lang and not tvdb_lang == 'en':
            ltvdb_api_parms['language'] = tvdb_lang

        try:
            t = tvdb_api.Tvdb(actors=True, **ltvdb_api_parms)
            myShow = t[ep_obj.show.tvdbid]
        except tvdb_exceptions.tvdb_shownotfound, e:
            raise exceptions.ShowNotFoundException(e.message)
Beispiel #10
0
    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/tvdb_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

        tvdb_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
            ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

            if tvdb_lang and not tvdb_lang == 'en':
                ltvdb_api_parms['language'] = tvdb_lang

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

            t = tvdb_api.Tvdb(actors=True, **ltvdb_api_parms)
            myShow = t[ep_obj.show.tvdbid]
        except tvdb_exceptions.tvdb_shownotfound, e:
            raise exceptions.ShowNotFoundException(str(e))
Beispiel #11
0
    def _get_episode_thumb_url(self, ep_obj):
        """
        Returns the URL to use for downloading an episode's thumbnail. Uses
        theTVDB.com data.
        
        ep_obj: a TVEpisode object for which to grab the thumb URL
        """
        all_eps = [ep_obj] + ep_obj.relatedEps

        tvdb_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
            ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

            if tvdb_lang and not tvdb_lang == 'en':
                ltvdb_api_parms['language'] = tvdb_lang

            t = tvdb_api.Tvdb(actors=True, **ltvdb_api_parms)
            tvdb_show_obj = t[ep_obj.show.tvdbid]
        except tvdb_exceptions.tvdb_shownotfound, e:
            raise exceptions.ShowNotFoundException(e.message)
Beispiel #12
0
    def _find_info(self):
        """
        For a given file try to find the showid, season, and episode.
        """

        tvdb_id = season = None
        episodes = []

        # try to look up the nzb in history
        attempt_list = [
            self._history_lookup,

            # try to analyze the nzb name
            lambda: self._analyze_name(self.nzb_name),

            # try to analyze the file name
            lambda: self._analyze_name(self.file_name),

            # try to analyze the dir name
            lambda: self._analyze_name(self.folder_name),

            # try to analyze the file+dir names together
            lambda: self._analyze_name(self.file_path),

            # try to analyze the dir + file name together as one name
            lambda: self._analyze_name(self.folder_name + u' ' + self.file_name
                                       )
        ]

        # attempt every possible method to get our info
        for cur_attempt in attempt_list:

            try:
                (cur_tvdb_id, cur_season, cur_episodes) = cur_attempt()
            except InvalidNameException, e:
                logger.log(u"Unable to parse, skipping: " + ex(e),
                           logger.DEBUG)
                continue

            # if we already did a successful history lookup then keep that tvdb_id value
            if cur_tvdb_id and not (self.in_history and tvdb_id):
                tvdb_id = cur_tvdb_id
            if cur_season != None:
                season = cur_season
            if cur_episodes:
                episodes = cur_episodes

            # for air-by-date shows we need to look up the season/episode from tvdb
            if season == -1 and tvdb_id and episodes:
                self._log(
                    u"Looks like this is an air-by-date show, attempting to convert the date to season/episode",
                    logger.DEBUG)

                # try to get language set for this show
                tvdb_lang = None
                try:
                    showObj = helpers.findCertainShow(sickbeard.showList,
                                                      tvdb_id)
                    if (showObj != None):
                        tvdb_lang = showObj.lang
                except exceptions.MultipleShowObjectsException:
                    raise  #TODO: later I'll just log this, for now I want to know about it ASAP

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

                    if tvdb_lang and not tvdb_lang == 'en':
                        ltvdb_api_parms['language'] = tvdb_lang

                    t = tvdb_api.Tvdb(**ltvdb_api_parms)
                    epObj = t[tvdb_id].airedOn(episodes[0])[0]
                    season = int(epObj["seasonnumber"])
                    episodes = [int(epObj["episodenumber"])]
                    self._log(
                        u"Got season " + str(season) + " episodes " +
                        str(episodes), logger.DEBUG)
                except tvdb_exceptions.tvdb_episodenotfound, e:
                    self._log(
                        u"Unable to find episode with date " +
                        str(episodes[0]) + u" for show " + str(tvdb_id) +
                        u", skipping", logger.DEBUG)
                    # we don't want to leave dates in the episode list if we couldn't convert them to real episode numbers
                    episodes = []
                    continue
                except tvdb_exceptions.tvdb_error, e:
                    logger.log(u"Unable to contact TVDB: " + ex(e),
                               logger.WARNING)
                    episodes = []
                    continue
Beispiel #13
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
        """

        tvdb_lang = show_obj.lang
        # There's gotta be a better way of doing this but we don't wanna
        # change the language value elsewhere
        ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

        if tvdb_lang and not tvdb_lang == 'en':
            ltvdb_api_parms['language'] = tvdb_lang

        t = tvdb_api.Tvdb(actors=True, **ltvdb_api_parms)

        tv_node = etree.Element("Series")

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

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

        # 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.tvdbid) + " on tvdb, skipping it",
                    logger.ERROR)
                return False
        except tvdb_exceptions.tvdb_attributenotfound:
            logger.log(
                u"Incomplete info for show with id " + str(show_obj.tvdbid) +
                " on tvdb, skipping it", logger.ERROR)
            return False

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

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

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

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

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

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

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

        ContentRating = etree.SubElement(tv_node, "ContentRating")
        MPAARating = etree.SubElement(tv_node, "MPAARating")
        certification = etree.SubElement(tv_node, "certification")
        if myShow['contentrating'] != 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 myShow['overview'] != None:
            Overview.text = myShow['overview']

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

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

        ProductionYear = etree.SubElement(tv_node, "ProductionYear")
        if myShow['firstaired'] != 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 myShow['runtime'] != 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 myShow['imdb_id'] != None:
            IMDB_ID.text = myShow['imdb_id']
            IMDB.text = myShow['imdb_id']
            IMDbId.text = myShow['imdb_id']

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

        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()

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

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

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

        if myShow["_actors"] != None:
            for actor in myShow["_actors"]:
                cur_actor_name_text = actor['name']

                if cur_actor_name_text != None and cur_actor_name_text.strip():
                    cur_actor = etree.SubElement(Persons, "Person")
                    cur_actor_name = etree.SubElement(cur_actor, "Name")
                    cur_actor_name.text = cur_actor_name_text.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
Beispiel #14
0
    def _analyze_name(self, name, file=True):
        """
        Takes a name and tries to figure out a show, season, and episode from it.
        
        name: A string which we want to analyze to determine show info from (unicode)
        
        Returns a (tvdb_id, season, [episodes]) tuple. The first two may be None and episodes may be []
        if none were found.
        """

        logger.log(u"Analyzing name " + repr(name))

        to_return = (None, None, [])

        if not name:
            return to_return

        # parse the name to break it into show name, season, and episode
        np = NameParser(file)
        parse_result = np.parse(name)
        self._log(
            "Parsed " + name + " into " + str(parse_result).decode('utf-8'),
            logger.DEBUG)

        if parse_result.air_by_date:
            season = -1
            episodes = [parse_result.air_date]
        else:
            season = parse_result.season_number
            episodes = parse_result.episode_numbers

        to_return = (None, season, episodes)

        # do a scene reverse-lookup to get a list of all possible names
        name_list = show_name_helpers.sceneToNormalShowNames(
            parse_result.series_name)

        if not name_list:
            return (None, season, episodes)

        def _finalize(parse_result):
            self.release_group = parse_result.release_group

            # remember whether it's a proper
            if parse_result.extra_info:
                self.is_proper = re.search(
                    '(^|[\. _-])(proper|repack)([\. _-]|$)',
                    parse_result.extra_info, re.I) != None

            # if the result is complete then remember that for later
            if parse_result.series_name and parse_result.season_number != None and parse_result.episode_numbers and parse_result.release_group:
                test_name = os.path.basename(name)
                if test_name == self.nzb_name:
                    self.good_results[self.NZB_NAME] = True
                elif test_name == self.folder_name:
                    self.good_results[self.FOLDER_NAME] = True
                elif test_name == self.file_name:
                    self.good_results[self.FILE_NAME] = True
                else:
                    logger.log(u"Nothing was good, found " + repr(test_name) +
                               " and wanted either " + repr(self.nzb_name) +
                               ", " + repr(self.folder_name) + ", or " +
                               repr(self.file_name))
            else:
                logger.log(
                    "Parse result not suficent(all folowing have to be set). will not save release name",
                    logger.DEBUG)
                logger.log(
                    "Parse result(series_name): " +
                    str(parse_result.series_name), logger.DEBUG)
                logger.log(
                    "Parse result(season_number): " +
                    str(parse_result.season_number), logger.DEBUG)
                logger.log(
                    "Parse result(episode_numbers): " +
                    str(parse_result.episode_numbers), logger.DEBUG)
                logger.log(
                    "Parse result(release_group): " +
                    str(parse_result.release_group), logger.DEBUG)

        # for each possible interpretation of that scene name
        for cur_name in name_list:
            self._log(u"Checking scene exceptions for a match on " + cur_name,
                      logger.DEBUG)
            scene_id = scene_exceptions.get_scene_exception_by_name(cur_name)
            if scene_id:
                self._log(
                    u"Scene exception lookup got tvdb id " + str(scene_id) +
                    u", using that", logger.DEBUG)
                _finalize(parse_result)
                return (scene_id, season, episodes)

        # see if we can find the name directly in the DB, if so use it
        for cur_name in name_list:
            self._log(u"Looking up " + cur_name + u" in the DB", logger.DEBUG)
            db_result = helpers.searchDBForShow(cur_name)
            if db_result:
                self._log(
                    u"Lookup successful, using tvdb id " + str(db_result[0]),
                    logger.DEBUG)
                _finalize(parse_result)
                return (int(db_result[0]), season, episodes)

        # see if we can find the name with a TVDB lookup
        for cur_name in name_list:
            try:
                t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI,
                                  **sickbeard.TVDB_API_PARMS)

                self._log(u"Looking up name " + cur_name + u" on TVDB",
                          logger.DEBUG)
                showObj = t[cur_name]
            except (tvdb_exceptions.tvdb_exception):
                # if none found, search on all languages
                try:
                    # There's gotta be a better way of doing this but we don't wanna
                    # change the language value elsewhere
                    ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

                    ltvdb_api_parms['search_all_languages'] = True
                    t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI,
                                      **ltvdb_api_parms)

                    self._log(
                        u"Looking up name " + cur_name +
                        u" in all languages on TVDB", logger.DEBUG)
                    showObj = t[cur_name]
                except (tvdb_exceptions.tvdb_exception, IOError):
                    pass

                continue
            except (IOError):
                continue

            self._log(
                u"Lookup successful, using tvdb id " + str(showObj["id"]),
                logger.DEBUG)
            _finalize(parse_result)
            return (int(showObj["id"]), season, episodes)

        _finalize(parse_result)
        return to_return
Beispiel #15
0
    def confirmShow(self, force=False):

        if self.show.tvrid != 0 and not force:
            logger.log(u"We already have a TVRage ID, skipping confirmation",
                       logger.DEBUG)
            return True

        logger.log(
            u"Checking the first episode of each season to see if the air dates match between TVDB and TVRage"
        )

        tvdb_lang = self.show.lang

        try:

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

                if tvdb_lang and not tvdb_lang == 'en':
                    ltvdb_api_parms['language'] = tvdb_lang

                t = tvdb_api.Tvdb(**ltvdb_api_parms)
            except tvdb_exceptions.tvdb_exception, e:
                logger.log(
                    u"Currently this doesn't work with TVDB down but with some DB magic it can be added",
                    logger.DEBUG)
                return None

            # check the first episode of every season
            for curSeason in t[self.show.tvdbid]:

                logger.log(
                    u"Checking TVDB and TVRage sync for season " +
                    str(curSeason), logger.DEBUG)

                airdate = None

                try:

                    # don't do specials and don't do seasons with no episode 1
                    if curSeason == 0 or 1 not in t[self.show.tvdbid]:
                        continue

                    # get the episode info from TVDB
                    ep = t[self.show.tvdbid][curSeason][1]

                    # make sure we have a date to compare with
                    if ep["firstaired"] == "" or ep["firstaired"] == None or ep[
                            "firstaired"] == "0000-00-00":
                        continue

                    # get a datetime object
                    rawAirdate = [int(x) for x in ep["firstaired"].split("-")]
                    airdate = datetime.date(rawAirdate[0], rawAirdate[1],
                                            rawAirdate[2])

                    # get the episode info from TVRage
                    info = self._getTVRageInfo(curSeason, 1)

                    # make sure we have enough info
                    if info == None or not info.has_key('Episode Info'):
                        logger.log(
                            u"TVRage doesn't have the episode info, skipping it",
                            logger.DEBUG)
                        continue

                    # parse the episode info
                    curEpInfo = self._getEpInfo(info['Episode Info'])

                    # make sure we got some info back
                    if curEpInfo == None:
                        continue

                # if we couldn't compare with TVDB try comparing it with the local database
                except tvdb_exceptions.tvdb_exception, e:
                    logger.log(u"Unable to check TVRage info against TVDB: " +
                               ex(e))

                    logger.log(u"Trying against DB instead", logger.DEBUG)

                    myDB = db.DBConnection()
                    sqlResults = myDB.select(
                        "SELECT * FROM tv_episodes WHERE showid = ? AND season = ? and episode = ?",
                        [
                            self.show.tvdbid, self.lastEpInfo['season'],
                            self.lastEpInfo['episode']
                        ])

                    if len(sqlResults) == 0:
                        raise exceptions.EpisodeNotFoundException(
                            "Unable to find episode in DB")
                    else:
                        airdate = datetime.date.fromordinal(
                            int(sqlResults[0]["airdate"]))

                # check if TVRage and TVDB have the same airdate for this episode
                if curEpInfo['airdate'] == airdate:
                    logger.log(
                        u"Successful match for TVRage and TVDB data for episode "
                        + str(curSeason) + "x1)", logger.DEBUG)
                    return True

                logger.log(
                    u"Date from TVDB for episode " + str(curSeason) + "x1: " +
                    str(airdate), logger.DEBUG)
                logger.log(
                    u"Date from TVRage for episode " + str(curSeason) +
                    "x1: " + str(curEpInfo['airdate']), logger.DEBUG)
class ProperFinder():
    def __init__(self):
        self.updateInterval = datetime.timedelta(hours=1)

    def run(self):

        if not sickbeard.DOWNLOAD_PROPERS:
            return

        # look for propers every night at 1 AM
        updateTime = datetime.time(hour=1)

        logger.log(u"Checking proper time", logger.DEBUG)

        hourDiff = datetime.datetime.today().time().hour - updateTime.hour

        # if it's less than an interval after the update time then do an update
        if hourDiff >= 0 and hourDiff < self.updateInterval.seconds / 3600:
            logger.log(u"Beginning the search for new propers")
        else:
            return

        propers = self._getProperList()

        self._downloadPropers(propers)

    def _getProperList(self):

        propers = {}

        # for each provider get a list of the propers
        for curProvider in providers.sortedProviderList():

            if not curProvider.isActive():
                continue

            search_date = datetime.datetime.today() - datetime.timedelta(
                days=2)

            logger.log(u"Searching for any new PROPER releases from " +
                       curProvider.name)
            try:
                curPropers = curProvider.findPropers(search_date)
            except exceptions.AuthException, e:
                logger.log(u"Authentication error: " + ex(e), logger.ERROR)
                continue

            # if they haven't been added by a different provider than add the proper to the list
            for x in curPropers:
                name = self._genericName(x.name)

                if not name in propers:
                    logger.log(u"Found new proper: " + x.name, logger.DEBUG)
                    x.provider = curProvider
                    propers[name] = x

        # take the list of unique propers and get it sorted by
        sortedPropers = sorted(propers.values(),
                               key=operator.attrgetter('date'),
                               reverse=True)
        finalPropers = []

        for curProper in sortedPropers:

            # parse the file name
            try:
                myParser = NameParser(False)
                parse_result = myParser.parse(curProper.name)
            except InvalidNameException:
                logger.log(
                    u"Unable to parse the filename " + curProper.name +
                    " into a valid episode", logger.DEBUG)
                continue

            if not parse_result.episode_numbers:
                logger.log(
                    u"Ignoring " + curProper.name +
                    " because it's for a full season rather than specific episode",
                    logger.DEBUG)
                continue

            # populate our Proper instance
            if parse_result.air_by_date:
                curProper.season = -1
                curProper.episode = parse_result.air_date
            else:
                curProper.season = parse_result.season_number if parse_result.season_number != None else 1
                curProper.episode = parse_result.episode_numbers[0]
            curProper.quality = Quality.nameQuality(curProper.name)

            # for each show in our list
            for curShow in sickbeard.showList:

                if not parse_result.series_name:
                    continue

                genericName = self._genericName(parse_result.series_name)

                # get the scene name masks
                sceneNames = set(
                    show_name_helpers.makeSceneShowSearchStrings(curShow))

                # for each scene name mask
                for curSceneName in sceneNames:

                    # if it matches
                    if genericName == self._genericName(curSceneName):
                        logger.log(
                            u"Successful match! Result " +
                            parse_result.series_name + " matched to show " +
                            curShow.name, logger.DEBUG)

                        # set the tvdbid in the db to the show's tvdbid
                        curProper.tvdbid = curShow.tvdbid

                        # since we found it, break out
                        break

                # if we found something in the inner for loop break out of this one
                if curProper.tvdbid != -1:
                    break

            if curProper.tvdbid == -1:
                continue

            if not show_name_helpers.filterBadReleases(curProper.name):
                logger.log(
                    u"Proper " + curProper.name +
                    " isn't a valid scene release that we want, igoring it",
                    logger.DEBUG)
                continue

            # if we have an air-by-date show then get the real season/episode numbers
            if curProper.season == -1 and curProper.tvdbid:
                showObj = helpers.findCertainShow(sickbeard.showList,
                                                  curProper.tvdbid)
                if not showObj:
                    logger.log(
                        u"This should never have happened, post a bug about this!",
                        logger.ERROR)
                    raise Exception("BAD STUFF HAPPENED")

                tvdb_lang = showObj.lang
                # There's gotta be a better way of doing this but we don't wanna
                # change the language value elsewhere
                ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

                if tvdb_lang and not tvdb_lang == 'en':
                    ltvdb_api_parms['language'] = tvdb_lang

                try:
                    t = tvdb_api.Tvdb(**ltvdb_api_parms)
                    epObj = t[curProper.tvdbid].airedOn(curProper.episode)[0]
                    curProper.season = int(epObj["seasonnumber"])
                    curProper.episodes = [int(epObj["episodenumber"])]
                except tvdb_exceptions.tvdb_episodenotfound:
                    logger.log(
                        u"Unable to find episode with date " +
                        str(curProper.episode) + " for show " +
                        parse_result.series_name + ", skipping",
                        logger.WARNING)
                    continue

            # check if we actually want this proper (if it's the right quality)
            sqlResults = db.DBConnection().select(
                "SELECT status FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?",
                [curProper.tvdbid, curProper.season, curProper.episode])
            if not sqlResults:
                continue
            oldStatus, oldQuality = Quality.splitCompositeStatus(
                int(sqlResults[0]["status"]))

            # only keep the proper if we have already retrieved the same quality ep (don't get better/worse ones)
            if oldStatus not in (DOWNLOADED,
                                 SNATCHED) or oldQuality != curProper.quality:
                continue

            # if the show is in our list and there hasn't been a proper already added for that particular episode then add it to our list of propers
            if curProper.tvdbid != -1 and (curProper.tvdbid, curProper.season,
                                           curProper.episode) not in map(
                                               operator.attrgetter(
                                                   'tvdbid', 'season',
                                                   'episode'), finalPropers):
                logger.log(u"Found a proper that we need: " +
                           str(curProper.name))
                finalPropers.append(curProper)

        return finalPropers
Beispiel #17
0
    def _analyze_name(self, name, file=True):
        """
        Takes a name and tries to figure out a show, season, and episode from it.
        
        Returns a (tvdb_id, season, [episodes]) tuple. The first two may be None and episodes may be []
        if none were found.
        """

        logger.log(u"Analyzing name " + repr(name))

        to_return = (None, None, [])

        if not name:
            return to_return

        # parse the name to break it into show name, season, and episode
        np = NameParser(file)
        parse_result = np.parse(name)
        self._log(
            "Parsed " + name + " into " + str(parse_result).decode('utf-8'),
            logger.DEBUG)

        if parse_result.air_by_date:
            season = -1
            episodes = [parse_result.air_date]
        else:
            season = parse_result.season_number
            episodes = parse_result.episode_numbers

        to_return = (None, season, episodes)

        # do a scene reverse-lookup to get a list of all possible names
        name_list = sceneHelpers.sceneToNormalShowNames(
            parse_result.series_name)

        if not name_list:
            return (None, season, episodes)

        def _finalize(parse_result):
            self.release_group = parse_result.release_group
            if parse_result.extra_info:
                self.is_proper = re.search(
                    '(^|[\. _-])(proper|repack)([\. _-]|$)',
                    parse_result.extra_info, re.I) != None

        # for each possible interpretation of that scene name
        for cur_name in name_list:
            self._log(u"Checking scene exceptions for a match on " + cur_name,
                      logger.DEBUG)
            for exceptionID in common.sceneExceptions:
                # for each exception name
                for curException in common.sceneExceptions[exceptionID]:
                    if cur_name.lower() in (curException.lower(),
                                            sceneHelpers.sanitizeSceneName(
                                                curException).lower().replace(
                                                    '.', ' ')):
                        self._log(
                            u"Scene exception lookup got tvdb id " +
                            str(exceptionID) + u", using that", logger.DEBUG)
                        _finalize(parse_result)
                        return (exceptionID, season, episodes)

        # see if we can find the name directly in the DB, if so use it
        for cur_name in name_list:
            self._log(u"Looking up " + cur_name + u" in the DB", logger.DEBUG)
            db_result = helpers.searchDBForShow(cur_name)
            if db_result:
                self._log(
                    u"Lookup successful, using tvdb id " + str(db_result[0]),
                    logger.DEBUG)
                _finalize(parse_result)
                return (int(db_result[0]), season, episodes)

        # see if we can find the name with a TVDB lookup
        for cur_name in name_list:
            try:
                t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI,
                                  **sickbeard.TVDB_API_PARMS)

                self._log(u"Looking up name " + cur_name + u" on TVDB",
                          logger.DEBUG)
                showObj = t[cur_name]
            except (tvdb_exceptions.tvdb_exception), e:
                # if none found, search on all languages
                try:
                    # There's gotta be a better way of doing this but we don't wanna
                    # change the language value elsewhere
                    ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

                    ltvdb_api_parms['search_all_languages'] = True
                    t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI,
                                      **ltvdb_api_parms)

                    self._log(
                        u"Looking up name " + cur_name +
                        u" in all languages on TVDB", logger.DEBUG)
                    showObj = t[cur_name]
                except (tvdb_exceptions.tvdb_exception, IOError), e:
                    pass

                continue
Beispiel #18
0
    def _addCacheEntry(self,
                       name,
                       url,
                       season=None,
                       episodes=None,
                       tvdb_id=0,
                       tvrage_id=0,
                       quality=None,
                       extraNames=[]):

        myDB = self._getDB()

        parse_result = None

        # if we don't have complete info then parse the filename to get it
        for curName in [name] + extraNames:
            try:
                myParser = NameParser()
                parse_result = myParser.parse(curName)
            except InvalidNameException:
                logger.log(
                    u"Unable to parse the filename " + curName +
                    " into a valid episode", logger.DEBUG)
                continue

        if not parse_result:
            logger.log(
                u"Giving up because I'm unable to parse this name: " + name,
                logger.DEBUG)
            return False

        if not parse_result.series_name:
            logger.log(
                u"No series name retrieved from " + name +
                ", unable to cache it", logger.DEBUG)
            return False

        tvdb_lang = None

        # if we need tvdb_id or tvrage_id then search the DB for them
        if not tvdb_id or not tvrage_id:

            # if we have only the tvdb_id, use the database
            if tvdb_id:
                showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id)
                if showObj:
                    tvrage_id = showObj.tvrid
                    tvdb_lang = showObj.lang
                else:
                    logger.log(
                        u"We were given a TVDB id " + str(tvdb_id) +
                        " but it doesn't match a show we have in our list, so leaving tvrage_id empty",
                        logger.DEBUG)
                    tvrage_id = 0

            # if we have only a tvrage_id then use the database
            elif tvrage_id:
                showObj = helpers.findCertainTVRageShow(
                    sickbeard.showList, tvrage_id)
                if showObj:
                    tvdb_id = showObj.tvdbid
                    tvdb_lang = showObj.lang
                else:
                    logger.log(
                        u"We were given a TVRage id " + str(tvrage_id) +
                        " but it doesn't match a show we have in our list, so leaving tvdb_id empty",
                        logger.DEBUG)
                    tvdb_id = 0

            # if they're both empty then fill out as much info as possible by searching the show name
            else:

                # check the name cache and see if we already know what show this is
                logger.log(
                    u"Checking the cache to see if we already know the tvdb id of "
                    + parse_result.series_name, logger.DEBUG)
                tvdb_id = name_cache.retrieveNameFromCache(
                    parse_result.series_name)

                # remember if the cache lookup worked or not so we know whether we should bother updating it later
                if tvdb_id == None:
                    logger.log(
                        u"No cache results returned, continuing on with the search",
                        logger.DEBUG)
                    from_cache = False
                else:
                    logger.log(
                        u"Cache lookup found " + repr(tvdb_id) +
                        ", using that", logger.DEBUG)
                    from_cache = True

                # if the cache failed, try looking up the show name in the database
                if tvdb_id == None:
                    logger.log(
                        u"Trying to look the show up in the show database",
                        logger.DEBUG)
                    showResult = helpers.searchDBForShow(
                        parse_result.series_name)
                    if showResult:
                        logger.log(
                            parse_result.series_name +
                            " was found to be show " + showResult[1] + " (" +
                            str(showResult[0]) + ") in our DB.", logger.DEBUG)
                        tvdb_id = showResult[0]

                # if the DB lookup fails then do a comprehensive regex search
                if tvdb_id == None:
                    logger.log(
                        u"Couldn't figure out a show name straight from the DB, trying a regex search instead",
                        logger.DEBUG)
                    for curShow in sickbeard.showList:
                        if show_name_helpers.isGoodResult(
                                name, curShow, False):
                            logger.log(
                                u"Successfully matched " + name + " to " +
                                curShow.name + " with regex", logger.DEBUG)
                            tvdb_id = curShow.tvdbid
                            tvdb_lang = curShow.lang
                            break

                # if tvdb_id was anything but None (0 or a number) then
                if not from_cache:
                    name_cache.addNameToCache(parse_result.series_name,
                                              tvdb_id)

                # if we came out with tvdb_id = None it means we couldn't figure it out at all, just use 0 for that
                if tvdb_id == None:
                    tvdb_id = 0

                # if we found the show then retrieve the show object
                if tvdb_id:
                    showObj = helpers.findCertainShow(sickbeard.showList,
                                                      tvdb_id)
                    if showObj:
                        tvrage_id = showObj.tvrid
                        tvdb_lang = showObj.lang

        # if we weren't provided with season/episode information then get it from the name that we parsed
        if not season:
            season = parse_result.season_number if parse_result.season_number != None else 1
        if not episodes:
            episodes = parse_result.episode_numbers

        # if we have an air-by-date show then get the real season/episode numbers
        if parse_result.air_by_date and tvdb_id:
            try:
                # There's gotta be a better way of doing this but we don't wanna
                # change the language value elsewhere
                ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

                if not (tvdb_lang == "" or tvdb_lang == "en"
                        or tvdb_lang == None):
                    ltvdb_api_parms['language'] = tvdb_lang

                t = tvdb_api.Tvdb(**ltvdb_api_parms)
                epObj = t[tvdb_id].airedOn(parse_result.air_date)[0]
                season = int(epObj["seasonnumber"])
                episodes = [int(epObj["episodenumber"])]
            except tvdb_exceptions.tvdb_episodenotfound:
                logger.log(
                    u"Unable to find episode with date " +
                    str(parse_result.air_date) + " for show " +
                    parse_result.series_name + ", skipping", logger.WARNING)
                return False
            except tvdb_exceptions.tvdb_error, e:
                logger.log(u"Unable to contact TVDB: " + ex(e), logger.WARNING)
                return False
Beispiel #19
0
    def series_name_to_tvdb_id(cls,
                               series_name,
                               check_scene_exceptions=True,
                               check_database=True,
                               check_tvdb=False):
        """
        Given a series name, return it's tvdbd_id.
        Returns None if not found.
        
        This is mostly robbed from postProcessor._analyze_name
        """

        # do a scene reverse-lookup to get a list of all possible names
        name_list = sickbeard.show_name_helpers.sceneToNormalShowNames(
            series_name)

        # for each possible interpretation of that scene name
        if check_scene_exceptions:
            for cur_name in name_list:
                logger.log(
                    u"Checking scene exceptions for a match on " + cur_name,
                    logger.DEBUG)
                scene_id = sickbeard.scene_exceptions.get_scene_exception_by_name(
                    cur_name)
                if scene_id: return scene_id

        # see if we can find the name directly in the DB, if so use it
        if check_database:
            for cur_name in name_list:
                logger.log(u"Looking up " + cur_name + u" in the DB",
                           logger.DEBUG)
                db_result = sickbeard.helpers.searchDBForShow(cur_name)
                if db_result: return db_result[0]

        # see if we can find the name with a TVDB lookup
        if check_tvdb:
            for cur_name in name_list:
                try:
                    t = tvdb_api.Tvdb(custom_ui=sickbeard.classes.ShowListUI,
                                      **sickbeard.TVDB_API_PARMS)

                    logger.log(u"Looking up name " + cur_name + u" on TVDB",
                               logger.DEBUG)
                    showObj = t[cur_name]
                except (tvdb_exceptions.tvdb_exception):
                    # if none found, search on all languages
                    try:
                        # There's gotta be a better way of doing this but we don't wanna
                        # change the language value elsewhere
                        ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

                        ltvdb_api_parms['search_all_languages'] = True
                        t = tvdb_api.Tvdb(
                            custom_ui=sickbeard.classes.ShowListUI,
                            **ltvdb_api_parms)

                        logger.log(
                            u"Looking up name " + cur_name +
                            u" in all languages on TVDB", logger.DEBUG)
                        showObj = t[cur_name]
                    except (tvdb_exceptions.tvdb_exception, IOError):
                        pass

                    continue
                except (IOError):
                    continue

                return showObj["id"]

        return None
Beispiel #20
0
 def test_tvdb_api(self):
     tvdb = tvdb_api.Tvdb()
     for (fileName, serie_name, season, episode_numbers) in TVShows:
         serie_info = tvdb[serie_name]
         season_info = tvdb[serie_name][season]
         episode_info = tvdb[serie_name][season][episode_numbers[0]]
Beispiel #21
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
        """

        tvdb_lang = show_obj.lang
        # There's gotta be a better way of doing this but we don't wanna
        # change the language value elsewhere
        ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

        if tvdb_lang and not tvdb_lang == 'en':
            ltvdb_api_parms['language'] = tvdb_lang

        t = tvdb_api.Tvdb(actors=True, **ltvdb_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.tvdbid)]
        except tvdb_exceptions.tvdb_shownotfound:
            logger.log(u"Unable to find show with id " + str(show_obj.tvdbid) + " on tvdb, skipping it", logger.ERROR)
            raise

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

        # 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.tvdbid) + " on tvdb, skipping it", logger.ERROR)
                return False
        except tvdb_exceptions.tvdb_attributenotfound:
            logger.log(u"Incomplete info for show with id " + str(show_obj.tvdbid) + " 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']

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

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

        cast = etree.SubElement(tv_node, "cast")

        if myShow["_actors"] != None:
            for actor in myShow['_actors']:
                cur_actor_name_text = actor['name']

                if cur_actor_name_text != None and cur_actor_name_text.strip():
                    cur_actor = etree.SubElement(cast, "actor")
                    cur_actor.text = cur_actor_name_text.strip()

        helpers.indentXML(rootNode)

        data = etree.ElementTree(rootNode)

        return data
Beispiel #22
0
    def _show_data(self, show_obj):
        """
        Creates an elementTree XML structure for an XBMC-style tvshow.nfo and
        returns the resulting data object.

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

        show_ID = show_obj.tvdbid

        tvdb_lang = show_obj.lang
        # There's gotta be a better way of doing this but we don't wanna
        # change the language value elsewhere
        ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

        if tvdb_lang and not tvdb_lang == 'en':
            ltvdb_api_parms['language'] = tvdb_lang

        t = tvdb_api.Tvdb(actors=True, **ltvdb_api_parms)

        tv_node = etree.Element("tvshow")

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

        except tvdb_exceptions.tvdb_error:
            logger.log(u"TVDB is down, can't use its data to add this show",
                       logger.ERROR)
            raise

        # 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_ID) +
                    " on tvdb, skipping it", logger.ERROR)

                return False
        except tvdb_exceptions.tvdb_attributenotfound:
            logger.log(
                u"Incomplete info for show with id " + str(show_ID) +
                " on tvdb, skipping it", logger.ERROR)

            return False

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

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

        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

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

        episodeguide = etree.SubElement(tv_node, "episodeguide")
        episodeguideurl = etree.SubElement(episodeguide, "url")
        episodeguideurl2 = etree.SubElement(tv_node, "episodeguideurl")
        if myShow["id"] != None:
            showurl = sickbeard.TVDB_BASE_URL + '/series/' + myShow[
                "id"] + '/all/en.zip'
            episodeguideurl.text = showurl
            episodeguideurl2.text = showurl

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

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

        genre = etree.SubElement(tv_node, "genre")
        if myShow["genre"] != None:
            genre.text = " / ".join([
                x.strip() for x in myShow["genre"].split('|')
                if x and x.strip()
            ])

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

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

        if myShow["_actors"] != None:
            for actor in myShow["_actors"]:
                cur_actor_name_text = actor['name']

                if cur_actor_name_text != None and cur_actor_name_text.strip():
                    cur_actor = etree.SubElement(tv_node, "actor")
                    cur_actor_name = etree.SubElement(cur_actor, "name")
                    cur_actor_name.text = cur_actor_name_text.strip()

                    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

                    cur_actor_thumb = etree.SubElement(cur_actor, "thumb")
                    cur_actor_thumb_text = actor['image']
                    if cur_actor_thumb_text != None:
                        cur_actor_thumb.text = cur_actor_thumb_text

        # Make it purdy
        helpers.indentXML(tv_node)

        data = etree.ElementTree(tv_node)

        return data
Beispiel #23
0
    def _analyze_name(self, name, file=True):
        """
        Takes a name and tries to figure out a show, season, and episode from it.
        
        name: A string which we want to analyze to determine show info from (unicode)
        
        Returns a (tvdb_id, season, [episodes]) tuple. The first two may be None and episodes may be []
        if none were found.
        """

        logger.log(u"Analyzing name " + repr(name))

        to_return = (None, None, [])

        if not name:
            return to_return

        trimprefix = [
            '^sof-', '^euhd-', '^amb-', '^itg-', '^idtv-', '^zzgtv-', '^itn-',
            '^tcpa-', '^tvp-'
        ]
        for regex in trimprefix:
            name = re.sub(regex, "", name)

        # parse the name to break it into show name, season, and episode
        np = NameParser(file)
        parse_result = np.parse(name)
        self._log(
            "Parsed " + name + " into " + str(parse_result).decode('utf-8'),
            logger.DEBUG)

        if parse_result.air_by_date:
            season = -1
            episodes = [parse_result.air_date]
        else:
            season = parse_result.season_number
            episodes = parse_result.episode_numbers

        to_return = (None, season, episodes)

        # do a scene reverse-lookup to get a list of all possible names
        name_list = show_name_helpers.sceneToNormalShowNames(
            parse_result.series_name)

        if not name_list:
            return (None, season, episodes)

        def _finalize(parse_result):
            self.release_group = parse_result.release_group
            if parse_result.extra_info:
                self.is_proper = re.search(
                    '(^|[\. _-])(proper|repack)([\. _-]|$)',
                    parse_result.extra_info, re.I) != None

        # for each possible interpretation of that scene name
        for cur_name in name_list:
            self._log(u"Checking scene exceptions for a match on " + cur_name,
                      logger.DEBUG)
            scene_id = scene_exceptions.get_scene_exception_by_name(cur_name)
            if scene_id:
                self._log(
                    u"Scene exception lookup got tvdb id " + str(scene_id) +
                    u", using that", logger.DEBUG)
                _finalize(parse_result)
                return (scene_id, season, episodes)

        # see if we can find the name directly in the DB, if so use it
        for cur_name in name_list:
            self._log(u"Looking up " + cur_name + u" in the DB", logger.DEBUG)
            db_result = helpers.searchDBForShow(cur_name)
            if db_result:
                self._log(
                    u"Lookup successful, using tvdb id " + str(db_result[0]),
                    logger.DEBUG)
                _finalize(parse_result)
                return (int(db_result[0]), season, episodes)

        # see if we can find the name with a TVDB lookup
        for cur_name in name_list:
            try:
                t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI,
                                  **sickbeard.TVDB_API_PARMS)

                self._log(u"Looking up name " + cur_name + u" on TVDB",
                          logger.DEBUG)
                showObj = t[cur_name]
            except (tvdb_exceptions.tvdb_exception):
                # if none found, search on all languages
                try:
                    # There's gotta be a better way of doing this but we don't wanna
                    # change the language value elsewhere
                    ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

                    ltvdb_api_parms['search_all_languages'] = True
                    t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI,
                                      **ltvdb_api_parms)

                    self._log(
                        u"Looking up name " + cur_name +
                        u" in all languages on TVDB", logger.DEBUG)
                    showObj = t[cur_name]
                except (tvdb_exceptions.tvdb_exception, IOError):
                    pass

                continue
            except (IOError):
                continue

            self._log(
                u"Lookup successful, using tvdb id " + str(showObj["id"]),
                logger.DEBUG)
            _finalize(parse_result)
            return (int(showObj["id"]), season, episodes)

        _finalize(parse_result)
        return to_return
Beispiel #24
0
    def _show_data(self, show_obj):
        """
        Creates an elementTree XML structure for a Mede8er-style Series.xml
        returns the resulting data object.
        
        show_obj: a TVShow instance to create the XML-NFO for
        """

        logger.log("Mede8er: Starting Mede8er _show_data method",
                   logger.MESSAGE)

        tvdb_lang = show_obj.lang
        # There's gotta be a better way of doing this but we don't wanna
        # change the language value elsewhere
        ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

        if tvdb_lang and not tvdb_lang == 'en':
            ltvdb_api_parms['language'] = tvdb_lang

        t = tvdb_api.Tvdb(actors=True, **ltvdb_api_parms)

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

        for ns in XML_NSMAP.keys():
            tv_node.set(ns, XML_NSMAP[ns])

        try:
            myShow = t[int(show_obj.tvdbid)]
        except tvdb_exceptions.tvdb_shownotfound:
            logger.log(
                "Mede8er: Unable to find show with id " +
                str(show_obj.tvdbid) + " on tvdb, skipping it", logger.ERROR)
            raise

        except tvdb_exceptions.tvdb_error:
            logger.log(
                "Mede8er: TVDB is down, can't use its data to make the XML-NFO",
                logger.ERROR)
            raise

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

            return False

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

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

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

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

        zap2id = etree.SubElement(tv_node, "zap2itid")
        if myShow["zap2it_id"] != None:
            zap2id.text = myShow["zap2it_id"]

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

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

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

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

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

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

        #tmpNode = etree.SubElement(tv_node, "myShow")
        #tmpNode.text = str(vars(myShow))
        #logger.log("Printing myShow info: " +  str(vars(myShow)), logger.MESSAGE)

        #Actors = etree.SubElement(tv_node, "Actors")
        #if myShow["actors"] != None:
        #    Actors.text = myShow["actors"]

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

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

        cast = etree.SubElement(tv_node, "cast")
        for actor in myShow['_actors']:
            cast_actor = etree.SubElement(cast, "actor")
            cast_actor.text = actor['name']

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

        cover = etree.SubElement(tv_node, "cover")
        poster = etree.SubElement(cover, "name")
        if myShow["poster"] != None:
            poster.text = myShow["poster"]

        backdrop = etree.SubElement(tv_node, "backdrop")
        fanart = etree.SubElement(backdrop, "name")
        if myShow["fanart"] != None:
            fanart.text = myShow["fanart"]

        helpers.indentXML(tv_node)

        data = etree.ElementTree(tv_node)

        return data
Beispiel #25
0
                elif season == -2:
                    self._log(
                        u"Looks like this is an anime with absolute numbering show, attempting to convert the absolute episode to season/episode",
                        logger.DEBUG)
                    ab_episodes = episodes
                    episodes = []
                    for episode in ab_episodes:
                        try:
                            # There's gotta be a better way of doing this but we don't wanna
                            # change the cache value elsewhere
                            ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

                            if tvdb_lang and not tvdb_lang == 'en':
                                ltvdb_api_parms['language'] = tvdb_lang

                            t = tvdb_api.Tvdb(**ltvdb_api_parms)

                            epObj = t[tvdb_id].absoluteNumber(episode)[0]
                            season = int(epObj["seasonnumber"])
                            episodes.append(int(epObj["episodenumber"]))
                        except tvdb_exceptions.tvdb_episodenotfound:
                            logger.log(
                                u"Unable to find episode with absolute number "
                                + str(episode) + " for show " + str(tvdb_id) +
                                ", skipping", logger.WARNING)
                            episodes = []
                            continue
                        except tvdb_exceptions.tvdb_error, e:
                            logger.log(u"Unable to contact TVDB: " + ex(e),
                                       logger.WARNING)
                            episodes = []
Beispiel #26
0
    def _analyze_name(self, name, file_name=True):
        """
        Takes a name and tries to figure out a show, season, and episode from it.

        name: A string which we want to analyze to determine show info from (unicode)

        Returns a (tvdb_id, season, [episodes], quality) tuple. tvdb_id, season, quality may be None and episodes may be [].
        if none were found.
        """

        logger.log(u"Analyzing name " + repr(name))

        to_return = (None, None, [], None)

        if not name:
            return to_return

        name = helpers.remove_non_release_groups(helpers.remove_extension(name))

        # parse the name to break it into show name, season, and episode
        np = NameParser(False)
        parse_result = np.parse(name)
        self._log(u"Parsed " + name + " into " + str(parse_result).decode('utf-8', 'xmlcharrefreplace'), logger.DEBUG)

        if parse_result.air_by_date:
            season = -1
            episodes = [parse_result.air_date]
        else:
            season = parse_result.season_number
            episodes = parse_result.episode_numbers

        to_return = (None, season, episodes, None)

        # do a scene reverse-lookup to get a list of all possible names
        name_list = show_name_helpers.sceneToNormalShowNames(parse_result.series_name)

        if not name_list:
            return (None, season, episodes, None)

        # try finding name in DB
        for cur_name in name_list:
            self._log(u"Looking up " + cur_name + u" in the DB", logger.DEBUG)
            db_result = helpers.searchDBForShow(cur_name)
            if db_result:
                self._log(u"Lookup successful, using tvdb id " + str(db_result[0]), logger.DEBUG)
                self._finalize(parse_result)
                return (int(db_result[0]), season, episodes, None)

        # try finding name in scene exceptions
        for cur_name in name_list:
            self._log(u"Checking scene exceptions for a match on " + cur_name, logger.DEBUG)
            scene_id = scene_exceptions.get_scene_exception_by_name(cur_name)
            if scene_id:
                self._log(u"Scene exception lookup got tvdb id " + str(scene_id) + u", using that", logger.DEBUG)
                self._finalize(parse_result)
                return (scene_id, season, episodes, None)

        # try finding name on TVDB
        for cur_name in name_list:
            try:
                t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI, **sickbeard.TVDB_API_PARMS)

                self._log(u"Looking up name " + cur_name + u" on TVDB", logger.DEBUG)
                showObj = t[cur_name]
            except (tvdb_exceptions.tvdb_exception):
                # if none found, search on all languages
                try:
                    # There's gotta be a better way of doing this but we don't wanna
                    # change the language value elsewhere
                    ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

                    ltvdb_api_parms['search_all_languages'] = True
                    t = tvdb_api.Tvdb(custom_ui=classes.ShowListUI, **ltvdb_api_parms)

                    self._log(u"Looking up name " + cur_name + u" in all languages on TVDB", logger.DEBUG)
                    showObj = t[cur_name]
                except (tvdb_exceptions.tvdb_exception, IOError):
                    pass

                continue
            except (IOError):
                continue

            self._log(u"Lookup successful, using tvdb id " + str(showObj["id"]), logger.DEBUG)
            self._finalize(parse_result)
            return (int(showObj["id"]), season, episodes, None)

        self._finalize(parse_result)
        return to_return
Beispiel #27
0
#  GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with pchtrakt.  If not, see <http://www.gnu.org/licenses/>.

from os.path import basename, isfile
from urllib import quote
from urllib2 import urlopen, HTTPError, URLError
import json
from lib import parser
from movieparser import *
from lib.tvdb_api import tvdb_exceptions
from pchtrakt.config import *
from lib.tvdb_api import tvdb_api, tvdb_exceptions

tvdb = tvdb_api.Tvdb()


class MediaParserResult():
    def __init__(self, file_name):
        self.file_name = file_name


class MediaParserResultTVShow(MediaParserResult):
    def __init__(self, file_name, name, season_number, episode_numbers):
        self.file_name = file_name
        self.name = name
        self.season_number = season_number
        self.episode_numbers = episode_numbers
        if self.name in cacheSerie.dictSerie:
            self.id = cacheSerie.dictSerie[self.name]['TvDbId']
Beispiel #28
0
    def _show_data(self, show_obj):
        """
        Creates an elementTree XML structure for a Synology-style series.xml
        returns the resulting data object.
        
        show_obj: a TVShow instance to create the NFO for
        """

        tvdb_lang = show_obj.lang
        # There's gotta be a better way of doing this but we don't wanna
        # change the language value elsewhere
        ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

        if tvdb_lang and not tvdb_lang == 'en':
            ltvdb_api_parms['language'] = tvdb_lang

        t = tvdb_api.Tvdb(actors=True, **ltvdb_api_parms)

        tv_node = etree.Element("Series")
        for ns in XML_NSMAP.keys():
            tv_node.set(ns, XML_NSMAP[ns])

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

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

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

            return False

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        helpers.indentXML(tv_node)

        data = etree.ElementTree(tv_node)

        return data
Beispiel #29
0
    def _addCacheEntry(self,
                       name,
                       url,
                       season=None,
                       episodes=None,
                       tvdb_id=0,
                       tvrage_id=0,
                       quality=None,
                       extraNames=[]):

        myDB = self._getDB()

        parse_result = None

        # if we don't have complete info then parse the filename to get it
        for curName in [name] + extraNames:
            try:
                myParser = NameParser()
                parse_result = myParser.parse(curName)
            except InvalidNameException:
                logger.log(
                    u"Unable to parse the filename " + curName +
                    " into a valid episode", logger.DEBUG)
                continue

        if not parse_result:
            logger.log(
                u"Giving up because I'm unable to parse this name: " + name,
                logger.DEBUG)
            return False

        if not parse_result.series_name:
            logger.log(
                u"No series name retrieved from " + name +
                ", unable to cache it", logger.DEBUG)
            return False

        # if we need tvdb_id or tvrage_id then search the DB for them
        if not tvdb_id or not tvrage_id:

            # if we have only the tvdb_id, use the database
            if tvdb_id:
                showObj = helpers.findCertainShow(sickbeard.showList, tvdb_id)
                if showObj:
                    tvrage_id = showObj.tvrid
                    tvdb_lang = showObj.lang
                else:
                    logger.log(
                        u"We were given a TVDB id " + str(tvdb_id) +
                        " but it doesn't match a show we have in our list, so leaving tvrage_id empty",
                        logger.DEBUG)
                    tvrage_id = 0

            # if we have only a tvrage_id then use the database
            elif tvrage_id:
                showObj = helpers.findCertainTVRageShow(
                    sickbeard.showList, tvrage_id)
                if showObj:
                    tvdb_id = showObj.tvdbid
                    tvdb_lang = showObj.lang
                else:
                    logger.log(
                        u"We were given a TVRage id " + str(tvrage_id) +
                        " but it doesn't match a show we have in our list, so leaving tvdb_id empty",
                        logger.DEBUG)
                    tvdb_id = 0

            # if they're both empty then fill out as much info as possible by searching the show name
            else:

                showResult = helpers.searchDBForShow(parse_result.series_name)
                if showResult:
                    logger.log(
                        parse_result.series_name + " was found to be show " +
                        showResult[1] + " (" + str(showResult[0]) +
                        ") in our DB.", logger.DEBUG)
                    tvdb_id = showResult[0]

                else:
                    logger.log(
                        u"Couldn't figure out a show name straight from the DB, trying a regex search instead",
                        logger.DEBUG)
                    for curShow in sickbeard.showList:
                        if sceneHelpers.isGoodResult(name, curShow, False):
                            logger.log(
                                u"Successfully matched " + name + " to " +
                                curShow.name + " with regex", logger.DEBUG)
                            tvdb_id = curShow.tvdbid
                            tvdb_lang = curShow.lang
                            break

                if tvdb_id:

                    showObj = helpers.findCertainShow(sickbeard.showList,
                                                      tvdb_id)
                    if not showObj:
                        logger.log(
                            u"This should never have happened, post a bug about this!",
                            logger.ERROR)
                        raise Exception("BAD STUFF HAPPENED")
                    tvrage_id = showObj.tvrid
                    tvdb_lang = showObj.lang

        if not season:
            season = parse_result.season_number if parse_result.season_number != None else 1
        if not episodes:
            episodes = parse_result.episode_numbers

        # if we have an air-by-date show then get the real season/episode numbers
        if parse_result.air_by_date and tvdb_id:
            try:
                # There's gotta be a better way of doing this but we don't wanna
                # change the language value elsewhere
                ltvdb_api_parms = sickbeard.TVDB_API_PARMS.copy()

                if not (tvdb_lang == "" or tvdb_lang == "en"
                        or tvdb_lang == None):
                    ltvdb_api_parms['language'] = tvdb_lang

                t = tvdb_api.Tvdb(**ltvdb_api_parms)
                epObj = t[tvdb_id].airedOn(parse_result.air_date)[0]
                season = int(epObj["seasonnumber"])
                episodes = [int(epObj["episodenumber"])]
            except tvdb_exceptions.tvdb_episodenotfound, e:
                logger.log(
                    u"Unable to find episode with date " +
                    str(parse_result.air_date) + " for show " +
                    parse_result.series_name + ", skipping", logger.WARNING)
                return False