#!/usr/bin/env python # -*- coding: utf-8 -*- """ API functions that can be used by external software """ try: from collections import OrderedDict except ImportError: # pragma: no-cover from ordereddict import OrderedDict # pylint:disable=import-error import traceback import six from rebulk.introspector import introspect from .rules import rebulk_builder from .options import parse_options from .__version__ import __version__ 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" "version=%s\n" "string=%s\n" "options=%s\n" "--------------------------------------------------------------------\n" "%s" "--------------------------------------------------------------------\n" "Please report at " "https://github.com/guessit-io/guessit/issues.\n" "====================================================================" % (__version__, str(string), str(options), traceback.format_exc())) self.string = string self.options = options def guessit(string, options=None): """ Retrieves all matches from string as a dict :param string: the filename or release name :type string: str :param options: the filename or release name :type options: str|dict :return: :rtype: """ return default_api.guessit(string, options) def properties(options=None): """ Retrieves all properties with possible values that can be guessed :param options: :type options: :return: :rtype: """ return default_api.properties(options) class GuessItApi(object): """ An api class that can be configured with custom Rebulk configuration. """ def __init__(self, rebulk): """ :param rebulk: Rebulk instance to use. :type rebulk: Rebulk :return: :rtype: """ self.rebulk = rebulk @staticmethod def _fix_option_encoding(value): if isinstance(value, list): return [GuessItApi._fix_option_encoding(item) for item in value] if six.PY2 and isinstance(value, six.text_type): return value.encode("utf-8") if six.PY3 and isinstance(value, six.binary_type): return value.decode('ascii') return value def guessit(self, string, options=None): """ Retrieves all matches from string as a dict :param string: the filename or release name :type string: str :param options: the filename or release name :type options: str|dict :return: :rtype: """ try: options = parse_options(options, True) result_decode = False result_encode = False fixed_options = {} for (key, value) in options.items(): key = GuessItApi._fix_option_encoding(key) value = GuessItApi._fix_option_encoding(value) fixed_options[key] = value options = fixed_options if six.PY2 and isinstance(string, six.text_type): string = string.encode("utf-8") result_decode = True if six.PY3 and isinstance(string, six.binary_type): string = string.decode('ascii') result_encode = True matches = self.rebulk.matches(string, options) if result_decode: for match in matches: if isinstance(match.value, six.binary_type): match.value = match.value.decode("utf-8") if result_encode: for match in matches: if isinstance(match.value, six.text_type): match.value = match.value.encode("ascii") return matches.to_dict(options.get('advanced', False), options.get('single_value', False), options.get('enforce_list', False)) except: raise GuessitException(string, options) def properties(self, options=None): """ Grab properties and values that can be generated. :param options: :type options: :return: :rtype: """ unordered = introspect(self.rebulk, options).properties ordered = OrderedDict() for k in sorted(unordered.keys(), key=six.text_type): ordered[k] = list(sorted(unordered[k], key=six.text_type)) if hasattr(self.rebulk, 'customize_properties'): ordered = self.rebulk.customize_properties(ordered) return ordered default_api = GuessItApi(rebulk_builder())