134 lines
3.5 KiB
Python
134 lines
3.5 KiB
Python
|
'''
|
||
|
xbmcswift2.common
|
||
|
-----------------
|
||
|
|
||
|
This module contains some common helpful functions.
|
||
|
|
||
|
:copyright: (c) 2012 by Jonathan Beluch
|
||
|
:license: GPLv3, see LICENSE for more details.
|
||
|
'''
|
||
|
|
||
|
from urllib import urlencode
|
||
|
from urllib2 import urlopen
|
||
|
|
||
|
try:
|
||
|
import cPickle as pickle
|
||
|
except ImportError:
|
||
|
import pickle
|
||
|
|
||
|
|
||
|
def xbmc_url(url, **options):
|
||
|
'''Appends key/val pairs to the end of a URL. Useful for passing arbitrary
|
||
|
HTTP headers to KODI to be used when fetching a media resource, e.g.
|
||
|
cookies.
|
||
|
'''
|
||
|
optionstring = urlencode(options)
|
||
|
if optionstring:
|
||
|
return url + '|' + optionstring
|
||
|
return url
|
||
|
|
||
|
|
||
|
def enum(*args, **kwargs):
|
||
|
'''An enum class to mirror KODI constatns. All args and kwargs.keys are
|
||
|
added as atrrs on the returned object.
|
||
|
|
||
|
>>> States = enum('NEW_JERSEY', NY='NEW_YORK')
|
||
|
>>> States.NY
|
||
|
'NEW_YORK'
|
||
|
>>> States.NEW_JERSEY
|
||
|
'NEW_JERSEY'
|
||
|
>>> States._fields
|
||
|
['NY', 'NEW_JERSEY']
|
||
|
'''
|
||
|
kwargs.update((arg, arg) for arg in args)
|
||
|
kwargs['_fields'] = kwargs.keys()
|
||
|
return type('Enum', (), kwargs)
|
||
|
|
||
|
|
||
|
Modes = enum('XBMC', 'ONCE', 'CRAWL', 'INTERACTIVE')
|
||
|
DEBUG_MODES = [Modes.ONCE, Modes.CRAWL, Modes.INTERACTIVE]
|
||
|
|
||
|
|
||
|
def clean_dict(dct):
|
||
|
'''Returns a dict where items with a None value are removed'''
|
||
|
return dict((key, val) for key, val in dct.items() if val is not None)
|
||
|
|
||
|
|
||
|
def pickle_dict(items):
|
||
|
'''Returns a new dictionary where values which aren't instances of
|
||
|
basestring are pickled. Also, a new key '_pickled' contains a comma
|
||
|
separated list of keys corresponding to the pickled values.
|
||
|
'''
|
||
|
ret = {}
|
||
|
pickled_keys = []
|
||
|
for key, val in items.items():
|
||
|
if isinstance(val, basestring):
|
||
|
ret[key] = val
|
||
|
else:
|
||
|
pickled_keys.append(key)
|
||
|
ret[key] = pickle.dumps(val)
|
||
|
if pickled_keys:
|
||
|
ret['_pickled'] = ','.join(pickled_keys)
|
||
|
return ret
|
||
|
|
||
|
|
||
|
def unpickle_args(items):
|
||
|
'''Takes a dict and unpickles values whose keys are found in
|
||
|
'_pickled' key.
|
||
|
|
||
|
>>> unpickle_args({'_pickled': ['foo']. 'foo': ['I3%0A.']})
|
||
|
{'foo': 3}
|
||
|
'''
|
||
|
# Technically there can be more than one _pickled value. At this point
|
||
|
# we'll just use the first one
|
||
|
pickled= items.pop('_pickled', None)
|
||
|
if pickled is None:
|
||
|
return items
|
||
|
|
||
|
pickled_keys = pickled[0].split(',')
|
||
|
ret = {}
|
||
|
for key, vals in items.items():
|
||
|
if key in pickled_keys:
|
||
|
ret[key] = [pickle.loads(val) for val in vals]
|
||
|
else:
|
||
|
ret[key] = vals
|
||
|
return ret
|
||
|
|
||
|
def unpickle_dict(items):
|
||
|
'''Returns a dict pickled with pickle_dict'''
|
||
|
pickled_keys = items.pop('_pickled', '').split(',')
|
||
|
ret = {}
|
||
|
for key, val in items.items():
|
||
|
if key in pickled_keys:
|
||
|
ret[key] = pickle.loads(val)
|
||
|
else:
|
||
|
ret[key] = val
|
||
|
return ret
|
||
|
|
||
|
|
||
|
def download_page(url, data=None):
|
||
|
'''Returns the response for the given url. The optional data argument is
|
||
|
passed directly to urlopen.'''
|
||
|
conn = urlopen(url, data)
|
||
|
resp = conn.read()
|
||
|
conn.close()
|
||
|
return resp
|
||
|
|
||
|
|
||
|
_hextochr = dict(('%02x' % i, chr(i)) for i in range(256))
|
||
|
_hextochr.update(('%02X' % i, chr(i)) for i in range(256))
|
||
|
|
||
|
|
||
|
def unhex(inp):
|
||
|
'''unquote(r'abc\x20def') -> 'abc def'.'''
|
||
|
res = inp.split(r'\x')
|
||
|
for i in xrange(1, len(res)):
|
||
|
item = res[i]
|
||
|
try:
|
||
|
res[i] = _hextochr[item[:2]] + item[2:]
|
||
|
except KeyError:
|
||
|
res[i] = '%' + item
|
||
|
except UnicodeDecodeError:
|
||
|
res[i] = unichr(int(item[:2], 16)) + item[2:]
|
||
|
return ''.join(res)
|