diff --git a/guessit/config/options.json b/guessit/config/options.json new file mode 100644 index 0000000..11b4774 --- /dev/null +++ b/guessit/config/options.json @@ -0,0 +1,5 @@ +{ + "expected_title": [ + "OSS 117" + ] +} \ No newline at end of file diff --git a/guessit/options.py b/guessit/options.py index 5a552c7..c0db746 100644 --- a/guessit/options.py +++ b/guessit/options.py @@ -5,6 +5,7 @@ Options """ import json import os +import pkgutil import shlex from argparse import ArgumentParser @@ -21,12 +22,6 @@ def build_argument_parser(): opts.add_argument(dest='filename', help='Filename or release name to guess', nargs='*') naming_opts = opts.add_argument_group("Naming") - naming_opts.add_argument('-c', '--config', dest='config', action='append', default=None, - help='Filepath to the configuration file. Configuration contains the same options as ' - 'those command line options, but option names have "-" characters replaced with "_". ' - 'If not defined, guessit tries to read a configuration default configuration file at ' - '~/.guessit/options.(json|yml|yaml) and ~/.config/guessit/options.(json|yml|yaml). ' - 'Set to "false" to disable default configuration file loading.') naming_opts.add_argument('-t', '--type', dest='type', default=None, help='The suggested file type: movie, episode. If undefined, type will be guessed.') naming_opts.add_argument('-n', '--name-only', dest='name_only', action='store_true', default=None, @@ -64,6 +59,17 @@ def build_argument_parser(): output_opts.add_argument('-y', '--yaml', dest='yaml', action='store_true', default=None, help='Display information for filename guesses as yaml output') + conf_opts = opts.add_argument_group("Configuration") + conf_opts.add_argument('-c', '--config', dest='config', action='append', default=None, + help='Filepath to the configuration file. Configuration contains the same options as ' + 'those command line options, but option names have "-" characters replaced with "_". ' + 'If not defined, guessit tries to read a configuration default configuration file at ' + '~/.guessit/options.(json|yml|yaml) and ~/.config/guessit/options.(json|yml|yaml). ' + 'Set to "false" to disable default configuration file loading.') + conf_opts.add_argument('--no-embedded-config', dest='no_embedded_config', action='store_true', + default=None, + help='Disable default configuration.') + information_opts = opts.add_argument_group("Information") information_opts.add_argument('-p', '--properties', dest='properties', action='store_true', default=None, help='Display properties that can be guessed.') @@ -111,33 +117,40 @@ def load_config(options): :return: :rtype: """ + config_files_enabled = True custom_config_files = None if options.get('config') is not None: custom_config_files = options.get('config') if not custom_config_files \ or not custom_config_files[0] \ or custom_config_files[0].lower() in ['0', 'no', 'false', 'disabled']: - return options - - home_directory = os.path.expanduser("~") - cwd = os.getcwd() - yaml_supported = False - try: - import yaml # pylint: disable=unused-variable - yaml_supported = True - except ImportError: - pass - config_file_locations = get_config_file_locations(home_directory, cwd, yaml_supported) - config_files = [f for f in config_file_locations if os.path.exists(f)] - - if custom_config_files: - config_files = config_files + custom_config_files + config_files_enabled = False configurations = [] - for config_file in config_files: - config_file_options = load_config_file(config_file) - if config_file_options: - configurations.append(config_file_options) + if config_files_enabled: + home_directory = os.path.expanduser("~") + cwd = os.getcwd() + yaml_supported = False + try: + import yaml # pylint: disable=unused-variable + yaml_supported = True + except ImportError: + pass + config_file_locations = get_config_file_locations(home_directory, cwd, yaml_supported) + config_files = [f for f in config_file_locations if os.path.exists(f)] + + if custom_config_files: + config_files = config_files + custom_config_files + + for config_file in config_files: + config_file_options = load_config_file(config_file) + if config_file_options: + configurations.append(config_file_options) + + if not options.get('no_embedded_config'): + embedded_options_data = pkgutil.get_data('guessit', 'config/options.json').decode("utf-8") + embedded_options = json.loads(embedded_options_data) + configurations.append(embedded_options) if configurations: configurations.append(options) diff --git a/guessit/rules/properties/episode_title.py b/guessit/rules/properties/episode_title.py index 9d6e4ab..f6c6e46 100644 --- a/guessit/rules/properties/episode_title.py +++ b/guessit/rules/properties/episode_title.py @@ -5,10 +5,12 @@ Episode title """ from collections import defaultdict -from rebulk import Rebulk, Rule, AppendMatch, RenameMatch +from rebulk import Rebulk, Rule, AppendMatch, RenameMatch, POST_PROCESS + from ..common import seps, title_seps -from ..properties.title import TitleFromPosition, TitleBaseRule from ..common.formatters import cleanup +from ..properties.title import TitleFromPosition, TitleBaseRule +from ..properties.type import TypeProcessor def episode_title(): @@ -21,7 +23,8 @@ def episode_title(): AlternativeTitleReplace, TitleToEpisodeTitle, Filepart3EpisodeTitle, - Filepart2EpisodeTitle) + Filepart2EpisodeTitle, + RenameEpisodeTitleWhenMovieType) return rebulk @@ -130,9 +133,31 @@ class AlternativeTitleReplace(Rule): def then(self, matches, when_response, context): matches.remove(when_response) when_response.name = 'episode_title' + when_response.tags.append('alternative-replaced') matches.append(when_response) +class RenameEpisodeTitleWhenMovieType(Rule): + """ + Rename episode_title by alternative_title when type is movie. + """ + priority = POST_PROCESS + + dependency = TypeProcessor + consequence = RenameMatch + + def when(self, matches, context): + if matches.named('episode_title', lambda m: 'alternative-replaced' not in m.tags) \ + and not matches.named('type', lambda m: m.value == 'episode'): + return matches.named('episode_title') + + def then(self, matches, when_response, context): + for match in when_response: + matches.remove(match) + match.name = 'alternative_title' + matches.append(match) + + class Filepart3EpisodeTitle(Rule): """ If we have at least 3 filepart structured like this: diff --git a/guessit/rules/properties/episodes.py b/guessit/rules/properties/episodes.py index acc8990..1da02f4 100644 --- a/guessit/rules/properties/episodes.py +++ b/guessit/rules/properties/episodes.py @@ -296,11 +296,6 @@ def episodes(): rebulk.regex(r'Minisodes?', name='episode_format', value="Minisode") - # Harcoded movie to disable weak season/eps - rebulk.regex('OSS-?117', - abbreviations=[dash], name="hardcoded-movies", marker=True, - conflict_solver=lambda match, other: None) - rebulk.rules(EpisodeNumberSeparatorRange(range_separators), SeasonSeparatorRange(range_separators), RemoveWeakIfMovie, RemoveWeakIfSxxExx, RemoveWeakDuplicate, EpisodeDetailValidator, RemoveDetachedEpisodeNumber, VersionValidator, @@ -418,7 +413,7 @@ class RemoveWeakIfMovie(Rule): return context.get('type') != 'episode' def when(self, matches, context): - if matches.named('year') or matches.markers.named('hardcoded-movies'): + if matches.named('year'): return matches.tagged('weak-movie') diff --git a/guessit/rules/properties/title.py b/guessit/rules/properties/title.py index 707a272..e282d1e 100644 --- a/guessit/rules/properties/title.py +++ b/guessit/rules/properties/title.py @@ -26,7 +26,7 @@ def title(): expected_title = build_expected_function('expected_title') - rebulk.functional(expected_title, name='title', tags=['expected'], + rebulk.functional(expected_title, name='title', tags=['expected', 'title'], validator=seps_surround, formatter=formatters(cleanup, reorder_title), conflict_solver=lambda match, other: other, diff --git a/guessit/test/movies.yml b/guessit/test/movies.yml index 351a3fa..9d8f973 100644 --- a/guessit/test/movies.yml +++ b/guessit/test/movies.yml @@ -823,12 +823,13 @@ video_codec: h264 year: 2015 -? Hyena.Road.2015.German.Ep.Title.1080p.DL.DTSHD.Bluray.x264-pmHD +? Hyena.Road.2015.German.1080p.DL.DTSHD.Bluray.x264-pmHD : audio_codec: DTS audio_profile: HD - episode_title: German Ep Title format: BluRay - language: mul + language: + - de + - mul release_group: pmHD screen_size: 1080p title: Hyena Road diff --git a/guessit/test/test_options.py b/guessit/test/test_options.py index f426ead..8374978 100644 --- a/guessit/test/test_options.py +++ b/guessit/test/test_options.py @@ -119,21 +119,22 @@ def test_load_config_file(): def test_load_config(): - config = load_config({'param1': 'test', 'config': [os.path.join(__location__, 'config', 'test.yml')]}) + config = load_config({'no_embedded_config': True, 'param1': 'test', + 'config': [os.path.join(__location__, 'config', 'test.yml')]}) assert config['param1'] == 'test' assert config['expected_title'] == ['The 100', 'OSS 117'] assert config['yaml'] is True - config = load_config({'param1': 'test'}) + config = load_config({'no_embedded_config': True, 'param1': 'test'}) assert config['param1'] == 'test' assert 'expected_title' not in config assert 'yaml' not in config - config = load_config({'param1': 'test', 'config': ['false']}) + config = load_config({'no_embedded_config': True, 'param1': 'test', 'config': ['false']}) assert config['param1'] == 'test' diff --git a/guessit/test/test_yml.py b/guessit/test/test_yml.py index 2f09bef..1175afe 100644 --- a/guessit/test/test_yml.py +++ b/guessit/test/test_yml.py @@ -16,7 +16,7 @@ import pytest from rebulk.remodule import re from rebulk.utils import is_iterable -from ..options import parse_options +from ..options import parse_options, load_config from ..yamlutils import OrderedDictYAMLLoader from .. import guessit @@ -209,6 +209,7 @@ class TestYml(object): if 'implicit' not in options: options['implicit'] = True options['config'] = False + options = load_config(options) try: result = guessit(string, options) except Exception as exc: diff --git a/setup.py b/setup.py index 2eebc85..52484d9 100644 --- a/setup.py +++ b/setup.py @@ -25,6 +25,8 @@ dev_require = ['zest.releaser[recommended]', 'pylint', 'tox', 'sphinx', 'sphinx- tests_require = ['pytest>=2.7.3', 'pytest-benchmark', 'pytest-capturelog', 'PyYAML'] +package_data = ['config/*'] + entry_points = { 'console_scripts': [ 'guessit = guessit.__main__:main' @@ -60,6 +62,7 @@ args = dict(name='guessit', download_url='https://pypi.python.org/packages/source/g/guessit/guessit-%s.tar.gz' % version, license='LGPLv3', packages=find_packages(), + package_data={'guessit': package_data}, include_package_data=True, install_requires=install_requires, setup_requires=setup_requires,