mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-11 05: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.
185 lines
5.2 KiB
Python
185 lines
5.2 KiB
Python
"""
|
|
Dictionnary classes which store values order.
|
|
"""
|
|
|
|
from hachoir.core.i18n import _
|
|
|
|
|
|
class UniqKeyError(Exception):
|
|
"""
|
|
Error raised when a value is set whereas the key already exist in a
|
|
dictionnary.
|
|
"""
|
|
pass
|
|
|
|
|
|
class Dict(object):
|
|
"""
|
|
This class works like classic Python dict() but has an important method:
|
|
__iter__() which allow to iterate into the dictionnary _values_ (and not
|
|
keys like Python's dict does).
|
|
"""
|
|
|
|
def __init__(self, values=None):
|
|
self._index = {} # key => index
|
|
self._key_list = [] # index => key
|
|
self._value_list = [] # index => value
|
|
if values:
|
|
for key, value in values:
|
|
self.append(key, value)
|
|
|
|
def _getValues(self):
|
|
return self._value_list
|
|
|
|
values = property(_getValues)
|
|
|
|
def index(self, key):
|
|
"""
|
|
Search a value by its key and returns its index
|
|
Returns None if the key doesn't exist.
|
|
|
|
>>> d=Dict( (("two", "deux"), ("one", "un")) )
|
|
>>> d.index("two")
|
|
0
|
|
>>> d.index("one")
|
|
1
|
|
>>> d.index("three") is None
|
|
True
|
|
"""
|
|
return self._index.get(key)
|
|
|
|
def __getitem__(self, key):
|
|
"""
|
|
Get item with specified key.
|
|
To get a value by it's index, use mydict.values[index]
|
|
|
|
>>> d=Dict( (("two", "deux"), ("one", "un")) )
|
|
>>> d["one"]
|
|
'un'
|
|
"""
|
|
return self._value_list[self._index[key]]
|
|
|
|
def __setitem__(self, key, value):
|
|
self._value_list[self._index[key]] = value
|
|
|
|
def append(self, key, value):
|
|
"""
|
|
Append new value
|
|
"""
|
|
if key in self._index:
|
|
raise UniqKeyError(_("Key '%s' already exists") % key)
|
|
self._index[key] = len(self._value_list)
|
|
self._key_list.append(key)
|
|
self._value_list.append(value)
|
|
|
|
def __len__(self):
|
|
return len(self._value_list)
|
|
|
|
def __contains__(self, key):
|
|
return key in self._index
|
|
|
|
def __iter__(self):
|
|
return iter(self._value_list)
|
|
|
|
def iteritems(self):
|
|
"""
|
|
Create a generator to iterate on: (key, value).
|
|
|
|
>>> d=Dict( (("two", "deux"), ("one", "un")) )
|
|
>>> for key, value in d.iteritems():
|
|
... print "%r: %r" % (key, value)
|
|
...
|
|
'two': 'deux'
|
|
'one': 'un'
|
|
"""
|
|
for index in xrange(len(self)):
|
|
yield (self._key_list[index], self._value_list[index])
|
|
|
|
def itervalues(self):
|
|
"""
|
|
Create an iterator on values
|
|
"""
|
|
return iter(self._value_list)
|
|
|
|
def iterkeys(self):
|
|
"""
|
|
Create an iterator on keys
|
|
"""
|
|
return iter(self._key_list)
|
|
|
|
def replace(self, oldkey, newkey, new_value):
|
|
"""
|
|
Replace an existing value with another one
|
|
|
|
>>> d=Dict( (("two", "deux"), ("one", "un")) )
|
|
>>> d.replace("one", "three", 3)
|
|
>>> d
|
|
{'two': 'deux', 'three': 3}
|
|
|
|
You can also use the classic form:
|
|
|
|
>>> d['three'] = 4
|
|
>>> d
|
|
{'two': 'deux', 'three': 4}
|
|
"""
|
|
index = self._index[oldkey]
|
|
self._value_list[index] = new_value
|
|
if oldkey != newkey:
|
|
del self._index[oldkey]
|
|
self._index[newkey] = index
|
|
self._key_list[index] = newkey
|
|
|
|
def __delitem__(self, index):
|
|
"""
|
|
Delete item at position index. May raise IndexError.
|
|
|
|
>>> d=Dict( ((6, 'six'), (9, 'neuf'), (4, 'quatre')) )
|
|
>>> del d[1]
|
|
>>> d
|
|
{6: 'six', 4: 'quatre'}
|
|
"""
|
|
if index < 0:
|
|
index += len(self._value_list)
|
|
if not (0 <= index < len(self._value_list)):
|
|
raise IndexError(_("list assignment index out of range (%s/%s)")
|
|
% (index, len(self._value_list)))
|
|
del self._value_list[index]
|
|
del self._key_list[index]
|
|
|
|
# First loop which may alter self._index
|
|
for key, item_index in self._index.iteritems():
|
|
if item_index == index:
|
|
del self._index[key]
|
|
break
|
|
|
|
# Second loop update indexes
|
|
for key, item_index in self._index.iteritems():
|
|
if index < item_index:
|
|
self._index[key] -= 1
|
|
|
|
def insert(self, index, key, value):
|
|
"""
|
|
Insert an item at specified position index.
|
|
|
|
>>> d=Dict( ((6, 'six'), (9, 'neuf'), (4, 'quatre')) )
|
|
>>> d.insert(1, '40', 'quarante')
|
|
>>> d
|
|
{6: 'six', '40': 'quarante', 9: 'neuf', 4: 'quatre'}
|
|
"""
|
|
if key in self:
|
|
raise UniqKeyError(_("Insert error: key '%s' ready exists") % key)
|
|
_index = index
|
|
if index < 0:
|
|
index += len(self._value_list)
|
|
if not (0 <= index <= len(self._value_list)):
|
|
raise IndexError(_("Insert error: index '%s' is invalid") % _index)
|
|
for item_key, item_index in self._index.iteritems():
|
|
if item_index >= index:
|
|
self._index[item_key] += 1
|
|
self._index[key] = index
|
|
self._key_list.insert(index, key)
|
|
self._value_list.insert(index, value)
|
|
|
|
def __repr__(self):
|
|
items = ("%r: %r" % (key, value) for key, value in self.iteritems())
|
|
return "{%s}" % ", ".join(items)
|