Example #1
0
class CountValidator(Rule):
    """
    Validate count property and rename it
    """
    priority = 64
    consequence = [
        RemoveMatch,
        RenameMatch('episode_count'),
        RenameMatch('season_count')
    ]

    properties = {'episode_count': [None], 'season_count': [None]}

    def when(self, matches, context):
        to_remove = []
        episode_count = []
        season_count = []

        for count in matches.named('count'):
            previous = matches.previous(
                count, lambda match: match.name in ['episode', 'season'], 0)
            if previous:
                if previous.name == 'episode':
                    episode_count.append(count)
                elif previous.name == 'season':
                    season_count.append(count)
            else:
                to_remove.append(count)
        if to_remove or episode_count or season_count:
            return to_remove, episode_count, season_count
        return False
Example #2
0
class RenameToDiscMatch(Rule):
    """
    Rename episodes detected with `d` episodeMarkers to `disc`.
    """

    consequence = [RenameMatch('disc'), RenameMatch('discMarker'), RemoveMatch]

    def when(self, matches, context):
        discs = []
        markers = []
        to_remove = []

        disc_disabled = is_disabled(context, 'disc')

        for marker in matches.named(
                'episodeMarker', predicate=lambda m: m.value.lower() == 'd'):
            if disc_disabled:
                to_remove.append(marker)
                to_remove.extend(marker.initiator.children)
                continue

            markers.append(marker)
            discs.extend(
                sorted(marker.initiator.children.named('episode'),
                       key=lambda m: m.value))

        if discs or markers or to_remove:
            return discs, markers, to_remove
        return False
Example #3
0
class SubtitleExtensionRule(Rule):
    """
    Convert language guess as subtitle_language if next match is a subtitle extension.

    Since it's a strong match, it also removes any conflicting source with it.
    """
    consequence = [RemoveMatch, RenameMatch('subtitle_language')]

    properties = {'subtitle_language': [None]}

    def enabled(self, context):
        return not is_disabled(context, 'subtitle_language')

    def when(self, matches, context):  # pylint:disable=inconsistent-return-statements
        subtitle_extension = matches.named(
            'container', lambda match: 'extension' in match.tags and 'subtitle'
            in match.tags, 0)
        if subtitle_extension:
            subtitle_lang = matches.previous(
                subtitle_extension, lambda match: match.name == 'language', 0)
            if subtitle_lang:
                for weak in matches.named(
                        'subtitle_language',
                        predicate=lambda m: 'weak-language' in m.tags):
                    weak.private = True

                return matches.conflicting(
                    subtitle_lang, lambda m: m.name == 'source'), subtitle_lang
Example #4
0
class RenameToAbsoluteEpisode(Rule):
    """
    Rename episode to absolute_episodes.

    Absolute episodes are only used if two groups of episodes are detected:
        S02E04-06 25-27
        25-27 S02E04-06
        2x04-06  25-27
        28. Anime Name S02E05
    The matches in the group with higher episode values are renamed to absolute_episode.
    """

    consequence = RenameMatch('absolute_episode')

    def when(self, matches, context):  # pylint:disable=inconsistent-return-statements
        initiators = {match.initiator for match in matches.named('episode')
                      if len(match.initiator.children.named('episode')) > 1}
        if len(initiators) != 2:
            ret = []
            for filepart in matches.markers.named('path'):
                if matches.range(filepart.start + 1, filepart.end, predicate=lambda m: m.name == 'episode'):
                    ret.extend(
                        matches.starting(filepart.start, predicate=lambda m: m.initiator.name == 'weak_episode'))
            return ret

        initiators = sorted(initiators, key=lambda item: item.end)
        if not matches.holes(initiators[0].end, initiators[1].start, predicate=lambda m: m.raw.strip(seps)):
            first_range = matches.named('episode', predicate=lambda m: m.initiator == initiators[0])
            second_range = matches.named('episode', predicate=lambda m: m.initiator == initiators[1])
            if len(first_range) == len(second_range):
                if second_range[0].value > first_range[0].value:
                    return second_range
                if first_range[0].value > second_range[0].value:
                    return first_range
Example #5
0
class RenameAnotherToOther(Rule):
    """
    Rename `another` properties to `other`
    """
    priority = 32
    consequence = RenameMatch('other')

    def when(self, matches, context):
        return matches.named('another')
Example #6
0
class SubtitleExtensionRule(Rule):
    """
    Convert language guess as subtitle_language if next match is a subtitle extension
    """
    consequence = RenameMatch('subtitle_language')

    properties = {'subtitle_language': [None]}

    def when(self, matches, context):
        subtitle_extension = matches.named('container',
                                           lambda match: 'extension' in match.tags and 'subtitle' in match.tags,
                                           0)
        if subtitle_extension:
            subtitle_lang = matches.previous(subtitle_extension, lambda match: match.name == 'language', 0)
            if subtitle_lang:
                return subtitle_lang
Example #7
0
class SubtitleExtensionRule(Rule):
    """
    Convert language guess as subtitle_language if next match is a subtitle extension.

    Since it's a strong match, it also removes any conflicting source with it.
    """
    consequence = [RemoveMatch, RenameMatch('subtitle_language')]

    properties = {'subtitle_language': [None]}

    def when(self, matches, context):
        subtitle_extension = matches.named('container',
                                           lambda match: 'extension' in match.tags and 'subtitle' in match.tags,
                                           0)
        if subtitle_extension:
            subtitle_lang = matches.previous(subtitle_extension, lambda match: match.name == 'language', 0)
            if subtitle_lang:
                return matches.conflicting(subtitle_lang, lambda m: m.name == 'source'), subtitle_lang