Example #1
0
    def convert(self):
        if self.air_by_date: return self # scene numbering does not apply to air-by-date
        if self.season_number == None: return self  # can't work without a season
        if len(self.episode_numbers) == 0: return self  # need at least one episode

        self.show = helpers.get_show_by_name(self.series_name)
        if not self.show:
            return self

        new_episode_numbers = []
        new_season_numbers = []
        for epNo in self.episode_numbers:
            (s, e) = scene_numbering.get_indexer_numbering(self.show.indexerid, self.season_number, epNo)
            new_episode_numbers.append(e)
            new_season_numbers.append(s)

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

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

        self.episode_numbers = new_episode_numbers
        self.season_number = new_season_numbers[0]

        return self
Example #2
0
    def _addCacheEntry(self, name, url, quality=None):

        season = None
        episodes = None

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

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

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

        showObj = helpers.get_show_by_name(parse_result.series_name)
        if not showObj:
            logger.log(u"Could not find a show matching " + parse_result.series_name + " in the database, skipping ...", logger.DEBUG)
            return None

        if parse_result.air_by_date:
            myDB = db.DBConnection()

            airdate = parse_result.air_date.toordinal()
            sql_results = myDB.select("SELECT season, episode FROM tv_episodes WHERE showid = ? AND indexer = ? AND airdate = ?",
                                      [showObj.indexerid, showObj.indexer, airdate])
            if sql_results > 0:
                season = int(sql_results[0]["season"])
                episodes = [int(sql_results[0]["episode"])]
        else:
            season = parse_result.season_number
            episodes = parse_result.episode_numbers

        if season and episodes:
            # store episodes as a seperated string
            episodeText = "|" + "|".join(map(str, episodes)) + "|"

            # get the current timestamp
            curTimestamp = int(time.mktime(datetime.datetime.today().timetuple()))

            # get quality of release
            if quality is None:
                quality = Quality.sceneQuality(name)

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


            logger.log(u"Added RSS item: [" + name + "] to cache: [" + self.providerID + "]", logger.DEBUG)
            return ["INSERT INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality) VALUES (?,?,?,?,?,?,?)",
                [name, season, episodeText, showObj.indexerid, url, curTimestamp, quality]]
 def test(self):
     show = TVShow(tvdb_id)
     show.name = data[0]
     if data[1]:
         show.anime = 1
     show.saveToDB()
     showList = [show]
     sceneName = data[2]
     result = helpers.get_show_by_name(sceneName, showList, False)
     if not result:
         self.assertEqual(False, show.tvdbid)
         return False
     self.assertEqual(result.tvdbid, show.tvdbid)
Example #4
0
 def test(self):
     show = TVShow(tvdb_id)
     show.name = data[0]
     if data[1]:
         show.anime = 1
     show.saveToDB()
     showList = [show]
     sceneName = data[2]
     result = helpers.get_show_by_name(sceneName, showList, False)
     if not result:
         self.assertEqual(False, show.tvdbid)
         return False
     self.assertEqual(result.tvdbid, show.tvdbid)
Example #5
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 (indexer_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))

        indexer_id = None
        indexer = None

        to_return = (indexer_id, indexer, 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(
            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]
        elif parse_result.sports:
            season = -1
            episodes = [parse_result.sports_event_date]
        else:
            season = parse_result.season_number
            episodes = parse_result.episode_numbers

        showObj = helpers.get_show_by_name(parse_result.series_name)
        if showObj:
            indexer_id = showObj.indexerid
            indexer = showObj.indexer

        to_return = (indexer_id, indexer, season, episodes, None)

        self._finalize(parse_result)
        return to_return
Example #6
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 (indexer_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))

        indexer_id = None
        indexer = None

        to_return = (indexer_id, indexer, 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(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]
        elif parse_result.sports:
            season = -1
            episodes = [parse_result.sports_event_date]
        else:
            season = parse_result.season_number
            episodes = parse_result.episode_numbers

        showObj = helpers.get_show_by_name(parse_result.series_name)
        if showObj:
            indexer_id = showObj.indexerid
            indexer = showObj.indexer

        to_return = (indexer_id, indexer, season, episodes, None)

        self._finalize(parse_result)
        return to_return
    def _get_show_id(self, series_name):
        """Find and return show ID by searching exceptions, then DB"""

        show_names = show_name_helpers.sceneToNormalShowNames(series_name)

        logger.log(u"show_names: " + str(show_names), logger.DEBUG)

        for show_name in show_names:
            exception = scene_exceptions.get_scene_exception_by_name(show_name)
            if exception is not None:
                return exception

        for show_name in show_names:
            found_info = helpers.get_show_by_name(show_name)
            if found_info is not None:
                return (found_info.indexerid)

        return None
    def _get_show_id(self, series_name):
        """Find and return show ID by searching exceptions, then DB"""

        show_names = show_name_helpers.sceneToNormalShowNames(series_name)

        logger.log(u"show_names: " + str(show_names), logger.DEBUG)

        for show_name in show_names:
            exception = scene_exceptions.get_scene_exception_by_name(show_name)
            if exception is not None:
                return exception

        for show_name in show_names:
            found_info = helpers.get_show_by_name(show_name)
            if found_info is not None:
                return found_info.indexerid

        return None
Example #9
0
    def convert(self):
        if self.air_by_date:
            return self  # scene numbering does not apply to air-by-date
        if self.season_number == None:
            return self  # can't work without a season
        if len(self.episode_numbers) == 0:
            return self  # need at least one episode

        # convert scene numbered releases before storing to cache
        showObj = helpers.get_show_by_name(self.series_name)
        if showObj:
            self.show = showObj

            new_episode_numbers = []
            new_season_numbers = []
            for epNo in self.episode_numbers:
                (s, e) = scene_numbering.get_indexer_numbering(
                    showObj.indexerid, self.season_number, epNo)
                new_episode_numbers.append(e)
                new_season_numbers.append(s)

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

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

            self.episode_numbers = new_episode_numbers
            self.season_number = new_season_numbers[0]

        return self
Example #10
0
    def test_parsing_scene_release(self):
        self.loadFromDB()

        # parse the file name
        scene_parsse_results1 = ''
        scene_parsse_results2 = ''
        scene_release = 'Pawn Stars S08E41 Field Trip HDTV x264-tNe'
        try:
            myParser = NameParser(False, 1)
            scene_parsse_results1 = myParser.parse(scene_release)
            scene_parsse_results2 = myParser.parse(scene_release).convert()
        except InvalidNameException:
            print(u"Unable to parse the filename " + scene_release + " into a valid episode")

        print scene_parsse_results1
        print scene_parsse_results2

        sports_release = 'UFC.168.Weidman.vs.Silva.II.28th.Dec.2013.HDTV.x264-Sir.Paul'
        try:
            myParser = NameParser(False, 2)
            parse_result = myParser.parse(sports_release)

            test = sickbeard.show_name_helpers.allPossibleShowNames(parse_result.series_name)
            show = get_show_by_name(parse_result.series_name)
            if show:
                sql_results = test.db.DBConnection().select(
                    "SELECT season, episode FROM tv_episodes WHERE showid = ? AND airdate = ?",
                    [show.indexerid, parse_result.sports_event_date.toordinal()])

                actual_season = int(sql_results[0]["season"])
                actual_episodes = [int(sql_results[0]["episode"])]

                print actual_season
                print actual_episodes
        except InvalidNameException:
            print(u"Unable to parse the filename " + scene_release + " into a valid episode")

        print scene_parsse_results1
    def _parse_string(self, name):

        if not name:
            return None

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

            if not match:
                continue

            result = ParseResult(name)
            result.which_regex = [cur_regex_name]

            named_groups = match.groupdict().keys()

            if 'series_name' in named_groups:
                result.series_name = match.group('series_name')
                if result.series_name:
                    result.series_name = self.clean_series_name(result.series_name)
                    name_list = sickbeard.show_name_helpers.sceneToNormalShowNames(result.series_name)
                    for name in name_list:
                        result.show = helpers.get_show_by_name(name)
                        if result.show:
                            break

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

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

            if 'sports_event_id' in named_groups:
                sports_event_id = match.group('sports_event_id')
                if sports_event_id:
                    result.sports_event_id = int(match.group('sports_event_id'))

            if 'sports_event_name' in named_groups:
                result.sports_event_name = match.group('sports_event_name')
                if result.sports_event_name:
                    result.sports_event_name = self.clean_series_name(result.sports_event_name)

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

            if 'air_year' in named_groups and 'air_month' in named_groups and 'air_day' in named_groups:
                year = int(match.group('air_year'))
                month = int(match.group('air_month'))
                day = int(match.group('air_day'))

                try:
                    dtStr = '%s-%s-%s' % (year, month, day)
                    result.air_date = datetime.datetime.strptime(dtStr, "%Y-%m-%d").date()
                except:
                    continue

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

                # Show.S04.Special is almost certainly not every episode in the season
                if tmp_extra_info and cur_regex_name == 'season_only' and re.match(
                        r'([. _-]|^)(special|extra)\w*([. _-]|$)', tmp_extra_info, re.I):
                    continue
                result.extra_info = tmp_extra_info

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

            return result

        return None
Example #12
0
    def _parse_string(self, name):

        if not name:
            return None

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

            if not match:
                continue

            result = ParseResult(name)
            result.which_regex = [cur_regex_name]

            named_groups = match.groupdict().keys()

            if 'series_name' in named_groups:
                result.series_name = match.group('series_name')
                if result.series_name:
                    result.series_name = self.clean_series_name(
                        result.series_name)
                    name_list = sickbeard.show_name_helpers.sceneToNormalShowNames(
                        result.series_name)
                    for name in name_list:
                        result.show = helpers.get_show_by_name(name)
                        if result.show:
                            break

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

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

            if 'sports_event_id' in named_groups:
                sports_event_id = match.group('sports_event_id')
                if sports_event_id:
                    result.sports_event_id = int(
                        match.group('sports_event_id'))

            if 'sports_event_name' in named_groups:
                result.sports_event_name = match.group('sports_event_name')
                if result.sports_event_name:
                    result.sports_event_name = self.clean_series_name(
                        result.sports_event_name)

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

            if 'air_year' in named_groups and 'air_month' in named_groups and 'air_day' in named_groups:
                year = int(match.group('air_year'))
                month = int(match.group('air_month'))
                day = int(match.group('air_day'))

                try:
                    dtStr = '%s-%s-%s' % (year, month, day)
                    result.air_date = datetime.datetime.strptime(
                        dtStr, "%Y-%m-%d").date()
                except:
                    continue

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

                # Show.S04.Special is almost certainly not every episode in the season
                if tmp_extra_info and cur_regex_name == 'season_only' and re.match(
                        r'([. _-]|^)(special|extra)\w*([. _-]|$)',
                        tmp_extra_info, re.I):
                    continue
                result.extra_info = tmp_extra_info

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

            return result

        return None
Example #13
0
                        cur_pattern_name = str(i) + "_" + cur_pattern_name
                        self.compiled_regexes[(regex_type, cur_pattern_name)] = cur_regex

    def _matchShowName(self, name, pattern):
        try:
            show_regex = re.compile(pattern, re.VERBOSE | re.IGNORECASE)
        except re.error, errormsg:
            logger.log(u"WARNING: Invalid show series name pattern, %s: [%s]" % (errormsg, pattern))
        else:
            # attempt matching with main show name pattern
            seriesname_match = show_regex.match(name)
            if seriesname_match:
                seriesname_groups = seriesname_match.groupdict().keys()
                if 'series_name' in seriesname_groups:
                    series_name = self.clean_series_name(seriesname_match.group('series_name'))
                    return helpers.get_show_by_name(series_name, useIndexer=self.useIndexers)

    def _parse_string(self, name):
        if not name:
            return

        if not self.showObj and not self.naming_pattern:
            # Regex pattern to return the Show / Series Name regardless of the file pattern tossed at it, matched 53 show name examples from regexes.py
            show_pattern = '''(?:(?:\[.*?\])|(?:\d{3}[\.-]))*[ _\.]?(?P<series_name>.*?(?:[ ._-]((?!\d{4}\W\d\d\W\d\d\W)\d{4}))?)(?:(?:(?:[ ._-]+\d+)|(?:[ ._-]+s\d{2}))|(?:\W+(?:(?:S\d[\dE._ -])|(?:\d\d?x)|(?:\d{4}\W\d\d\W\d\d)|(?:(?:part|pt)[\._ -]?(?:\d|[ivx]))|Season\W+\d+\W+|E\d+\W+|(?:\d{1,3}.+\d{1,}[a-zA-Z]{2}\W+[a-zA-Z]{3,}\W+\d{4}.+))))'''
            show_pattern_alt = '''^(?P<series_name>.*?(?:[ ._-]((?!\d{4}\W\d\d\W\d\d\W)\d{4}))?)(?:(?:(?:[ ._-]+\d+)|(?:[ ._-]+s\d{2}))|(?:\W+(?:(?:S\d[\dE._ -])|(?:\d\d?x)|(?:\d{4}\W\d\d\W\d\d)|(?:(?:part|pt)[\._ -]?(?:\d|[ivx]))|Season\W+\d+\W+|E\d+\W+|(?:\d{1,3}.+\d{1,}[a-zA-Z]{2}\W+[a-zA-Z]{3,}\W+\d{4}.+))))'''

            self.showObj = self._matchShowName(name, show_pattern)
            if not self.showObj:
                self.showObj = self._matchShowName(name, show_pattern_alt)

            if not self.showObj:
Example #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 (indexer_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).convert()

        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(
                    u"Parse result not sufficient(all following 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:
            showObj = helpers.get_show_by_name(cur_name)
            if showObj:
                _finalize(parse_result)
                return (showObj.indexerid, season, episodes)

        _finalize(parse_result)
        return to_return
        ep = self._build_anidb_episode(sickbeard.ADBA_CONNECTION, filePath)
        try:
            self._log(u"Trying to lookup " + str(filePath) + " on anidb", logger.MESSAGE)
            ep.load_data()
        except Exception, e:
            self._log(u"exception msg: " + str(e))
            raise InvalidNameException
        else:
            self.anidbEpisode = ep

        #TODO: clean code. it looks like it's from hell
        for name in ep.allNames:

            indexer_id = name_cache.retrieveNameFromCache(name)
            if not indexer_id:
                show = helpers.get_show_by_name(name)
                if show:
                    indexer_id = show.indexerid
                else:
                    indexer_id = 0

                if indexer_id:
                    name_cache.addNameToCache(name, indexer_id)
            if indexer_id:
                try:
                    show = helpers.findCertainShow(sickbeard.showList, indexer_id)
                    (season, episodes) = helpers.get_all_episodes_from_absolute_number(show, None, [ep.epno])
                except exceptions.EpisodeNotFoundByAbsoluteNumberException:
                    self._log(str(indexer_id) + ": Indexer object absolute number " + str(
                        ep.epno) + " is incomplete, skipping this episode")
                else:
Example #16
0
    def _parse_string(self, name):
        if not name:
            return

        matches = []
        result = None
        for (cur_regex_type, cur_regex_name), cur_regex in self.compiled_regexes.items():
            match = cur_regex.match(name)

            if not match:
                continue

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

            named_groups = match.groupdict().keys()

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

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

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

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

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

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

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

            if 'air_year' in named_groups and 'air_month' in named_groups and 'air_day' in named_groups:
                year = int(match.group('air_year'))
                month = int(match.group('air_month'))
                day = int(match.group('air_day'))

                try:
                    dtStr = '%s-%s-%s' % (year, month, day)
                    result.air_date = datetime.datetime.strptime(dtStr, "%Y-%m-%d").date()
                    result.score += 1
                except:
                    pass

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

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

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

            cur_show = helpers.get_show_by_name(result.series_name, useIndexer=self.useIndexers)
            if not cur_show:
                if self.showObj:
                    if self.showObj.air_by_date and result.air_date:
                        result.score += 1
                    elif self.showObj.sports and result.sports_event_date:
                        result.score += 1
                    elif self.showObj.anime and len(result.ab_episode_numbers):
                        result.score += 1

                matches.append(result)
                continue

            if self.showObj and self.showObj.indexerid != cur_show.indexerid:
                logger.log(
                    u"I expected an episode of the show " + self.showObj.name + " but the parser thinks its the show " + cur_show.name + ". I will continue thinking its " + self.showObj.name,
                    logger.WARNING)
                continue

            result.show = cur_show

            if self.convert:
                result = result.convert()

            result.score += 1
            matches.append(result)

        if len(matches):
            result = max(matches, key=lambda x: x.score)

            # get quality
            if result.show:
                result.quality = common.Quality.nameQuality(name, bool(result.show and result.show.is_anime))

        return result
Example #17
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 (indexer_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).convert()

        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(u"Parse result not sufficient(all following 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:
            showObj = helpers.get_show_by_name(cur_name)
            if showObj:
                _finalize(parse_result)
                return (showObj.indexerid, season, episodes)

        _finalize(parse_result)
        return to_return
        try:
            self._log(u"Trying to lookup " + str(filePath) + " on anidb",
                      logger.MESSAGE)
            ep.load_data()
        except Exception, e:
            self._log(u"exception msg: " + str(e))
            raise InvalidNameException
        else:
            self.anidbEpisode = ep

        #TODO: clean code. it looks like it's from hell
        for name in ep.allNames:

            tvdb_id = name_cache.retrieveNameFromCache(name)
            if not tvdb_id:
                show = helpers.get_show_by_name(name, sickbeard.showList, True)
                if show:
                    tvdb_id = show.tvdbid
                else:
                    tvdb_id = 0

                if tvdb_id:
                    name_cache.addNameToCache(name, tvdb_id)
            if tvdb_id:
                try:
                    show = helpers.findCertainShow(sickbeard.showList, tvdb_id)
                    (season,
                     episodes) = helpers.get_all_episodes_from_absolute_number(
                         show, None, [ep.epno])
                except exceptions.EpisodeNotFoundByAbsoluteNumerException:
                    self._log(
Example #19
0
    def _parse_string(self, name):
        if not name:
            return

        matches = []
        result = None
        for (cur_regex_type, cur_regex_name), cur_regex in self.compiled_regexes.items():
            match = cur_regex.match(name)

            if not match:
                continue

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

            named_groups = match.groupdict().keys()

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

                    if not self.showObj and not self.naming_pattern:
                        self.showObj = helpers.get_show_by_name(result.series_name, useIndexer=self.useIndexers)

                    if self.showObj:
                        result.show = self.showObj
                        if getattr(self.showObj, 'air_by_date', None) and not cur_regex_type == 'normal':
                            continue
                        elif getattr(self.showObj, 'sports', None) and not cur_regex_type == 'sports':
                            continue
                        elif getattr(self.showObj, 'anime', None) and not cur_regex_type == 'anime':
                            continue

            # don't continue parsing if we don't have a show object by now, try next regex pattern
            if not self.showObj and not self.naming_pattern:
                continue

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

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

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

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

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

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

            if 'air_year' in named_groups and 'air_month' in named_groups and 'air_day' in named_groups:
                year = int(match.group('air_year'))
                month = int(match.group('air_month'))
                day = int(match.group('air_day'))

                try:
                    dtStr = '%s-%s-%s' % (year, month, day)
                    result.air_date = datetime.datetime.strptime(dtStr, "%Y-%m-%d").date()
                    result.score += 1
                except:
                    pass

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

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

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

            if getattr(self.showObj, 'air_by_date', None) and result.air_date:
                result.score += 1
            elif getattr(self.showObj, 'sports', None) and result.sports_event_date:
                result.score += 1
            elif getattr(self.showObj, 'anime', None) and len(result.ab_episode_numbers):
                result.score += 1

            result.score += 1
            matches.append(result)

        if len(matches):
            result = max(matches, key=lambda x: x.score)

            if result.show:
                if self.convert:
                    # scene convert result
                    result = result.convert()

                # get quality
                result.quality = common.Quality.nameQuality(name, bool(result.show and result.show.is_anime))

        return result
        ep = self._build_anidb_episode(sickbeard.ADBA_CONNECTION,filePath)
        try:
            self._log(u"Trying to lookup "+str(filePath)+" on anidb", logger.MESSAGE)        
            ep.load_data()
        except Exception,e :
            self._log(u"exception msg: "+str(e))
            raise InvalidNameException
        else:
            self.anidbEpisode = ep
        
        #TODO: clean code. it looks like it's from hell
        for name in ep.allNames:
            
            tvdb_id = name_cache.retrieveNameFromCache(name)
            if not tvdb_id:
                show = helpers.get_show_by_name(name, sickbeard.showList, True)
                if show:
                    tvdb_id = show.tvdbid
                else:
                    tvdb_id = 0

                if tvdb_id:
                    name_cache.addNameToCache(name, tvdb_id)
            if tvdb_id:
                try:
                    show = helpers.findCertainShow(sickbeard.showList, tvdb_id)
                    (season, episodes) = helpers.get_all_episodes_from_absolute_number(show, None, [ep.epno])
                except exceptions.EpisodeNotFoundByAbsoluteNumerException:
                    self._log(str(tvdb_id) + ": TVDB object absolute number " + str(ep.epno) + " is incomplete, skipping this episode")
                else:
                    if len(episodes):
Example #21
0
    def _parse_string(self, name):
        if not name:
            return

        matches = []
        result = None
        for (cur_regex_type,
             cur_regex_name), cur_regex in self.compiled_regexes.items():
            match = cur_regex.match(name)

            if not match:
                continue

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

            named_groups = match.groupdict().keys()

            if 'series_name' in named_groups:
                result.series_name = match.group('series_name')
                if not result.series_name:
                    continue

                result.series_name = self.clean_series_name(result.series_name)
                result.score += 1

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

                result.season_number = tmp_season
                result.score += 1

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

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

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

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

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

            if 'air_year' in named_groups and 'air_month' in named_groups and 'air_day' in named_groups:
                year = int(match.group('air_year'))
                month = int(match.group('air_month'))
                day = int(match.group('air_day'))

                try:
                    dtStr = '%s-%s-%s' % (year, month, day)
                    result.air_date = datetime.datetime.strptime(
                        dtStr, "%Y-%m-%d").date()
                    result.score += 1
                except:
                    continue

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

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

                result.extra_info = tmp_extra_info
                result.score += 1

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

            cur_show = helpers.get_show_by_name(result.series_name,
                                                useIndexer=self.useIndexers)
            if not cur_show:
                matches.append(result)
                continue

            if self.showObj and self.showObj.indexerid != cur_show.indexerid:
                logger.log(
                    u"I expected an episode of the show " + self.showObj.name +
                    " but the parser thinks its the show " + cur_show.name +
                    ". I will continue thinking its " + self.showObj.name,
                    logger.WARNING)
                continue

            result.show = cur_show

            if self.convert:
                result = result.convert()

            result.score += 1
            matches.append(result)

        if len(matches):
            result = max(matches, key=lambda x: x.score)

        return result
Example #22
0
        ep = self._build_anidb_episode(sickbeard.ADBA_CONNECTION, filePath)
        try:
            self._log(u"Trying to lookup " + str(filePath) + " on anidb", logger.MESSAGE)
            ep.load_data()
        except Exception, e:
            self._log(u"exception msg: " + str(e))
            raise InvalidNameException
        else:
            self.anidbEpisode = ep

        #TODO: clean code. it looks like it's from hell
        for name in ep.allNames:

            indexer_id = name_cache.retrieveNameFromCache(name)
            if not indexer_id:
                show = helpers.get_show_by_name(name)
                if show:
                    indexer_id = show.indexerid
                else:
                    indexer_id = 0

                if indexer_id:
                    name_cache.addNameToCache(name, indexer_id)
            if indexer_id:
                try:
                    show = helpers.findCertainShow(sickbeard.showList, indexer_id)
                    (season, episodes) = helpers.get_all_episodes_from_absolute_number(show, None, [ep.epno])
                except exceptions.EpisodeNotFoundByAbsoluteNumberException:
                    self._log(str(indexer_id) + ": Indexer object absolute number " + str(
                        ep.epno) + " is incomplete, skipping this episode")
                else: