Exemple #1
0
class Matcher(MatcherBase):

    def __init__(self):
        super(Matcher, self).__init__()

        self.caper = Caper()

        addEvent('matcher.parse', self.parse)
        addEvent('matcher.match', self.match)

        addEvent('matcher.flatten_info', self.flattenInfo)
        addEvent('matcher.construct_from_raw', self.constructFromRaw)

        addEvent('matcher.correct_title', self.correctTitle)
        addEvent('matcher.correct_quality', self.correctQuality)

    def parse(self, name, parser='scene'):
        return self.caper.parse(name, parser)

    def match(self, release, media, quality):
        match = fireEvent('matcher.parse', release['name'], single = True)

        if len(match.chains) < 1:
            log.info2('Wrong: %s, unable to parse release name (no chains)', release['name'])
            return False

        for chain in match.chains:
            if fireEvent('%s.matcher.correct' % media['type'], chain, release, media, quality, single = True):
                return chain

        return False

    def correctTitle(self, chain, media):
        root_library = media['library']['root_library']

        if 'show_name' not in chain.info or not len(chain.info['show_name']):
            log.info('Wrong: missing show name in parsed result')
            return False

        # Get the lower-case parsed show name from the chain
        chain_words = [x.lower() for x in chain.info['show_name']]

        # Build a list of possible titles of the media we are searching for
        titles = root_library['info']['titles']

        # Add year suffix titles (will result in ['<name_one>', '<name_one> <suffix_one>', '<name_two>', ...])
        suffixes = [None, root_library['info']['year']]

        titles = [
            title + ((' %s' % suffix) if suffix else '')
            for title in titles
            for suffix in suffixes
        ]

        # Check show titles match
        # TODO check xem names
        for title in titles:
            for valid_words in [x.split(' ') for x in possibleTitles(title)]:

                if valid_words == chain_words:
                    return True

        return False

    def correctQuality(self, chain, quality, quality_map):
        if quality['identifier'] not in quality_map:
            log.info2('Wrong: unknown preferred quality %s', quality['identifier'])
            return False

        if 'video' not in chain.info:
            log.info2('Wrong: no video tags found')
            return False

        video_tags = quality_map[quality['identifier']]

        if not self.chainMatch(chain, 'video', video_tags):
            log.info2('Wrong: %s tags not in chain', video_tags)
            return False

        return True
Exemple #2
0
class CaperTests(object):
    def __init__(self, debug):
        self.caper = Caper(debug=debug)

        self.name_col = None
        self.test_names = None

    def _read_header(self, reader):
        header = next(reader)

        for i, col in enumerate(header):
            if col == 'name':
                self.name_col = i

        if self.name_col is None:
            raise Exception()

    def load(self, filename, limit=100):
        if not os.path.isfile(filename):
            raise Exception()

        with open(filename) as fp:
            reader = csv.reader(fp, escapechar='|')

            self._read_header(reader)

            self.test_names = []
            for i, row in enumerate(reader):
                if not len(row) or row[0].startswith('#'):
                    continue

                self.test_names.append(row[self.name_col])

                if len(self.test_names) >= limit:
                    break

        print "loaded %s names for testing" % len(self.test_names)

    def run(self, parser_type, arguments):
        max_num_length = len(str(len(self.test_names)))
        row_format = '[%%0%dd] %%s' % max_num_length

        start = arguments['start'] or raw_input('Start position: ')
        if start.strip() != '':
            start = int(start)
        else:
            start = 0

        for i, name in enumerate(self.test_names):
            if i < start - 1:
                continue

            print row_format % (i + 1, name)

            result = self.caper.parse(name, parser_type)

            if arguments['print'] and result and result.chains:
                print "------------------------------------------------------------------------"

                for chain in result.chains:
                    print "Chain [%s]: %s" % (chain.weight, chain.info)

                print "------------------------------------------------------------------------"

            if arguments['pause']:
                print "Press ENTER to continue testing"
                try:
                    raw_input()
                except EOFError:
                    return
Exemple #3
0
class Matcher(MatcherBase):
    def __init__(self):
        super(Matcher, self).__init__()

        self.caper = Caper()

        addEvent('matcher.parse', self.parse)
        addEvent('matcher.match', self.match)

        addEvent('matcher.flatten_info', self.flattenInfo)
        addEvent('matcher.construct_from_raw', self.constructFromRaw)

        addEvent('matcher.correct_title', self.correctTitle)
        addEvent('matcher.correct_quality', self.correctQuality)

    def parse(self, name, parser='scene'):
        return self.caper.parse(name, parser)

    def match(self, release, media, quality):
        match = fireEvent('matcher.parse', release['name'], single=True)

        if len(match.chains) < 1:
            log.info2('Wrong: %s, unable to parse release name (no chains)',
                      release['name'])
            return False

        for chain in match.chains:
            if fireEvent('%s.matcher.correct' % media['type'],
                         chain,
                         release,
                         media,
                         quality,
                         single=True):
                return chain

        return False

    def correctTitle(self, chain, media):
        root = fireEvent('library.root', media, single=True)

        if 'show_name' not in chain.info or not len(chain.info['show_name']):
            log.info('Wrong: missing show name in parsed result')
            return False

        # Get the lower-case parsed show name from the chain
        chain_words = [x.lower() for x in chain.info['show_name']]

        # Build a list of possible titles of the media we are searching for
        titles = root['info']['titles']

        # Add year suffix titles (will result in ['<name_one>', '<name_one> <suffix_one>', '<name_two>', ...])
        suffixes = [None, root['info']['year']]

        titles = [
            title + ((' %s' % suffix) if suffix else '') for title in titles
            for suffix in suffixes
        ]

        # Check show titles match
        # TODO check xem names
        for title in titles:
            for valid_words in [x.split(' ') for x in possibleTitles(title)]:

                if valid_words == chain_words:
                    return True

        return False

    def correctQuality(self, chain, quality, quality_map):
        if quality['identifier'] not in quality_map:
            log.info2('Wrong: unknown preferred quality %s',
                      quality['identifier'])
            return False

        if 'video' not in chain.info:
            log.info2('Wrong: no video tags found')
            return False

        video_tags = quality_map[quality['identifier']]

        if not self.chainMatch(chain, 'video', video_tags):
            log.info2('Wrong: %s tags not in chain', video_tags)
            return False

        return True