mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-02 17:33:37 +00:00
980e05cc99
Backported 400 revisions from rev 1de4961-8897c5b (2018-2014). Move core/benchmark, core/cmd_line, core/memory, core/profiler and core/timeout to core/optional/* Remove metadata/qt* PORT: Version 2.0a3 (inline with 3.0a3 @ f80c7d5). Basic Support for XMP Packets. tga: improvements to adhere more closely to the spec. pdf: slightly improved parsing. rar: fix TypeError on unknown block types. Add MacRoman win32 codepage. tiff/exif: support SubIFDs and tiled images. Add method to export metadata in dictionary. mpeg_video: don't attempt to parse Stream past length. mpeg_video: parse ESCR correctly, add SCR value. Change centralise CustomFragments. field: don't set parser class if class is None, to enable autodetect. field: add value/display for CustomFragment. parser: inline warning to enable tracebacks in debug mode. Fix empty bytestrings in makePrintable. Fix contentSize in jpeg.py to account for image_data blocks. Fix the ELF parser. Enhance the AR archive parser. elf parser: fix wrong wrong fields order in parsing little endian section flags. elf parser: add s390 as a machine type. Flesh out mp4 parser. PORT: Version 2.0a1 (inline with 3.0a1). Major refactoring and PEP8. Fix ResourceWarning warnings on files. Add a close() method and support for the context manager protocol ("with obj: ...") to parsers, input and output streams. metadata: get comment from ZIP. Support for InputIOStream.read(0). Fix sizeGe when size is None. Remove unused new_seekable_field_set file. Remove parser Mapsforge .map. Remove parser Parallel Realities Starfighter .pak files. sevenzip: fix for newer archives. java: update access flags and modifiers for Java 1.7 and update description text for most recent Java. Support ustar prefix field in tar archives. Remove file_system* parsers. Remove misc parsers 3d0, 3ds, gnome_keyring, msoffice*, mstask, ole*, word*. Remove program parsers macho, nds, prc. Support non-8bit Character subclasses. Python parser supports Python 3.7. Enhance mpeg_ts parser to support MTS/M2TS. Support for creation date in tiff. Change don't hardcode errno constant. PORT: 1.9.1 Internal Only: The following are legacy reference to upstream commit messages. Relevant changes up to b0a115f8. Use integer division. Replace HACHOIR_ERRORS with Exception. Fix metadata.Data: make it sortable. Import fixes from e7de492. PORT: Version 2.0a1 (inline with 3.0a1 @ e9f8fad). Replace hachoir.core.field with hachoir.field Replace hachoir.core.stream with hachoir.stream Remove the compatibility module for PY1.5 to PY2.5. metadata: support TIFF picture. metadata: fix string normalization. metadata: fix datetime regex Fix hachoir bug #57. FileFromInputStream: fix comparison between None and an int. InputIOStream: open the file in binary mode.
152 lines
5 KiB
Python
152 lines
5 KiB
Python
from hachoir.core.tools import makeUnicode, normalizeNewline
|
|
from hachoir.metadata import config
|
|
from hachoir.metadata.setter import normalizeString
|
|
|
|
MIN_PRIORITY = 100
|
|
MAX_PRIORITY = 999
|
|
|
|
QUALITY_FASTEST = 0.0
|
|
QUALITY_FAST = 0.25
|
|
QUALITY_NORMAL = 0.5
|
|
QUALITY_GOOD = 0.75
|
|
QUALITY_BEST = 1.0
|
|
|
|
|
|
class DataValue:
|
|
def __init__(self, value, text):
|
|
self.value = value
|
|
self.text = text
|
|
|
|
|
|
class Data:
|
|
def __init__(self, key, priority, description,
|
|
text_handler=None, type=None, filter=None, conversion=None):
|
|
"""
|
|
handler is only used if value is not string nor unicode, prototype:
|
|
def handler(value) -> str/unicode
|
|
"""
|
|
assert MIN_PRIORITY <= priority <= MAX_PRIORITY
|
|
assert isinstance(description, unicode)
|
|
self.metadata = None
|
|
self.key = key
|
|
self.description = description
|
|
self.values = []
|
|
if type and not isinstance(type, (tuple, list)):
|
|
type = (type,)
|
|
self.type = type
|
|
self.text_handler = text_handler
|
|
self.filter = filter
|
|
self.priority = priority
|
|
self.conversion = conversion
|
|
|
|
def __lt__(self, other):
|
|
return self.priority < other.priority
|
|
|
|
def _createItem(self, value, text=None):
|
|
if text is None:
|
|
if isinstance(value, unicode):
|
|
text = value
|
|
elif self.text_handler:
|
|
text = self.text_handler(value)
|
|
assert isinstance(text, unicode)
|
|
else:
|
|
text = makeUnicode(value)
|
|
return DataValue(value, text)
|
|
|
|
def add(self, value):
|
|
if isinstance(value, tuple):
|
|
if len(value) != 2:
|
|
raise ValueError("Data.add() only accept "
|
|
"tuple of 2 elements: (value,text)")
|
|
value, text = value
|
|
else:
|
|
text = None
|
|
|
|
# Skip value 'None'
|
|
if value is None:
|
|
return
|
|
|
|
# Convert string to Unicode string using charset ISO-8859-1
|
|
if self.conversion:
|
|
try:
|
|
new_value = self.conversion(self.metadata, self.key, value)
|
|
except Exception as err:
|
|
self.metadata.warning("Error during conversion of %r value: %s"
|
|
% (self.key, err))
|
|
return
|
|
if new_value is None:
|
|
dest_types = " or ".join(str(item.__name__)
|
|
for item in self.type)
|
|
self.metadata.warning("Unable to convert %s=%r (%s) to %s" % (
|
|
self.key, value, type(value).__name__, dest_types))
|
|
return
|
|
if isinstance(new_value, tuple):
|
|
if text:
|
|
value = new_value[0]
|
|
else:
|
|
value, text = new_value
|
|
else:
|
|
value = new_value
|
|
elif isinstance(value, str):
|
|
value = unicode(value, "ISO-8859-1")
|
|
|
|
if isinstance(value, (str, unicode)):
|
|
value = normalizeString(value)
|
|
if not value:
|
|
return
|
|
|
|
if self.type and not isinstance(value, self.type):
|
|
dest_types = " or ".join(str(item.__name__) for item in self.type)
|
|
self.metadata.warning("Key %r: value %r type (%s) is not %s" % (
|
|
self.key, value, type(value).__name__, dest_types))
|
|
return
|
|
|
|
# Skip empty strings
|
|
if isinstance(value, unicode):
|
|
value = normalizeNewline(value)
|
|
if (config.MAX_STR_LENGTH
|
|
and config.MAX_STR_LENGTH < len(value)):
|
|
value = value[:config.MAX_STR_LENGTH] + "(...)"
|
|
|
|
# Skip duplicates
|
|
if value in self:
|
|
return
|
|
|
|
# Use filter
|
|
if self.filter and not self.filter(value):
|
|
self.metadata.warning("Skip value %s=%r (filter)"
|
|
% (self.key, value))
|
|
return
|
|
|
|
# For string, if you have "verlongtext" and "verylo",
|
|
# keep the longer value
|
|
if isinstance(value, unicode):
|
|
for index, item in enumerate(self.values):
|
|
item = item.value
|
|
if not isinstance(item, unicode):
|
|
continue
|
|
if value.startswith(item):
|
|
# Find longer value, replace the old one
|
|
self.values[index] = self._createItem(value, text)
|
|
return
|
|
if item.startswith(value):
|
|
# Find truncated value, skip it
|
|
return
|
|
|
|
# Add new value
|
|
self.values.append(self._createItem(value, text))
|
|
|
|
def __len__(self):
|
|
return len(self.values)
|
|
|
|
def __getitem__(self, index):
|
|
return self.values[index]
|
|
|
|
def __contains__(self, value):
|
|
for item in self.values:
|
|
if value == item.value:
|
|
return True
|
|
return False
|
|
|
|
def __cmp__(self, other):
|
|
return cmp(self.priority, other.priority)
|