mirror of
https://github.com/clinton-hall/nzbToMedia.git
synced 2024-11-14 09:30:21 -08:00
56c6773c6b
Updates colorama to 0.4.6 Adds confuse version 1.7.0 Updates jellyfish to 0.9.0 Adds mediafile 0.10.1 Updates munkres to 1.1.4 Updates musicbrainzngs to 0.7.1 Updates mutagen to 1.46.0 Updates pyyaml to 6.0 Updates unidecode to 1.3.6
228 lines
8.8 KiB
Python
228 lines
8.8 KiB
Python
|
|
__all__ = ['BaseResolver', 'Resolver']
|
|
|
|
from .error import *
|
|
from .nodes import *
|
|
|
|
import re
|
|
|
|
class ResolverError(YAMLError):
|
|
pass
|
|
|
|
class BaseResolver:
|
|
|
|
DEFAULT_SCALAR_TAG = 'tag:yaml.org,2002:str'
|
|
DEFAULT_SEQUENCE_TAG = 'tag:yaml.org,2002:seq'
|
|
DEFAULT_MAPPING_TAG = 'tag:yaml.org,2002:map'
|
|
|
|
yaml_implicit_resolvers = {}
|
|
yaml_path_resolvers = {}
|
|
|
|
def __init__(self):
|
|
self.resolver_exact_paths = []
|
|
self.resolver_prefix_paths = []
|
|
|
|
@classmethod
|
|
def add_implicit_resolver(cls, tag, regexp, first):
|
|
if not 'yaml_implicit_resolvers' in cls.__dict__:
|
|
implicit_resolvers = {}
|
|
for key in cls.yaml_implicit_resolvers:
|
|
implicit_resolvers[key] = cls.yaml_implicit_resolvers[key][:]
|
|
cls.yaml_implicit_resolvers = implicit_resolvers
|
|
if first is None:
|
|
first = [None]
|
|
for ch in first:
|
|
cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp))
|
|
|
|
@classmethod
|
|
def add_path_resolver(cls, tag, path, kind=None):
|
|
# Note: `add_path_resolver` is experimental. The API could be changed.
|
|
# `new_path` is a pattern that is matched against the path from the
|
|
# root to the node that is being considered. `node_path` elements are
|
|
# tuples `(node_check, index_check)`. `node_check` is a node class:
|
|
# `ScalarNode`, `SequenceNode`, `MappingNode` or `None`. `None`
|
|
# matches any kind of a node. `index_check` could be `None`, a boolean
|
|
# value, a string value, or a number. `None` and `False` match against
|
|
# any _value_ of sequence and mapping nodes. `True` matches against
|
|
# any _key_ of a mapping node. A string `index_check` matches against
|
|
# a mapping value that corresponds to a scalar key which content is
|
|
# equal to the `index_check` value. An integer `index_check` matches
|
|
# against a sequence value with the index equal to `index_check`.
|
|
if not 'yaml_path_resolvers' in cls.__dict__:
|
|
cls.yaml_path_resolvers = cls.yaml_path_resolvers.copy()
|
|
new_path = []
|
|
for element in path:
|
|
if isinstance(element, (list, tuple)):
|
|
if len(element) == 2:
|
|
node_check, index_check = element
|
|
elif len(element) == 1:
|
|
node_check = element[0]
|
|
index_check = True
|
|
else:
|
|
raise ResolverError("Invalid path element: %s" % element)
|
|
else:
|
|
node_check = None
|
|
index_check = element
|
|
if node_check is str:
|
|
node_check = ScalarNode
|
|
elif node_check is list:
|
|
node_check = SequenceNode
|
|
elif node_check is dict:
|
|
node_check = MappingNode
|
|
elif node_check not in [ScalarNode, SequenceNode, MappingNode] \
|
|
and not isinstance(node_check, str) \
|
|
and node_check is not None:
|
|
raise ResolverError("Invalid node checker: %s" % node_check)
|
|
if not isinstance(index_check, (str, int)) \
|
|
and index_check is not None:
|
|
raise ResolverError("Invalid index checker: %s" % index_check)
|
|
new_path.append((node_check, index_check))
|
|
if kind is str:
|
|
kind = ScalarNode
|
|
elif kind is list:
|
|
kind = SequenceNode
|
|
elif kind is dict:
|
|
kind = MappingNode
|
|
elif kind not in [ScalarNode, SequenceNode, MappingNode] \
|
|
and kind is not None:
|
|
raise ResolverError("Invalid node kind: %s" % kind)
|
|
cls.yaml_path_resolvers[tuple(new_path), kind] = tag
|
|
|
|
def descend_resolver(self, current_node, current_index):
|
|
if not self.yaml_path_resolvers:
|
|
return
|
|
exact_paths = {}
|
|
prefix_paths = []
|
|
if current_node:
|
|
depth = len(self.resolver_prefix_paths)
|
|
for path, kind in self.resolver_prefix_paths[-1]:
|
|
if self.check_resolver_prefix(depth, path, kind,
|
|
current_node, current_index):
|
|
if len(path) > depth:
|
|
prefix_paths.append((path, kind))
|
|
else:
|
|
exact_paths[kind] = self.yaml_path_resolvers[path, kind]
|
|
else:
|
|
for path, kind in self.yaml_path_resolvers:
|
|
if not path:
|
|
exact_paths[kind] = self.yaml_path_resolvers[path, kind]
|
|
else:
|
|
prefix_paths.append((path, kind))
|
|
self.resolver_exact_paths.append(exact_paths)
|
|
self.resolver_prefix_paths.append(prefix_paths)
|
|
|
|
def ascend_resolver(self):
|
|
if not self.yaml_path_resolvers:
|
|
return
|
|
self.resolver_exact_paths.pop()
|
|
self.resolver_prefix_paths.pop()
|
|
|
|
def check_resolver_prefix(self, depth, path, kind,
|
|
current_node, current_index):
|
|
node_check, index_check = path[depth-1]
|
|
if isinstance(node_check, str):
|
|
if current_node.tag != node_check:
|
|
return
|
|
elif node_check is not None:
|
|
if not isinstance(current_node, node_check):
|
|
return
|
|
if index_check is True and current_index is not None:
|
|
return
|
|
if (index_check is False or index_check is None) \
|
|
and current_index is None:
|
|
return
|
|
if isinstance(index_check, str):
|
|
if not (isinstance(current_index, ScalarNode)
|
|
and index_check == current_index.value):
|
|
return
|
|
elif isinstance(index_check, int) and not isinstance(index_check, bool):
|
|
if index_check != current_index:
|
|
return
|
|
return True
|
|
|
|
def resolve(self, kind, value, implicit):
|
|
if kind is ScalarNode and implicit[0]:
|
|
if value == '':
|
|
resolvers = self.yaml_implicit_resolvers.get('', [])
|
|
else:
|
|
resolvers = self.yaml_implicit_resolvers.get(value[0], [])
|
|
wildcard_resolvers = self.yaml_implicit_resolvers.get(None, [])
|
|
for tag, regexp in resolvers + wildcard_resolvers:
|
|
if regexp.match(value):
|
|
return tag
|
|
implicit = implicit[1]
|
|
if self.yaml_path_resolvers:
|
|
exact_paths = self.resolver_exact_paths[-1]
|
|
if kind in exact_paths:
|
|
return exact_paths[kind]
|
|
if None in exact_paths:
|
|
return exact_paths[None]
|
|
if kind is ScalarNode:
|
|
return self.DEFAULT_SCALAR_TAG
|
|
elif kind is SequenceNode:
|
|
return self.DEFAULT_SEQUENCE_TAG
|
|
elif kind is MappingNode:
|
|
return self.DEFAULT_MAPPING_TAG
|
|
|
|
class Resolver(BaseResolver):
|
|
pass
|
|
|
|
Resolver.add_implicit_resolver(
|
|
'tag:yaml.org,2002:bool',
|
|
re.compile(r'''^(?:yes|Yes|YES|no|No|NO
|
|
|true|True|TRUE|false|False|FALSE
|
|
|on|On|ON|off|Off|OFF)$''', re.X),
|
|
list('yYnNtTfFoO'))
|
|
|
|
Resolver.add_implicit_resolver(
|
|
'tag:yaml.org,2002:float',
|
|
re.compile(r'''^(?:[-+]?(?:[0-9][0-9_]*)\.[0-9_]*(?:[eE][-+][0-9]+)?
|
|
|\.[0-9][0-9_]*(?:[eE][-+][0-9]+)?
|
|
|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*
|
|
|[-+]?\.(?:inf|Inf|INF)
|
|
|\.(?:nan|NaN|NAN))$''', re.X),
|
|
list('-+0123456789.'))
|
|
|
|
Resolver.add_implicit_resolver(
|
|
'tag:yaml.org,2002:int',
|
|
re.compile(r'''^(?:[-+]?0b[0-1_]+
|
|
|[-+]?0[0-7_]+
|
|
|[-+]?(?:0|[1-9][0-9_]*)
|
|
|[-+]?0x[0-9a-fA-F_]+
|
|
|[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X),
|
|
list('-+0123456789'))
|
|
|
|
Resolver.add_implicit_resolver(
|
|
'tag:yaml.org,2002:merge',
|
|
re.compile(r'^(?:<<)$'),
|
|
['<'])
|
|
|
|
Resolver.add_implicit_resolver(
|
|
'tag:yaml.org,2002:null',
|
|
re.compile(r'''^(?: ~
|
|
|null|Null|NULL
|
|
| )$''', re.X),
|
|
['~', 'n', 'N', ''])
|
|
|
|
Resolver.add_implicit_resolver(
|
|
'tag:yaml.org,2002:timestamp',
|
|
re.compile(r'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
|
|
|[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]?
|
|
(?:[Tt]|[ \t]+)[0-9][0-9]?
|
|
:[0-9][0-9] :[0-9][0-9] (?:\.[0-9]*)?
|
|
(?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X),
|
|
list('0123456789'))
|
|
|
|
Resolver.add_implicit_resolver(
|
|
'tag:yaml.org,2002:value',
|
|
re.compile(r'^(?:=)$'),
|
|
['='])
|
|
|
|
# The following resolver is only for documentation purposes. It cannot work
|
|
# because plain scalars cannot start with '!', '&', or '*'.
|
|
Resolver.add_implicit_resolver(
|
|
'tag:yaml.org,2002:yaml',
|
|
re.compile(r'^(?:!|&|\*)$'),
|
|
list('!&*'))
|
|
|