def container(): """Builder for rebulk object. :return: Created Rebulk object :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE).string_defaults(ignore_case=True) rebulk.defaults(name='container', tags=['extension'], conflict_solver=lambda match, other: other if other.name in ['format', 'video_codec'] or other.name == 'container' and 'extension' not in other.tags else '__default__') nzb = ['nzb'] rebulk.regex(r'\.' + build_or_pattern(nzb) + '$', exts=nzb, tags=['extension', 'torrent']) rebulk.defaults(name='container', validator=seps_surround, formatter=lambda s: s.upper(), conflict_solver=lambda match, other: match if other.name in ['format', 'video_codec'] or other.name == 'container' and 'extension' in other.tags else '__default__') rebulk.string(*nzb, tags=['nzb']) return rebulk
def container(): """Builder for rebulk object. :return: Created Rebulk object :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE).string_defaults(ignore_case=True) rebulk.defaults(name='container', tags=['extension'], conflict_solver=lambda match, other: other if other.name in ['source', 'video_codec'] or other.name == 'container' and 'extension' not in other.tags else '__default__') if six.PY3: nzb = ['nzb'] else: nzb = [b'nzb'] rebulk.regex(r'\.' + build_or_pattern(nzb) + '$', exts=nzb, tags=['extension', 'torrent']) rebulk.defaults(name='container', validator=seps_surround, formatter=lambda s: s.upper(), conflict_solver=lambda match, other: match if other.name in ['source', 'video_codec'] or other.name == 'container' and 'extension' in other.tags else '__default__') rebulk.string(*nzb, tags=['nzb']) return rebulk
def blacklist(): """Blacklisted patterns. All blacklisted patterns should use `other` property and be private. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='other', private=True) rebulk.regex('DownRev', 'small-size') return rebulk
def size(): """Size property. Remove when https://github.com/guessit-io/guessit/issues/299 is fixed. :return: :rtype: Rebulk """ def format_size(value): return re.sub(r'(?<=\d)[\.](?=[^\d])', '', value.upper()) rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='size', validator=seps_surround) rebulk.regex(r'\d+\.?[mgt]b', r'\d+\.\d+[mgt]b', formatter=format_size, tags=['release-group-prefix']) return rebulk
def rules(): """Return all custom rules to be applied to guessit default api. IMPORTANT! The order is important. Certain rules needs to be executed first, and others should be executed at the end. DO NOT define priority or dependency in each rule, it can become a mess. Better to just define the correct order in this method. Builder for rebulk object. :return: Created Rebulk object :rtype: Rebulk """ return Rebulk().rules( BlacklistedReleaseGroup, FixTvChaosUkWorkaround, FixAnimeReleaseGroup, FixInvalidAbsoluteReleaseGroups, AnimeWithSeasonAbsoluteEpisodeNumbers, AnimeAbsoluteEpisodeNumbers, AbsoluteEpisodeNumbers, PartsAsEpisodeNumbers, RemoveInvalidEpisodeSeparator, CreateAliasWithAlternativeTitles, CreateAliasWithCountryOrYear, ReleaseGroupPostProcessor, FixParentFolderReplacingTitle, FixMultipleSources, AudioCodecStandardizer, SourceStandardizer, VideoEncoderRule, CreateProperTags, AvoidMultipleValuesRule, )
def language(): """Language property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='language', validator=seps_surround) rebulk.regex('SPANISH-?AUDIO', r'(?:Espa[.]ol-)?castellano', value=babelfish.Language('spa')) rebulk.regex('german-dubbed', 'dubbed-german', value=babelfish.Language('deu')) rebulk.regex('dublado', value='und', formatter=babelfish.Language) return rebulk
def screen_size(): """Screen size property. :return: :rtype: Rebulk """ # https://github.com/guessit-io/guessit/issues/319 rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE) rebulk.defaults(name='screen_size', validator=seps_surround) rebulk.regex(r'(?:\d{3,}(?:x|\*))?720phd', value='720p') rebulk.regex(r'(?:\d{3,}(?:x|\*))?1080phd', value='1080p') rebulk.regex('NetflixUHD', value='4k') return rebulk
def screen_size(): """Screen size property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE) rebulk.defaults(name='screen_size', validator=seps_surround) rebulk.regex('NetflixUHD', value='2160p') rebulk.regex(r'(?:\d{3,}(?:x|\*))?4320(?:p?x?)', value='4320p') return rebulk
def other(): """Other property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='other', validator=seps_surround) rebulk.regex('F1', value='Formula One', conflict_solver=lambda match, other: other if other.name == 'film' else '__default__') # Discarded: rebulk.regex('DownRev', 'small-size', private=True) return rebulk
def audio_codec(): """Audio codec property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(name='audio_codec', flags=re.IGNORECASE) rebulk.regex(r'DDP', value='AC3') rebulk.rules(Ac3Rule, AudioValidatorRule, HqConflictRule) return rebulk
def audio_channels(): """Audio channels property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]).string_defaults(ignore_case=True) rebulk.defaults(name='audio_channels') # https://github.com/guessit-io/guessit/issues/328 rebulk.string('7.1ch', value='7.1') rebulk.string('5.1ch', value='5.1') rebulk.string('2.0ch', value='2.0') return rebulk
def screen_size(): """Screen size property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE) rebulk.defaults(name='screen_size', validator=seps_surround) rebulk.regex('NetflixUHD', value='4k') return rebulk
def other(): """Other property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='other', validator=seps_surround) rebulk.regex('F1', value='Formula One', conflict_solver=lambda match, other: other if other.name == 'film' else '__default__') # Discarded: rebulk.regex('DownRev', 'small-size', private=True) return rebulk
def screen_size(): """Screen size property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE) rebulk.defaults(name='screen_size', validator=seps_surround) # Discarded: rebulk.regex(r'(?:\d{3,}(?:x|\*))?4320(?:p?x?)', value='4320p', private=True) return rebulk
def size(): """Size property. Remove when https://github.com/guessit-io/guessit/issues/299 is fixed. :return: :rtype: Rebulk """ def format_size(value): return re.sub(r'(?<=\d)[.](?=[^\d])', '', value.upper()) rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='size', validator=seps_surround) rebulk.regex(r'\d+\.?[mgt]b', r'\d+\.\d+[mgt]b', formatter=format_size, tags=['release-group-prefix']) return rebulk
def other(): """Other property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='other', validator=seps_surround) # https://github.com/guessit-io/guessit/issues/300 rebulk.regex(r'Re-?Enc(?:oded)?', value='Re-Encoded') rebulk.regex('DIRFIX', value='DirFix') rebulk.regex('INTERNAL', value='Internal') rebulk.regex(r'(?:HD)?iTunes(?:HD)?', value='iTunes') rebulk.regex('HC', value='Hardcoded subtitles') rebulk.rules(ValidateHardcodedSubs) return rebulk
def format_(): """Format property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='format') # https://github.com/guessit-io/guessit/issues/307 rebulk.regex('HDTV-?Mux', value='HDTV') rebulk.regex('B[RD]-?Mux', 'Blu-?ray-?Mux', value='BluRay') rebulk.regex('DVD-?Mux', value='DVD') rebulk.regex('WEB-?Mux', 'DL-?WEB-?Mux', 'WEB-?DL-?Mux', 'DL-?Mux', value='WEB-DL') # https://github.com/guessit-io/guessit/issues/315 rebulk.regex('WEB-?DL-?Rip', value='WEBRip') rebulk.regex('WEB-?Cap', value='WEBCap') rebulk.regex('DSR', 'DS-?Rip', 'SAT-?Rip', 'DTH-?Rip', value='DSRip') rebulk.regex('LDTV', value='TV') rebulk.regex('DVD\d', value='DVD') return rebulk
def source(): """Source property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='source', tags='video-codec-prefix') # More accurate sources rebulk.regex('BD-?Rip', 'BD(?=-?Mux)', value='BDRip', conflict_solver=lambda match, other: other if other.name == 'source' else '__default__') rebulk.regex(r'BD(?!\d)', value='BDRip', validator=seps_surround, conflict_solver=lambda match, other: other if other.name == 'source' else '__default__') rebulk.regex('BR-?Rip', 'BR(?=-?Mux)', value='BRRip', conflict_solver=lambda match, other: other if other.name == 'source' else '__default__') rebulk.regex('DVD-?Rip', value='DVDRip', conflict_solver=lambda match, other: other if other.name == 'source' else '__default__') rebulk.regex(r'DVD\d', value='DVD') return rebulk
def format_(): """Format property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='format') # More accurate formats rebulk.regex('BD(?!\d)', 'BD-?Rip', 'BD-?Mux', 'BD-?Rip-?Mux', value='BDRip', validator=seps_surround, conflict_solver=lambda match, other: other if other.name == 'format' else '__default__') rebulk.regex('BR-?Rip', 'BR-?Mux', 'BR-?Rip-?Mux', value='BRRip', conflict_solver=lambda match, other: other if other.name == 'format' else '__default__') rebulk.regex('DVD-?Rip', value='DVDRip', conflict_solver=lambda match, other: other if other.name == 'format' else '__default__') # https://github.com/guessit-io/guessit/issues/307 rebulk.regex('HDTV-?Mux', value='HDTV') rebulk.regex('Blu-?ray-?Mux', value='BluRay') rebulk.regex('DVD-?Mux', value='DVD') rebulk.regex('WEB-?Mux', 'DL-?WEB-?Mux', 'WEB-?DL-?Mux', 'DL-?Mux', value='WEB-DL') rebulk.regex('DVD\d', value='DVD') return rebulk
def subtitle_language(): """Subtitle language property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE | re.UNICODE, abbreviations=[alt_dash]) rebulk.defaults(name='subtitle_language', validator=seps_surround) # special handling rebulk.regex(r'Legenda(?:s|do)?@PT-?BR', value=babelfish.Language('por', 'BR')) rebulk.regex(r'Legenda(?:s|do)?@PT(?!-?BR)', value=babelfish.Language('por')) rebulk.regex('Subtitulado@ESP(?:a[nñ]ol)?@Spanish', 'Subtitulado@ESP(?:a[nñ]ol)?', value=babelfish.Language('spa'), conflict_solver=lambda match, other: other if other.name == 'language' else '__default__') # undefined language rebulk.regex('Subtitles', 'Legenda(?:s|do)', 'Subbed', 'Sub(?:title)?s?@Latino', value='und', formatter=babelfish.Language, tags='subtitle.undefined') rebulk.rules(RemoveSubtitleUndefined) return rebulk
def subtitle_language(): """Subtitle language property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE | re.UNICODE, abbreviations=[alt_dash]) rebulk.defaults(name='subtitle_language', validator=seps_surround) # special handling rebulk.regex(r'Legenda(?:s|do)?@PT-?BR', value=babelfish.Language('por', 'BR')) rebulk.regex(r'Legenda(?:s|do)?@PT(?!-?BR)', value=babelfish.Language('por')) rebulk.regex('Subtitulado@ESP(?:a[nñ]ol)?@Spanish', 'Subtitulado@ESP(?:a[nñ]ol)?', value=babelfish.Language('spa'), conflict_solver=lambda match, other: other if other.name == 'language' else '__default__') # undefined language rebulk.regex('Subtitles', 'Legenda(?:s|do)', 'Subbed', 'Sub(?:title)?s?@Latino', value='und', formatter=babelfish.Language, tags='subtitle.undefined') rebulk.rules(RemoveSubtitleUndefined) return rebulk
def blacklist(): """Blacklisted patterns. All blacklisted patterns. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='blacklist', validator=seps_surround, conflict_solver=lambda match, other: other if other.name != 'blacklist' else '__default__') rebulk.regex(r'(?:(?:\[\d+/\d+\])-+)?\.".+".*', tags=['blacklist-01']) rebulk.regex(r'vol\d{2,3}\+\d{2,3}.*', tags=['blacklist-02']) rebulk.regex(r'(?:nzb|par2)-+\d+\.of\.\d+.*', tags=['blacklist-03']) rebulk.regex(r'(?:(?:nzb|par2)-+)?\d+\.of\.\d+.*', tags=['blacklist-03', 'should-have-container-before']) rebulk.rules(ValidateBlacklist, RemoveBlacklisted) return rebulk
def language(): """Language property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='language', validator=seps_surround) rebulk.regex('SPANISH-?AUDIO', r'(?:Espa[.]ol-)?castellano', value=babelfish.Language('spa')) rebulk.regex('german-dubbed', 'dubbed-german', value=babelfish.Language('deu')) rebulk.regex('english-dubbed', value=babelfish.Language('eng')) rebulk.regex('dublado', value='und', formatter=babelfish.Language) return rebulk
def blacklist(): """Blacklisted patterns. All blacklisted patterns. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='blacklist', validator=seps_surround, conflict_solver=lambda match, other: other if other.name != 'blacklist' else '__default__') rebulk.regex(r'(?:(?:\[\d+/\d+\])-+)?\.".+".*', tags=['blacklist-01']) rebulk.regex(r'vol\d{2,3}\+\d{2,3}.*', tags=['blacklist-02']) rebulk.regex(r'(?:nzb|par2)-+\d+\.of\.\d+.*', tags=['blacklist-03']) rebulk.regex(r'(?:(?:nzb|par2)-+)?\d+\.of\.\d+.*', tags=['blacklist-03', 'should-have-container-before']) rebulk.rules(ValidateBlacklist, RemoveBlacklisted) return rebulk
def format_(): """Format property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='format', tags='video-codec-prefix') # More accurate formats rebulk.regex('BD-?Rip', 'BD(?=-?Mux)', value='BDRip', conflict_solver=lambda match, other: other if other.name == 'format' else '__default__') rebulk.regex('BD(?!\d)', value='BDRip', validator=seps_surround, conflict_solver=lambda match, other: other if other.name == 'format' else '__default__') rebulk.regex('BR-?Rip', 'BR(?=-?Mux)', value='BRRip', conflict_solver=lambda match, other: other if other.name == 'format' else '__default__') rebulk.regex('DVD-?Rip', value='DVDRip', conflict_solver=lambda match, other: other if other.name == 'format' else '__default__') rebulk.regex('DVD\d', value='DVD') return rebulk
def format_(): """Format property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='format') # https://github.com/guessit-io/guessit/issues/307 rebulk.regex('HDTV-?Mux', value='HDTV') rebulk.regex('B[RD]-?Mux', 'Blu-?ray-?Mux', value='BluRay') rebulk.regex('DVD-?Mux', value='DVD') rebulk.regex('WEB-?Mux', 'DL-?WEB-?Mux', 'WEB-?DL-?Mux', 'DL-?Mux', value='WEB-DL') # https://github.com/guessit-io/guessit/issues/315 rebulk.regex('WEB-?DL-?Rip', value='WEBRip') rebulk.regex('WEB-?Cap', value='WEBCap') rebulk.regex('DSR', 'DS-?Rip', 'SAT-?Rip', 'DTH-?Rip', value='DSRip') rebulk.regex('LDTV', value='TV') rebulk.regex('DVD\d', value='DVD') return rebulk
def other(): """Other property. :return: :rtype: Rebulk """ rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='other', validator=seps_surround) # https://github.com/guessit-io/guessit/issues/300 rebulk.regex(r'Re-?Enc(?:oded)?', value='Re-Encoded') rebulk.regex('DIRFIX', value='DirFix') rebulk.regex('INTERNAL', value='Internal') rebulk.regex(r'(?:HD)?iTunes(?:HD)?', value='iTunes') rebulk.regex(r'UNCENSORED', value='Uncensored') rebulk.regex(r'MULTi', value='Multi Language') rebulk.regex('HC', value='Hardcoded subtitles') # Discarded: rebulk.regex('DownRev', 'small-size', private=True) rebulk.rules(ValidateHardcodedSubs) return rebulk