Adding tests for include/exclude option with required fixes

This commit is contained in:
Rato
2017-12-16 22:18:07 +01:00
parent 0506a97505
commit 2ce6443e33
7 changed files with 386 additions and 21 deletions
+21 -8
View File
@@ -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
+1 -1
View File
@@ -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)
+6 -2
View File
@@ -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:
+12 -3
View File
@@ -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
+27 -6
View File
@@ -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')
+4 -1
View File
@@ -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:
+315
View File
@@ -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