mirror of
https://github.com/zoriya/guessit.git
synced 2026-06-03 18:51:09 +00:00
Adding tests for include/exclude option with required fixes
This commit is contained in:
@@ -6,7 +6,7 @@ video_bit_rate and audio_bit_rate properties
|
||||
import re
|
||||
|
||||
from rebulk import Rebulk
|
||||
from rebulk.rules import Rule, RenameMatch
|
||||
from rebulk.rules import Rule, RemoveMatch, RenameMatch
|
||||
|
||||
from ..common import dash, seps
|
||||
from ..common.pattern import is_disabled
|
||||
@@ -20,7 +20,8 @@ def bit_rate():
|
||||
:return: Created Rebulk object
|
||||
:rtype: Rebulk
|
||||
"""
|
||||
rebulk = Rebulk(disabled=lambda context: is_disabled(context, 'bit_rate'))
|
||||
rebulk = Rebulk(disabled=lambda context: (is_disabled(context, 'audio_bit_rate')
|
||||
and is_disabled(context, 'video_bit_rate')))
|
||||
rebulk = rebulk.regex_defaults(flags=re.IGNORECASE, abbreviations=[dash])
|
||||
rebulk.defaults(name='audio_bit_rate', validator=seps_surround)
|
||||
rebulk.regex(r'\d+-?[kmg]bps', r'\d+\.\d+-?[kmg]bps',
|
||||
@@ -40,11 +41,23 @@ class BitRateTypeRule(Rule):
|
||||
"""
|
||||
Convert audio bit rate guess into video bit rate.
|
||||
"""
|
||||
consequence = RenameMatch('video_bit_rate')
|
||||
consequence = [RenameMatch('video_bit_rate'), RemoveMatch]
|
||||
|
||||
def when(self, matches, context):
|
||||
for match in matches.named('audio_bit_rate'):
|
||||
previous = matches.previous(match, index=0,
|
||||
predicate=lambda m: m.name in ('source', 'screen_size', 'video_codec'))
|
||||
if previous and not matches.holes(previous.end, match.start, predicate=lambda m: m.value.strip(seps)):
|
||||
yield match
|
||||
to_rename = []
|
||||
to_remove = []
|
||||
|
||||
if is_disabled(context, 'audio_bit_rate'):
|
||||
to_remove.extend(matches.named('audio_bit_rate'))
|
||||
else:
|
||||
video_bit_rate_disabled = is_disabled(context, 'video_bit_rate')
|
||||
for match in matches.named('audio_bit_rate'):
|
||||
previous = matches.previous(match, index=0,
|
||||
predicate=lambda m: m.name in ('source', 'screen_size', 'video_codec'))
|
||||
if previous and not matches.holes(previous.end, match.start, predicate=lambda m: m.value.strip(seps)):
|
||||
if video_bit_rate_disabled:
|
||||
to_remove.append(match)
|
||||
else:
|
||||
to_rename.append(match)
|
||||
|
||||
return to_rename, to_remove
|
||||
|
||||
@@ -16,7 +16,7 @@ def crc():
|
||||
:return: Created Rebulk object
|
||||
:rtype: Rebulk
|
||||
"""
|
||||
rebulk = Rebulk(disabled=lambda context: is_disabled(context, 'crc'))
|
||||
rebulk = Rebulk(disabled=lambda context: is_disabled(context, 'crc32'))
|
||||
rebulk = rebulk.regex_defaults(flags=re.IGNORECASE)
|
||||
rebulk.defaults(validator=seps_surround)
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@ def date():
|
||||
:return: Created Rebulk object
|
||||
:rtype: Rebulk
|
||||
"""
|
||||
rebulk = Rebulk(disabled=lambda context: is_disabled(context, 'date'))
|
||||
rebulk = rebulk.defaults(validator=seps_surround)
|
||||
rebulk = Rebulk().defaults(validator=seps_surround)
|
||||
|
||||
rebulk.regex(r"\d{4}", name="year", formatter=int,
|
||||
disabled=lambda context: is_disabled(context, 'year'),
|
||||
validator=lambda match: seps_surround(match) and valid_year(match.value))
|
||||
|
||||
def date_functional(string, context): # pylint:disable=inconsistent-return-statements
|
||||
@@ -35,6 +35,7 @@ def date():
|
||||
return ret[0], ret[1], {'value': ret[2]}
|
||||
|
||||
rebulk.functional(date_functional, name="date", properties={'date': [None]},
|
||||
disabled=lambda context: is_disabled(context, 'date'),
|
||||
conflict_solver=lambda match, other: other
|
||||
if other.name in ('episode', 'season', 'crc32')
|
||||
else '__default__')
|
||||
@@ -51,6 +52,9 @@ class KeepMarkedYearInFilepart(Rule):
|
||||
priority = 64
|
||||
consequence = RemoveMatch
|
||||
|
||||
def enabled(self, context):
|
||||
return not is_disabled(context, 'year')
|
||||
|
||||
def when(self, matches, context):
|
||||
ret = []
|
||||
if len(matches.named('year')) > 1:
|
||||
|
||||
@@ -29,7 +29,7 @@ def episodes():
|
||||
# pylint: disable=too-many-branches,too-many-statements,too-many-locals
|
||||
def is_season_episode_disabled(context):
|
||||
"""Whether season and episode rules should be enabled."""
|
||||
return is_disabled(context, 'episode') and is_disabled(context, 'season')
|
||||
return is_disabled(context, 'episode') or is_disabled(context, 'season')
|
||||
|
||||
rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE).string_defaults(ignore_case=True)
|
||||
rebulk.defaults(private_names=['episodeSeparator', 'seasonSeparator', 'episodeMarker', 'seasonMarker'])
|
||||
@@ -836,13 +836,22 @@ class RenameToDiscMatch(Rule):
|
||||
Rename episodes detected with `d` episodeMarkers to `disc`.
|
||||
"""
|
||||
|
||||
consequence = [RenameMatch('disc'), RenameMatch('discMarker')]
|
||||
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))
|
||||
|
||||
return discs, markers
|
||||
return discs, markers, to_remove
|
||||
|
||||
@@ -37,7 +37,7 @@ def language():
|
||||
rebulk.functional(find_languages,
|
||||
properties={'language': [None]},
|
||||
disabled=lambda context: not context.get('allowed_languages'))
|
||||
rebulk.rules(SubtitlePrefixLanguageRule, SubtitleSuffixLanguageRule, SubtitleExtensionRule)
|
||||
rebulk.rules(SubtitlePrefixLanguageRule, SubtitleSuffixLanguageRule, SubtitleExtensionRule, RemoveLanguage)
|
||||
|
||||
return rebulk
|
||||
|
||||
@@ -193,9 +193,19 @@ class LanguageFinder(object):
|
||||
Helper class to search and return language matches: 'language' and 'subtitle_language' properties
|
||||
"""
|
||||
|
||||
def __init__(self, allowed_languages):
|
||||
def __init__(self, context):
|
||||
allowed_languages = context.get('allowed_languages') if context else None
|
||||
self.allowed_languages = set([l.lower() for l in allowed_languages or []])
|
||||
self.common_words = COMMON_WORDS
|
||||
self.prefixes_map = {}
|
||||
self.suffixes_map = {}
|
||||
|
||||
if not is_disabled(context, 'subtitle_language'):
|
||||
self.prefixes_map['subtitle_language'] = subtitle_prefixes
|
||||
self.suffixes_map['subtitle_language'] = subtitle_suffixes
|
||||
|
||||
self.prefixes_map['language'] = lang_prefixes
|
||||
self.suffixes_map['language'] = lang_suffixes
|
||||
|
||||
def find(self, string):
|
||||
"""
|
||||
@@ -256,11 +266,11 @@ class LanguageFinder(object):
|
||||
"""
|
||||
tuples = [
|
||||
(language_word, language_word.next_word,
|
||||
{'subtitle_language': subtitle_prefixes, 'language': lang_prefixes},
|
||||
self.prefixes_map,
|
||||
lambda string, prefix: string.startswith(prefix),
|
||||
lambda string, prefix: string[len(prefix):]),
|
||||
(language_word.next_word, language_word,
|
||||
{'subtitle_language': subtitle_suffixes, 'language': lang_suffixes},
|
||||
self.suffixes_map,
|
||||
lambda string, suffix: string.endswith(suffix),
|
||||
lambda string, suffix: string[:len(string) - len(suffix)])
|
||||
]
|
||||
@@ -351,8 +361,7 @@ def find_languages(string, context=None):
|
||||
|
||||
:return: list of tuple (property, Language, lang_word, word)
|
||||
"""
|
||||
allowed_languages = context.get('allowed_languages') if context else None
|
||||
return LanguageFinder(allowed_languages).find(string)
|
||||
return LanguageFinder(context).find(string)
|
||||
|
||||
|
||||
class SubtitlePrefixLanguageRule(Rule):
|
||||
@@ -455,3 +464,15 @@ class SubtitleExtensionRule(Rule):
|
||||
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
|
||||
|
||||
|
||||
class RemoveLanguage(Rule):
|
||||
"""Remove language matches that were not converted to subtitle_language when language is disabled."""
|
||||
|
||||
consequence = RemoveMatch
|
||||
|
||||
def enabled(self, context):
|
||||
return is_disabled(context, 'language')
|
||||
|
||||
def when(self, matches, context):
|
||||
return matches.named('language')
|
||||
|
||||
@@ -77,7 +77,10 @@ class PostProcessScreenSize(Rule):
|
||||
|
||||
aspect_ratio = Match(match.start, match.end, input_string=match.input_string,
|
||||
name='aspect_ratio', value=round(calculated_ar, 3))
|
||||
to_append.append(aspect_ratio)
|
||||
|
||||
if not is_disabled(context, 'aspect_ratio'):
|
||||
to_append.append(aspect_ratio)
|
||||
|
||||
if height in self.standard_heights and self.min_ar < calculated_ar < self.max_ar:
|
||||
match.value = '{0}{1}'.format(height, scan_type)
|
||||
else:
|
||||
|
||||
@@ -0,0 +1,315 @@
|
||||
? vorbis
|
||||
: options: --exclude audio_codec
|
||||
-audio_codec: Vorbis
|
||||
|
||||
? DTS-ES
|
||||
: options: --exclude audio_profile
|
||||
audio_codec: DTS
|
||||
-audio_profile: Extended Surround
|
||||
|
||||
? DTS.ES
|
||||
: options: --include audio_codec
|
||||
audio_codec: DTS
|
||||
-audio_profile: Extended Surround
|
||||
|
||||
? 5.1
|
||||
? 5ch
|
||||
? 6ch
|
||||
: options: --exclude audio_channels
|
||||
-audio_channels: '5.1'
|
||||
|
||||
? Movie Title-x01-Other Title.mkv
|
||||
? Movie Title-x01-Other Title
|
||||
? directory/Movie Title-x01-Other Title/file.mkv
|
||||
: options: --exclude bonus
|
||||
-bonus: 1
|
||||
-bonus_title: Other Title
|
||||
|
||||
? Title-x02-Bonus Title.mkv
|
||||
: options: --include bonus
|
||||
bonus: 2
|
||||
-bonus_title: Other Title
|
||||
|
||||
? cd 1of3
|
||||
: options: --exclude cd
|
||||
-cd: 1
|
||||
-cd_count: 3
|
||||
|
||||
? This.Is.Us
|
||||
: options: --exclude country
|
||||
title: This Is Us
|
||||
-country: US
|
||||
|
||||
? 2015.01.31
|
||||
: options: --exclude date
|
||||
year: 2015
|
||||
-date: 2015-01-31
|
||||
|
||||
? Something 2 mar 2013)
|
||||
: options: --exclude date
|
||||
-date: 2013-03-02
|
||||
|
||||
? 2012 2009 S01E02 2015 # If no year is marked, the second one is guessed.
|
||||
: options: --exclude year
|
||||
-year: 2009
|
||||
|
||||
? Director's cut
|
||||
: options: --exclude edition
|
||||
-edition: Director's Cut
|
||||
|
||||
? 2x5
|
||||
? 2X5
|
||||
? 02x05
|
||||
? 2X05
|
||||
? 02x5
|
||||
? S02E05
|
||||
? s02e05
|
||||
? s02e5
|
||||
? s2e05
|
||||
? s02ep05
|
||||
? s2EP5
|
||||
: options: --exclude season
|
||||
-season: 2
|
||||
-episode: 5
|
||||
|
||||
? 2x6
|
||||
? 2X6
|
||||
? 02x06
|
||||
? 2X06
|
||||
? 02x6
|
||||
? S02E06
|
||||
? s02e06
|
||||
? s02e6
|
||||
? s2e06
|
||||
? s02ep06
|
||||
? s2EP6
|
||||
: options: --exclude episode
|
||||
-season: 2
|
||||
-episode: 6
|
||||
|
||||
? serie Season 2 other
|
||||
: options: --exclude season
|
||||
-season: 2
|
||||
|
||||
? Some Dummy Directory/S02 Some Series/E01-Episode title.mkv
|
||||
: options: --exclude episode_title
|
||||
-episode_title: Episode title
|
||||
season: 2
|
||||
episode: 1
|
||||
|
||||
? Another Dummy Directory/S02 Some Series/E01-Episode title.mkv
|
||||
: options: --include season --include episode
|
||||
-episode_title: Episode title
|
||||
season: 2
|
||||
episode: 1
|
||||
|
||||
# pattern contains season and episode: it wont work enabling only one
|
||||
? Some Series S03E01E02
|
||||
: options: --include episode
|
||||
-season: 3
|
||||
-episode: [1, 2]
|
||||
|
||||
# pattern contains season and episode: it wont work enabling only one
|
||||
? Another Series S04E01E02
|
||||
: options: --include season
|
||||
-season: 4
|
||||
-episode: [1, 2]
|
||||
|
||||
? Show.Name.Season.4.Episode.1
|
||||
: options: --include episode
|
||||
-season: 4
|
||||
episode: 1
|
||||
|
||||
? Another.Show.Name.Season.4.Episode.1
|
||||
: options: --include season
|
||||
season: 4
|
||||
-episode: 1
|
||||
|
||||
? Some Series S01 02 03
|
||||
: options: --exclude season
|
||||
-season: [1, 2, 3]
|
||||
|
||||
? Some Series E01 02 04
|
||||
: options: --exclude episode
|
||||
-episode: [1, 2, 4]
|
||||
|
||||
? A very special episode s06 special
|
||||
: options: -t episode --exclude episode_details
|
||||
season: 6
|
||||
-episode_details: Special
|
||||
|
||||
? S01D02.3-5-GROUP
|
||||
: options: --exclude disc
|
||||
-season: 1
|
||||
-disc: [2, 3, 4, 5]
|
||||
-episode: [2, 3, 4, 5]
|
||||
|
||||
? S01D02&4-6&8
|
||||
: options: --exclude season
|
||||
-season: 1
|
||||
-disc: [2, 4, 5, 6, 8]
|
||||
-episode: [2, 4, 5, 6, 8]
|
||||
|
||||
? Film Title-f01-Series Title.mkv
|
||||
: options: --exclude film
|
||||
-film: 1
|
||||
-film_title: Film Title
|
||||
|
||||
? Another Film Title-f01-Series Title.mkv
|
||||
: options: --exclude film_title
|
||||
film: 1
|
||||
-film_title: Film Title
|
||||
|
||||
? English
|
||||
? .ENG.
|
||||
: options: --exclude language
|
||||
-language: English
|
||||
|
||||
? SubFrench
|
||||
? SubFr
|
||||
? STFr
|
||||
: options: --exclude subtitle_language
|
||||
-language: French
|
||||
-subtitle_language: French
|
||||
|
||||
? ST.FR
|
||||
: options: --exclude subtitle_language
|
||||
language: French
|
||||
-subtitle_language: French
|
||||
|
||||
? ENG.-.sub.FR
|
||||
? ENG.-.FR Sub
|
||||
: options: --include language
|
||||
language: [English, French]
|
||||
-subtitle_language: French
|
||||
|
||||
? ENG.-.SubFR
|
||||
: options: --include language
|
||||
language: English
|
||||
-subtitle_language: French
|
||||
|
||||
? ENG.-.FRSUB
|
||||
? ENG.-.FRSUBS
|
||||
? ENG.-.FR-SUBS
|
||||
: options: --include subtitle_language
|
||||
-language: English
|
||||
subtitle_language: French
|
||||
|
||||
? DVD.Real.XViD
|
||||
? DVD.fix.XViD
|
||||
: options: --exclude other
|
||||
-other: Proper
|
||||
-proper_count: 1
|
||||
|
||||
? Part 3
|
||||
? Part III
|
||||
? Part Three
|
||||
? Part Trois
|
||||
? Part3
|
||||
: options: --exclude part
|
||||
-part: 3
|
||||
|
||||
? Some.Title.XViD-by.Artik[SEDG].avi
|
||||
: options: --exclude release_group
|
||||
-release_group: Artik[SEDG]
|
||||
|
||||
? "[ABC] Some.Title.avi"
|
||||
? some/folder/[ABC]Some.Title.avi
|
||||
: options: --exclude release_group
|
||||
-release_group: ABC
|
||||
|
||||
? 360p
|
||||
? 360px
|
||||
? "360"
|
||||
? +500x360
|
||||
: options: --exclude screen_size
|
||||
-screen_size: 360p
|
||||
|
||||
? 640x360
|
||||
: options: --exclude aspect_ratio
|
||||
screen_size: 360p
|
||||
-aspect_ratio: 1.778
|
||||
|
||||
? 8196x4320
|
||||
: options: --exclude screen_size
|
||||
-screen_size: 4320p
|
||||
-aspect_ratio: 1.897
|
||||
|
||||
? 4.3gb
|
||||
: options: --exclude size
|
||||
-size: 4.3GB
|
||||
|
||||
? VhS_rip
|
||||
? VHS.RIP
|
||||
: options: --exclude source
|
||||
-source: VHS
|
||||
-other: Rip
|
||||
|
||||
? DVD.RIP
|
||||
: options: --include other
|
||||
-source: DVD
|
||||
-other: Rip
|
||||
|
||||
? Title Only.avi
|
||||
: options: --exclude title
|
||||
-title: Title Only
|
||||
|
||||
? h265
|
||||
? x265
|
||||
? h.265
|
||||
? x.265
|
||||
? hevc
|
||||
: options: --exclude video_codec
|
||||
-video_codec: H.265
|
||||
|
||||
? hevc10
|
||||
: options: --include color_depth
|
||||
-video_codec: H.265
|
||||
-color_depth: 10-bit
|
||||
|
||||
? HEVC-YUV420P10
|
||||
: options: --include color_depth
|
||||
-video_codec: H.265
|
||||
color_depth: 10-bit
|
||||
|
||||
? h265-HP
|
||||
: options: --exclude video_profile
|
||||
video_codec: H.265
|
||||
-video_profile: High
|
||||
|
||||
? House.of.Cards.2013.S02E03.1080p.NF.WEBRip.DD5.1.x264-NTb.mkv
|
||||
? House.of.Cards.2013.S02E03.1080p.Netflix.WEBRip.DD5.1.x264-NTb.mkv
|
||||
: options: --exclude streaming_service
|
||||
-streaming_service: Netflix
|
||||
|
||||
? wawa.co.uk
|
||||
: options: --exclude website
|
||||
-website: wawa.co.uk
|
||||
|
||||
? movie.mkv
|
||||
: options: --exclude mimetype
|
||||
-mimetype: video/x-matroska
|
||||
|
||||
? another movie.mkv
|
||||
: options: --exclude container
|
||||
-container: mkv
|
||||
|
||||
? series s02e01
|
||||
: options: --exclude type
|
||||
-type: episode
|
||||
|
||||
? series s02e01
|
||||
: options: --exclude type
|
||||
-type: episode
|
||||
|
||||
? Hotel.Hell.S01E01.720p.DD5.1.448kbps-ALANiS
|
||||
: options: --exclude audio_bit_rate
|
||||
-audio_bit_rate: 448Kbps
|
||||
|
||||
? Katy Perry - Pepsi & Billboard Summer Beats Concert Series 2012 1080i HDTV 20 Mbps DD2.0 MPEG2-TrollHD.ts
|
||||
: options: --exclude video_bit_rate
|
||||
-video_bit_rate: 20Mbps
|
||||
|
||||
? "[Figmentos] Monster 34 - At the End of Darkness [781219F1].mkv"
|
||||
: options: --exclude crc32
|
||||
-crc32: 781219F1
|
||||
Reference in New Issue
Block a user