The branch, frodo has been updated
via 16a7288a6066e7444119d7fa0c511a19e9626e42 (commit)
from c9f871cd2e206a2d82d37a5047895a165a7a0833 (commit)
- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/scripts;a=commit;h=16a7288a6066e7444119d7fa0c511a19e9626e42
commit 16a7288a6066e7444119d7fa0c511a19e9626e42
Author: Martijn Kaijser <[email protected]>
Date: Tue Nov 27 17:59:27 2012 +0100
[script.module.xbmcswift2] -1.3
diff --git a/script.module.xbmcswift2/addon.xml
b/script.module.xbmcswift2/addon.xml
index 86b96fb..d4d818f 100644
--- a/script.module.xbmcswift2/addon.xml
+++ b/script.module.xbmcswift2/addon.xml
@@ -1,4 +1,4 @@
-<addon id="script.module.xbmcswift2" name="xbmcswift2" provider-name="Jonathan
Beluch (jbel)" version="1.2.0">
+<addon id="script.module.xbmcswift2" name="xbmcswift2" provider-name="Jonathan
Beluch (jbel)" version="1.3">
<requires>
<import addon="xbmc.python" version="2.0" />
</requires>
diff --git a/script.module.xbmcswift2/changelog.txt
b/script.module.xbmcswift2/changelog.txt
index bb8ccc2..c551282 100644
--- a/script.module.xbmcswift2/changelog.txt
+++ b/script.module.xbmcswift2/changelog.txt
@@ -1,6 +1,16 @@
CHANGES
=======
+Version 1.3
+-----------
+
+- Update usages of pickle to use cPickle if available.
+- Allow settings to be specified as environment variables when running in CLI
+ mode. e.g. to set a username, the environment variable will be
+ XBMCSWIFT2_USERNAME.
+- Add new keyboard helper method available on a plugin instance.
+- Allow TTL to be specified as an arg to the cached_route decorator.
+
Version 1.2
-----------
diff --git a/script.module.xbmcswift2/lib/xbmcswift2/__init__.py
b/script.module.xbmcswift2/lib/xbmcswift2/__init__.py
index 8c411d1..f7a9ca0 100644
--- a/script.module.xbmcswift2/lib/xbmcswift2/__init__.py
+++ b/script.module.xbmcswift2/lib/xbmcswift2/__init__.py
@@ -36,7 +36,7 @@ class module(ModuleType):
'''
log.warning('The %s method has not been implented on the CLI. '
'Your code might not work properly when calling '
- 'it.' % name)
+ 'it.', name)
return self
return func
diff --git a/script.module.xbmcswift2/lib/xbmcswift2/common.py
b/script.module.xbmcswift2/lib/xbmcswift2/common.py
index 66a658d..46d5580 100644
--- a/script.module.xbmcswift2/lib/xbmcswift2/common.py
+++ b/script.module.xbmcswift2/lib/xbmcswift2/common.py
@@ -7,17 +7,23 @@
:copyright: (c) 2012 by Jonathan Beluch
:license: GPLv3, see LICENSE for more details.
'''
-import pickle
+import urllib
import urllib2
+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 creating XBMC urls
- with options, such as RTMP urls with playpath.
+ '''Appends key/val pairs to the end of a URL. Useful for passing arbitrary
+ HTTP headers to XBMC to be used when fetching a media resource, e.g.
+ cookies.
'''
- optionstring = ' '.join('%s=%s' % (key, val)
- for key, val in options.items())
- return ' '.join([url, optionstring]).strip()
+ optionstring = urllib.urlencode(options)
+ if optionstring:
+ return url + '|' + optionstring
+ return url
def enum(*args, **kwargs):
diff --git a/script.module.xbmcswift2/lib/xbmcswift2/logger.py
b/script.module.xbmcswift2/lib/xbmcswift2/logger.py
index 13a27e1..d7341f2 100644
--- a/script.module.xbmcswift2/lib/xbmcswift2/logger.py
+++ b/script.module.xbmcswift2/lib/xbmcswift2/logger.py
@@ -71,7 +71,10 @@ class XBMCFilter(object):
return False
-GLOBAL_LOG_LEVEL = logging.INFO
+if CLI_MODE:
+ GLOBAL_LOG_LEVEL = logging.INFO
+else:
+ GLOBAL_LOG_LEVEL = logging.DEBUG
def setup_log(name):
diff --git a/script.module.xbmcswift2/lib/xbmcswift2/plugin.py
b/script.module.xbmcswift2/lib/xbmcswift2/plugin.py
index eaad77b..a88994a 100644
--- a/script.module.xbmcswift2/lib/xbmcswift2/plugin.py
+++ b/script.module.xbmcswift2/lib/xbmcswift2/plugin.py
@@ -217,11 +217,18 @@ class Plugin(XBMCMixin):
for func in module._register_funcs:
func(self, url_prefix)
- def cached_route(self, url_rule, name=None, options=None):
- '''A decorator to add a route to a view and also apply caching.
+ def cached_route(self, url_rule, name=None, options=None, TTL=None):
+ '''A decorator to add a route to a view and also apply caching. The
+ url_rule, name and options arguments are the same arguments for the
+ route function. The TTL argument if given will passed along to the
+ caching decorator.
'''
route_decorator = self.route(url_rule, name=name, options=options)
- cache_decorator = self.cached()
+ if TTL:
+ cache_decorator = self.cached(TTL)
+ else:
+ cache_decorator = self.cached()
+
def new_decorator(func):
return route_decorator(cache_decorator(func))
return new_decorator
@@ -248,11 +255,11 @@ class Plugin(XBMCMixin):
if name in self._view_functions.keys():
# TODO: Raise exception for ambiguous views during registration
log.warning('Cannot add url rule "%s" with name "%s". There is '
- 'already a view with that name' % (url_rule, name))
+ 'already a view with that name', url_rule, name)
self._view_functions[name] = None
else:
log.debug('Adding url rule "%s" named "%s" pointing to function '
- '"%s"' % (url_rule, name, view_func.__name__))
+ '"%s"', url_rule, name, view_func.__name__)
self._view_functions[name] = rule
self._routes.append(rule)
@@ -283,8 +290,8 @@ class Plugin(XBMCMixin):
view_func, items = rule.match(path)
except NotFoundException:
continue
- log.info('Request for "%s" matches rule for function "%s"'
- % (path, view_func.__name__))
+ log.info('Request for "%s" matches rule for function "%s"',
+ path, view_func.__name__)
listitems = view_func(**items)
# TODO: Verify the main UI handle is always 0, this check exists so
@@ -301,11 +308,11 @@ class Plugin(XBMCMixin):
have the final plugin:// url.'''
# TODO: Should we be overriding self.request with the new request?
new_request = self._parse_request(url=url, handle=self.request.handle)
- log.debug('Redirecting %s to %s' % (self.request.path,
new_request.path))
+ log.debug('Redirecting %s to %s', self.request.path, new_request.path)
return self._dispatch(new_request.path)
def run(self, test=False):
'''The main entry point for a plugin.'''
self._request = self._parse_request()
- log.debug('Handling incoming request for %s' % (self.request.path))
+ log.debug('Handling incoming request for %s', self.request.path)
return self._dispatch(self.request.path)
diff --git a/script.module.xbmcswift2/lib/xbmcswift2/storage.py
b/script.module.xbmcswift2/lib/xbmcswift2/storage.py
index 63959c1..908a64f 100644
--- a/script.module.xbmcswift2/lib/xbmcswift2/storage.py
+++ b/script.module.xbmcswift2/lib/xbmcswift2/storage.py
@@ -11,7 +11,10 @@ import os
import csv
import json
import time
-import pickle
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
import shutil
import collections
from datetime import datetime
@@ -37,8 +40,8 @@ class _PersistentDictMixin(object):
self.file_format = file_format # 'csv', 'json', or 'pickle'
self.filename = filename
if flag != 'n' and os.access(filename, os.R_OK):
- log.debug('Reading %s storage from disk at "%s"' %
- (self.file_format, self.filename))
+ log.debug('Reading %s storage from disk at "%s"',
+ self.file_format, self.filename)
fileobj = open(filename, 'rb' if file_format == 'pickle' else 'r')
with fileobj:
self.load(fileobj)
@@ -91,7 +94,6 @@ class _PersistentDictMixin(object):
try:
return self.initial_update(loader(fileobj))
except Exception as e:
- print e
pass
raise ValueError('File not in a supported format')
diff --git a/script.module.xbmcswift2/lib/xbmcswift2/xbmcmixin.py
b/script.module.xbmcswift2/lib/xbmcswift2/xbmcmixin.py
index 7fe7645..781e6f0 100644
--- a/script.module.xbmcswift2/lib/xbmcswift2/xbmcmixin.py
+++ b/script.module.xbmcswift2/lib/xbmcswift2/xbmcmixin.py
@@ -21,7 +21,7 @@ class XBMCMixin(object):
# Also, the child class is responsible for ensuring that this path
# exists.
- self.storage_path
+ self.storage_path
self.added_items
@@ -33,7 +33,7 @@ class XBMCMixin(object):
self.handle
- # optional
+ # optional
self.info_type: should be in ['video', 'music', 'pictures']
_memoized_storage = None
_unsynced_storages = None
@@ -63,17 +63,16 @@ class XBMCMixin(object):
try:
result = storage[key]
- #log.debug('Cache hit for key "%s"' % (key, ))
log.debug('Storage hit for function "%s" with args "%s" '
- 'and kwargs "%s"' % (function.__name__, args,
- kwargs))
+ 'and kwargs "%s"', function.__name__, args,
+ kwargs)
except KeyError:
log.debug('Storage miss for function "%s" with args "%s" '
- 'and kwargs "%s"' % (function.__name__, args,
- kwargs))
+ 'and kwargs "%s"', function.__name__, args,
+ kwargs)
result = function(*args, **kwargs)
storage[key] = result
- storage.sync()
+ storage.sync()
return result
return wrapper
return decorating_function
@@ -92,7 +91,7 @@ class XBMCMixin(object):
fully functioning python dictionary and is designed to be used that
way. It is usually not necessary for the caller to load or save the
storage manually. If the storage does not already exist, it will be
- created.
+ created.
.. seealso:: :class:`xbmcswift2.TimedStorage` for more details.
@@ -116,13 +115,13 @@ class XBMCMixin(object):
filename = os.path.join(self.storage_path, name)
try:
storage = self._unsynced_storages[filename]
- log.debug('Loaded storage "%s" from memory' % name)
+ log.debug('Loaded storage "%s" from memory', name)
except KeyError:
if TTL:
TTL = timedelta(minutes=TTL)
storage = TimedStorage(filename, file_format, TTL)
self._unsynced_storages[filename] = storage
- log.debug('Loaded storage "%s" from disk' % name)
+ log.debug('Loaded storage "%s" from disk', name)
return storage
def temp_fn(self, path):
@@ -196,6 +195,26 @@ class XBMCMixin(object):
view_mode_id'''
xbmc.executebuiltin('Container.SetViewMode(%d)' % view_mode_id)
+ def keyboard(self, default=None, heading=None, hidden=False):
+ '''Displays the keyboard input window to the user. If the user does not
+ cancel the modal, the value entered by the user will be returned.
+
+ :param default: The placeholder text used to prepopulate the input
field.
+ :param heading: The heading for the window. Defaults to the current
+ addon's name. If you require a blank heading, pass an
+ empty string.
+ :param hidden: Whether or not the input field should be masked with
+ stars, e.g. a password field.
+ '''
+ if heading is None:
+ heading = self.addon.getAddonInfo('name')
+ if default is None:
+ default = ''
+ keyboard = xbmc.Keyboard(default, heading, hidden)
+ keyboard. xbmc.Keyboard(default, heading, hidden) be masked
with d. mcswift2/lib/xbmcswift2/xbmcmixin.py 5+ IËÿ IËÿ uÚ®5+ ú¯5+ õÏ5+ èË5+ IËÿ î5+ pIËÿ @IËÿ kð®5+ 6
è è! è! IËÿ IËÿ x¤Ë5+ pIËÿ Ò®5+ ð®5+ IËÿ `Ò®5+ O IËÿ À/5+ uÚ®5+ /5+ Ø/5+ ¨/5+ ú¯5+ x¤Ë5+ pIËÿ @IËÿ kð®5+ à! à! IËÿ IËÿ Hn«5+ PIËÿ Ò®5+ ð®5+ IËÿ `Ò®5+ O IËÿ @ IËÿ 8 IËÿ 8ûÏ5+ p IËÿ uÚ®5+ ú¯5+ PIËÿ
IËÿ kð®5+ G H I J K M N O P IËÿ IËÿ H%5+ ðIËÿ Ò®5+ ð®5+ IËÿ 0/5+ uÚ®5+ °Ë5+ Y_5+ /5+ Ø/5+ ¨/5+ ú¯5+ H%5+ ðIËÿ 0IËÿ kð®5+ 8%5+ ðIËÿ `IËÿ kð®5+ (%5+ ðIËÿ IËÿ kð®5+ %5+ ðIËÿ ÀIËÿ kð®5+
¨/5+ uÚ®5+ ¨/5+ @IËÿ ¨_5+ eÙ®5+ Ø/5+ `IËÿ y¨_5+ eÙ®5+ /5+ IËÿ Z¨_5+ eÙ®5+ ØT_5+ °Ë5+ Y_5+ /5+ Ø´Ë5+ Ø/5+ ¨/5+ ú¯5+ 8ûÏ5+ +5+ IËÿ pë^5+ @IËÿ IËÿ kð®5+ 5 6 7 8 : <