common.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. '''
  2. xbmcswift2.common
  3. -----------------
  4. This module contains some common helpful functions.
  5. :copyright: (c) 2012 by Jonathan Beluch
  6. :license: GPLv3, see LICENSE for more details.
  7. '''
  8. try:
  9. import urllib.request as urllib_request #for python 3
  10. import urllib.parse as urllib_parse #for python 3
  11. except ImportError:
  12. import urllib2 as urllib_request # for python 2
  13. import urllib as urllib_parse
  14. try:
  15. import cPickle as pickle
  16. except ImportError:
  17. import pickle
  18. def xbmc_url(url, **options):
  19. '''Appends key/val pairs to the end of a URL. Useful for passing arbitrary
  20. HTTP headers to XBMC to be used when fetching a media resource, e.g.
  21. cookies.
  22. '''
  23. optionstring = urllib_parse.urlencode(options)
  24. if optionstring:
  25. return url + '|' + optionstring
  26. return url
  27. def enum(*args, **kwargs):
  28. '''An enum class to mirror XBMC constatns. All args and kwargs.keys are
  29. added as atrrs on the returned object.
  30. >>> States = enum('NEW_JERSEY', NY='NEW_YORK')
  31. >>> States.NY
  32. 'NEW_YORK'
  33. >>> States.NEW_JERSEY
  34. 'NEW_JERSEY'
  35. >>> States._fields
  36. ['NY', 'NEW_JERSEY']
  37. '''
  38. kwargs.update((arg, arg) for arg in args)
  39. kwargs['_fields'] = kwargs.keys()
  40. return type('Enum', (), kwargs)
  41. Modes = enum('XBMC', 'ONCE', 'CRAWL', 'INTERACTIVE')
  42. DEBUG_MODES = [Modes.ONCE, Modes.CRAWL, Modes.INTERACTIVE]
  43. def clean_dict(dct):
  44. '''Returns a dict where items with a None value are removed'''
  45. return dict((key, val) for key, val in dct.items() if val is not None)
  46. def pickle_dict(items):
  47. '''Returns a new dictionary where values which aren't instances of
  48. basestring are pickled. Also, a new key '_pickled' contains a comma
  49. separated list of keys corresponding to the pickled values.
  50. '''
  51. ret = {}
  52. pickled_keys = []
  53. for key, val in items.items():
  54. if isinstance(val, basestring):
  55. ret[key] = val
  56. else:
  57. pickled_keys.append(key)
  58. ret[key] = pickle.dumps(val)
  59. if pickled_keys:
  60. ret['_pickled'] = ','.join(pickled_keys)
  61. return ret
  62. def unpickle_args(items):
  63. '''Takes a dict and unpickles values whose keys are found in
  64. '_pickled' key.
  65. >>> unpickle_args({'_pickled': ['foo']. 'foo': ['I3%0A.']})
  66. {'foo': 3}
  67. '''
  68. # Technically there can be more than one _pickled value. At this point
  69. # we'll just use the first one
  70. pickled = items.pop('_pickled', None)
  71. if pickled is None:
  72. return items
  73. pickled_keys = pickled[0].split(',')
  74. ret = {}
  75. for key, vals in items.items():
  76. if key in pickled_keys:
  77. ret[key] = [pickle.loads(val) for val in vals]
  78. else:
  79. ret[key] = vals
  80. return ret
  81. def unpickle_dict(items):
  82. '''Returns a dict pickled with pickle_dict'''
  83. pickled_keys = items.pop('_pickled', '').split(',')
  84. ret = {}
  85. for key, val in items.items():
  86. if key in pickled_keys:
  87. ret[key] = pickle.loads(val)
  88. else:
  89. ret[key] = val
  90. return ret
  91. def download_page(url, data=None):
  92. '''Returns the response for the given url. The optional data argument is
  93. passed directly to urlopen.'''
  94. return None
  95. _hextochr = dict(('%02x' % i, chr(i)) for i in range(256))
  96. _hextochr.update(('%02X' % i, chr(i)) for i in range(256))
  97. def unhex(inp):
  98. '''unquote(r'abc\x20def') -> 'abc def'.'''
  99. res = inp.split(r'\x')
  100. for i in xrange(1, len(res)):
  101. item = res[i]
  102. try:
  103. res[i] = _hextochr[item[:2]] + item[2:]
  104. except KeyError:
  105. res[i] = '%' + item
  106. except UnicodeDecodeError:
  107. res[i] = unichr(int(item[:2], 16)) + item[2:]
  108. return ''.join(res)