diff --git a/docs/index.rst b/docs/index.rst index 981fd7ce..925d5f42 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -67,10 +67,10 @@ Usage GuessIt can be used from command line:: $ guessit - usage: guessit [-h] [-t TYPE] [-n] [-Y] [-D] [-L ALLOWED_LANGUAGES] - [-C ALLOWED_COUNTRIES] [-E] [-T EXPECTED_TITLE] - [-G EXPECTED_GROUP] [-f INPUT_FILE] [-v] [-P SHOW_PROPERTY] - [-a] [-j] [-y] [-p] [-V] [--version] + usage: guessit [-h] [-c CONFIG] [-t TYPE] [-n] [-Y] [-D] + [-L ALLOWED_LANGUAGES] [-C ALLOWED_COUNTRIES] [-E] + [-T EXPECTED_TITLE] [-G EXPECTED_GROUP] [-f INPUT_FILE] [-v] + [-P SHOW_PROPERTY] [-a] [-j] [-y] [-p] [-V] [--version] [filename [filename ...]] positional arguments: @@ -80,6 +80,15 @@ GuessIt can be used from command line:: -h, --help show this help message and exit Naming: + -c CONFIG, --config CONFIG + 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. -t TYPE, --type TYPE The suggested file type: movie, episode. If undefined, type will be guessed. -n, --name-only Parse files as name only, considering "/" and "\" like diff --git a/guessit/api.py b/guessit/api.py index 900f6965..ad9e7de7 100644 --- a/guessit/api.py +++ b/guessit/api.py @@ -3,26 +3,31 @@ """ API functions that can be used by external software """ +from __future__ import print_function + try: from collections import OrderedDict except ImportError: # pragma: no-cover from ordereddict import OrderedDict # pylint:disable=import-error +import json +import os +import sys import traceback import six - from rebulk.introspector import introspect -from .rules import rebulk_builder -from .options import parse_options from .__version__ import __version__ +from .options import parse_options +from .rules import rebulk_builder class GuessitException(Exception): """ Exception raised when guessit fails to perform a guess because of an internal error. """ + def __init__(self, string, options): super(GuessitException, self).__init__("An internal error has occured in guessit.\n" "===================== Guessit Exception Report =====================\n" @@ -101,6 +106,7 @@ def guessit(self, string, options=None): """ try: options = parse_options(options) + options = GuessItApi.load_config(options) result_decode = False result_encode = False @@ -146,5 +152,86 @@ def properties(self, options=None): ordered = self.rebulk.customize_properties(ordered) return ordered + @staticmethod + def load_config(options): + """ + Load configuration from configuration file, if defined. + :param options: + :type options: + :return: + :rtype: + """ + config_file_options = None + if options.get('config'): + config_file = options.get('config') + if config_file and config_file in ['0', 'no', 'false', 'disabled']: + return options + else: + home_directory = os.path.expanduser("~") + config_file = GuessItApi.get_json_config_file(home_directory) + if not config_file: + config_file = GuessItApi.get_yml_config_file(home_directory) + if config_file: + if os.path.exists(config_file): + if config_file.endswith('.json'): + with open(config_file) as config_file_data: + config_file_options = json.load(config_file_data) + elif config_file.endswith('.yaml') or config_file.endswith('.yml'): + try: + import yaml + with open(config_file) as config_file_data: + config_file_options = yaml.load(config_file_data) + except ImportError: # pragma: no cover + print('PyYAML is not installed. Options file "%s" will be ignored ...' % (config_file,), + file=sys.stderr) + else: + print('Configuration file "%s" has no supported extension. It should ends with json, yaml or yml. ' + 'Using default options...' % (config_file,), file=sys.stderr) + else: + print('Configuration file "%s" was not found. Using default options...' % (config_file,), + file=sys.stderr) + if config_file_options: + options.update(config_file_options) + return options + + @staticmethod + def get_json_config_file(basedir): + """ + Get default json configuration filepath, if exists. + :param basedir: + :type basedir: + :return: + :rtype: + """ + config_file = os.path.join(basedir, '.guessit', 'options.json') + if os.path.exists(config_file): + return config_file + config_file = os.path.join(basedir, '.config', 'guessit', 'options.json') + if os.path.exists(config_file): + return config_file + return None + + @staticmethod + def get_yml_config_file(basedir): + """ + Get default yaml configuration filepath, if exists. + :param basedir: + :type basedir: + :return: + :rtype: + """ + config_file = os.path.join(basedir, '.guessit', 'options.yml') + if os.path.exists(config_file): + return config_file + config_file = os.path.join(basedir, '.config', 'guessit', 'options.yml') + if os.path.exists(config_file): + return config_file + config_file = os.path.join(basedir, '.guessit', 'options.yaml') + if os.path.exists(config_file): + return config_file + config_file = os.path.join(basedir, '.config', 'guessit', 'options.yaml') + if os.path.exists(config_file): + return config_file + return None default_api = GuessItApi(rebulk_builder()) diff --git a/guessit/options.py b/guessit/options.py index be24af48..33d5c792 100644 --- a/guessit/options.py +++ b/guessit/options.py @@ -3,8 +3,8 @@ """ Options """ -from argparse import ArgumentParser import shlex +from argparse import ArgumentParser import six @@ -19,6 +19,12 @@ 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', 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=False, @@ -56,8 +62,6 @@ def build_argument_parser(): output_opts.add_argument('-y', '--yaml', dest='yaml', action='store_true', default=False, help='Display information for filename guesses as yaml output') - - information_opts = opts.add_argument_group("Information") information_opts.add_argument('-p', '--properties', dest='properties', action='store_true', default=False, help='Display properties that can be guessed.')