mirror of
https://github.com/rembo10/headphones.git
synced 2026-03-20 19:59:26 +00:00
- Delete from Releases when deleting artist/album - Searcher - Size limits not quite working - Searcher - 1st newznab used even if disabled - Rutracker search stopped working for me, fixed by updating Beautiful Soup. Moved bs4 and html5lib to lib and ensured (I think) it’s imported from the right place
83 lines
2.5 KiB
Python
83 lines
2.5 KiB
Python
from __future__ import absolute_import, division, unicode_literals
|
|
|
|
from types import ModuleType
|
|
|
|
try:
|
|
import xml.etree.cElementTree as default_etree
|
|
except ImportError:
|
|
import xml.etree.ElementTree as default_etree
|
|
|
|
|
|
__all__ = ["default_etree", "MethodDispatcher", "isSurrogatePair",
|
|
"surrogatePairToCodepoint", "moduleFactoryFactory"]
|
|
|
|
|
|
class MethodDispatcher(dict):
|
|
"""Dict with 2 special properties:
|
|
|
|
On initiation, keys that are lists, sets or tuples are converted to
|
|
multiple keys so accessing any one of the items in the original
|
|
list-like object returns the matching value
|
|
|
|
md = MethodDispatcher({("foo", "bar"):"baz"})
|
|
md["foo"] == "baz"
|
|
|
|
A default value which can be set through the default attribute.
|
|
"""
|
|
|
|
def __init__(self, items=()):
|
|
# Using _dictEntries instead of directly assigning to self is about
|
|
# twice as fast. Please do careful performance testing before changing
|
|
# anything here.
|
|
_dictEntries = []
|
|
for name, value in items:
|
|
if type(name) in (list, tuple, frozenset, set):
|
|
for item in name:
|
|
_dictEntries.append((item, value))
|
|
else:
|
|
_dictEntries.append((name, value))
|
|
dict.__init__(self, _dictEntries)
|
|
self.default = None
|
|
|
|
def __getitem__(self, key):
|
|
return dict.get(self, key, self.default)
|
|
|
|
|
|
# Some utility functions to dal with weirdness around UCS2 vs UCS4
|
|
# python builds
|
|
|
|
def isSurrogatePair(data):
|
|
return (len(data) == 2 and
|
|
ord(data[0]) >= 0xD800 and ord(data[0]) <= 0xDBFF and
|
|
ord(data[1]) >= 0xDC00 and ord(data[1]) <= 0xDFFF)
|
|
|
|
|
|
def surrogatePairToCodepoint(data):
|
|
char_val = (0x10000 + (ord(data[0]) - 0xD800) * 0x400 +
|
|
(ord(data[1]) - 0xDC00))
|
|
return char_val
|
|
|
|
# Module Factory Factory (no, this isn't Java, I know)
|
|
# Here to stop this being duplicated all over the place.
|
|
|
|
|
|
def moduleFactoryFactory(factory):
|
|
moduleCache = {}
|
|
|
|
def moduleFactory(baseModule, *args, **kwargs):
|
|
if isinstance(ModuleType.__name__, type("")):
|
|
name = "_%s_factory" % baseModule.__name__
|
|
else:
|
|
name = b"_%s_factory" % baseModule.__name__
|
|
|
|
if name in moduleCache:
|
|
return moduleCache[name]
|
|
else:
|
|
mod = ModuleType(name)
|
|
objs = factory(baseModule, *args, **kwargs)
|
|
mod.__dict__.update(objs)
|
|
moduleCache[name] = mod
|
|
return mod
|
|
|
|
return moduleFactory
|