Skip to content

Commit

Permalink
[xbmcswift2-release-script] prepare release 2.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
jbeluch committed Feb 21, 2013
1 parent 14bcd18 commit 20c66bb
Show file tree
Hide file tree
Showing 10 changed files with 285 additions and 50 deletions.
2 changes: 1 addition & 1 deletion addon.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<addon id="script.module.xbmcswift2" name="xbmcswift2" provider-name="Jonathan Beluch (jbel)" version="2.3.2">
<addon id="script.module.xbmcswift2" name="xbmcswift2" provider-name="Jonathan Beluch (jbel)" version="2.4.0">
<requires>
<import addon="xbmc.python" version="2.1.0" />
</requires>
Expand Down
32 changes: 32 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
CHANGES
=======


Version 2.4.0
-------------
- Allow ints to be passed to plugin.url_for() and str() them.
- plugin.set_resolved_url() now takes an item dict instead of a URL. (The URL
is still allowed for backwards compatibility but is decprecated).
- Ability to replace the context menu items by setting 'replace_context_menu'
to True in an item dict.
- pluign.get_setting() now requires an extra paramter, *converter*, which
converts the item from XML to a python type specified by converter.
- Major bug fix to accomodate handles > 0 in XBMC Frodo.
- Auto-call plugin.finish(succeeded=False) if a view returns None.
- XBMC now decides the default player when using plugin.play_video().
- Storages now call sync() when clear() is called.
- Added plugin.clear_function_cache() which clears the storage behind the
@cached and @cached_route decorators.
- Add ability to set stream info for list items. Also, devs can now add
stream_info to item dicts.
- Added the actions module. Contains actions.background() and
actions.update_view() which are convenience wrappers for RunPlugin() and
Container.Update().
- Allow passing of functions to url_for.
- 'properties' key in an item dict should now be a dictionary. A list of tuples
is still allowed for backwards compatibility.
- Addon user is now prompted and storage automatically cleared if it becomes
corrupted.
- Added subtitles support. A 'subtitles' parameter was added to
plugin.set_resolved_url().
- xbmcswift2 URLs and routing code is now indifferent to a trailing slash.
- Bug fixes. See https://github.com/jbeluch/xbmcswift2/issues?milestone=3.


Version 2.3.2
-------------

Expand Down
4 changes: 2 additions & 2 deletions lib/xbmcswift2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ def func(*args, **kwargs):
from logger import log

# Mock the XBMC modules
from mockxbmc import xbmc, xbmcgui, xbmcplugin, xbmcaddon
from mockxbmc import xbmc, xbmcgui, xbmcplugin, xbmcaddon, xbmcvfs
xbmc = module(xbmc)
xbmcgui = module(xbmcgui)
xbmcplugin = module(xbmcplugin)
xbmcaddon = module(xbmcaddon)
xbmcvfs = module()
xbmcvfs = module(xbmcvfs)


from xbmcswift2.storage import TimedStorage
Expand Down
27 changes: 27 additions & 0 deletions lib/xbmcswift2/actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'''
xbmcswift2.actions
------------------
This module contains wrapper functions for XBMC built-in functions.
:copyright: (c) 2012 by Jonathan Beluch
:license: GPLv3, see LICENSE for more details.
'''


def background(url):
'''This action will run an addon in the background for the provided URL.
See 'XBMC.RunPlugin()' at
http://wiki.xbmc.org/index.php?title=List_of_built-in_functions.
'''
return 'XBMC.RunPlugin(%s)' % url


def update_view(url):
'''This action will update the current container view with provided url.
See 'XBMC.Container.Update()' at
http://wiki.xbmc.org/index.php?title=List_of_built-in_functions.
'''
return 'XBMC.Container.Update(%s)' % url
19 changes: 15 additions & 4 deletions lib/xbmcswift2/listitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ def set_property(self, key, value):
'''Sets a property for the given key and value'''
return self._listitem.setProperty(key, value)

def add_stream_info(self, stream_type, stream_values):
'''Adds stream details'''
return self._listitem.addStreamInfo(stream_type, stream_values)

def get_icon(self):
'''Returns the listitem's icon image'''
return self._icon
Expand Down Expand Up @@ -181,7 +185,8 @@ def as_xbmc_listitem(self):
@classmethod
def from_dict(cls, label=None, label2=None, icon=None, thumbnail=None,
path=None, selected=None, info=None, properties=None,
context_menu=None, is_playable=None, info_type='video'):
context_menu=None, replace_context_menu=False,
is_playable=None, info_type='video', stream_info=None):
'''A ListItem constructor for setting a lot of properties not
available in the regular __init__ method. Useful to collect all
the properties in a dict and then use the **dct to call this
Expand All @@ -199,12 +204,18 @@ def from_dict(cls, label=None, label2=None, icon=None, thumbnail=None,
listitem.set_is_playable(True)

if properties:
# Need to support existing tuples, but prefer to have a dict for
# properties.
if hasattr(properties, 'items'):
properties = properties.items()
for key, val in properties:
listitem.set_property(key, val)

# By default doesn't replace, use .add_context_menu_items if you wish
# to set replace_items=True
if stream_info:
for stream_type, stream_values in stream_info.items():
listitem.add_stream_info(stream_type, stream_values)

if context_menu:
listitem.add_context_menu_items(context_menu)
listitem.add_context_menu_items(context_menu, replace_context_menu)

return listitem
35 changes: 23 additions & 12 deletions lib/xbmcswift2/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ def __init__(self, name=None, addon_id=None, filepath=None, info_type=None):
# A flag to keep track of a call to xbmcplugin.endOfDirectory()
self._end_of_directory = False

# Keep track of the update_listing flag passed to
# xbmcplugin.endOfDirectory()
self._update_listing = False

# The plugin's named logger
self._log = setup_log(self._addon_id)

Expand Down Expand Up @@ -272,11 +276,18 @@ def url_for(self, endpoint, **items):
Raises AmbiguousUrlException if there is more than one possible
view for the given endpoint name.
'''
if endpoint not in self._view_functions.keys():
raise NotFoundException, ('%s doesn\'t match any known patterns.' %
endpoint)

rule = self._view_functions[endpoint]
try:
rule = self._view_functions[endpoint]
except KeyError:
try:
rule = (rule for rule in self._view_functions.values() if rule.view_func == endpoint).next()
except StopIteration:
raise NotFoundException(
'%s doesn\'t match any known patterns.' % endpoint)

# rule can be None since values of None are allowed in the
# _view_functions dict. This signifies more than one view function is
# tied to the same name.
if not rule:
# TODO: Make this a regular exception
raise AmbiguousUrlException
Expand All @@ -294,14 +305,14 @@ def _dispatch(self, path):
path, view_func.__name__)
listitems = view_func(**items)

# XXX: The UI Container listing call to plugin or the resolving
# url call always has a handle greater or equals 0. RunPlugin()
# call using a handle -1. we only auto-call endOfDirectory for
# the UI Container listing call. and set_resolve_url() also
# set the _end_of_directory flag so we do not call finish() for it.
# Allow the returning of bare dictionaries so we can cache view
# Only call self.finish() for UI container listing calls to plugin
# (handle will be >= 0). Do not call self.finish() when called via
# RunPlugin() (handle will be -1).
if not self._end_of_directory and self.handle >= 0:
listitems = self.finish(listitems)
if listitems is None:
self.finish(succeeded=False)
else:
listitems = self.finish(listitems)

return listitems
raise NotFoundException, 'No matching view found for %s' % path
Expand Down
4 changes: 4 additions & 0 deletions lib/xbmcswift2/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ def raw_dict(self):

initial_update = collections.MutableMapping.update

def clear(self):
super(_Storage, self).clear()
self.sync()


class TimedStorage(_Storage):
'''A dict with the ability to persist to disk and TTL for items.'''
Expand Down
13 changes: 11 additions & 2 deletions lib/xbmcswift2/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ def __init__(self, url_rule, view_func, name, options):
self._url_format = self._url_rule.replace('<', '{').replace('>', '}')

# Make a regex pattern for matching incoming URLs
p = self._url_rule.replace('<', '(?P<').replace('>', '>[^/]+?)')
rule = self._url_rule
if rule != '/':
# Except for a path of '/', the trailing slash is optional.
rule = self._url_rule.rstrip('/') + '/?'
p = rule.replace('<', '(?P<').replace('>', '>[^/]+?)')

try:
self._regex = re.compile('^' + p + '$')
Expand Down Expand Up @@ -130,7 +134,7 @@ def make_path_qs(self, items):
parameters.
All items will be urlencoded. Any items which are not instances of
basestring will be pickled before being urlencoded.
basestring, or int/long will be pickled before being urlencoded.
.. warning:: The pickling of items only works for key/value pairs which
will be in the query string. This behavior should only be
Expand All @@ -139,6 +143,11 @@ def make_path_qs(self, items):
hard limit on URL length. See the caching section if you
need to persist a large amount of data between requests.
'''
# Convert any ints and longs to strings
for key, val in items.items():
if isinstance(val, (int, long)):
items[key] = str(val)

# First use our defaults passed when registering the rule
url_items = dict((key, val) for key, val in self._options.items()
if key in self._keywords)
Expand Down
Loading

0 comments on commit 20c66bb

Please sign in to comment.