The branch, frodo has been updated
       via  22f42293f107dedf45324970d61336ee6788453b (commit)
       via  43738e2f9bbb8fbb3a917d318474a3012599bd57 (commit)
       via  f106c8095c4852c24cf1881a3a81e41d6e3a3214 (commit)
      from  991559c5db9f9e13b3e43466bea6d6dca4cc506c (commit)

- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=22f42293f107dedf45324970d61336ee6788453b


http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=43738e2f9bbb8fbb3a917d318474a3012599bd57

commit 43738e2f9bbb8fbb3a917d318474a3012599bd57
Author: beenje <[email protected]>
Date:   Wed Jan 23 22:13:51 2013 +0100

    [plugin.video.khanacademy] updated to version 2.5.0

diff --git a/plugin.video.khanacademy/addon.py 
b/plugin.video.khanacademy/addon.py
index 0e851e8..03ee24f 100755
--- a/plugin.video.khanacademy/addon.py
+++ b/plugin.video.khanacademy/addon.py
@@ -1,105 +1,60 @@
-#!/usr/bin/env python
-# Copyright 2011 Jonathan Beluch.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-import os
-import time
-try:
-    import json
-except ImportError:
-    import simplejson as json
-from urlparse import urljoin
-from xbmcswift import Plugin, download_page, xbmc
-from BeautifulSoup import BeautifulSoup as BS
-from resources.lib.khan import KhanData, download_playlists_json
-from resources.lib.cache import get_cached_data, put_cached_data
+'''
+    Khan Academy XBMC Addon
+    ~~~~~~~~~~~~~~~~~~~~~~~
 
+    Watch videos from http://www.khanacademy.org in XBMC.
 
-__plugin_name__ = 'Khan Academy'
-__plugin_id__ = 'plugin.video.khanacademy'
-plugin = Plugin(__plugin_name__, __plugin_id__, __file__)
-BASE_URL = 'http://www.khanacademy.org'
+    :copyright: (c) 2013 by Jonathan Beluch
+    :license: GPLv3, see LICENSE.txt for more details.
+'''
+import xbmcswift2
+from resources.lib import khan
 
 
-# Ugly temporary hack until xbmcswift is fixed. Need to ensure the basedirs
-# for the cache already exist before we attempt to use it. Also, in pyton 2.4
-# we don't get the lovely os.makedirs :(
-def make_cache_dirs():
-    '''Make plugin_id and .cache dirs for the current plugin.'''
-    def make_if_not_exist(path):
-        print path
-        if not os.path.exists(path):
-            os.mkdir(path)
-    cache_root = xbmc.translatePath('special://profile/addon_data')
-    make_if_not_exist(os.path.join(cache_root, __plugin_id__))
-    make_if_not_exist(os.path.join(cache_root, __plugin_id__, '.cache'))
-make_cache_dirs()
-
-
-def full_url(path):
-    '''Returns the full url for the given path. Uses BASE_URL.'''
-    return urljoin(BASE_URL, path)
-
-
-def htmlify(url):
-    '''Returns a BeautifulSoup object for a give url's response.'''
-    return BS(download_page(url))
+ONE_HOUR_IN_MINUTES = 60
+YOUTUBE_URL = 'plugin://plugin.video.youtube/?action=play_video&videoid=%s'
+plugin = xbmcswift2.Plugin()
 
 
[email protected](TTL=ONE_HOUR_IN_MINUTES)
 def get_khan_data():
-    '''Returns a KhanData instance containg playlist data.
-
-    Behind the scenes, it checks for a local cached copy first. If the cached
-    copy's lifetime has not expired it will use the local copy. Otherwise, it
-    will fetch fresh data from the API and cache it locally.
+    '''A wrapper method that exists to cache the results of the remote API
+    calls.
     '''
-    json_fn = plugin.cache_fn('playlists.json')
-    timestamp_fn = plugin.cache_fn('playlists.json.ts')
-
-    _json = get_cached_data(json_fn, timestamp_fn)
-    if _json is None:
-        _json = download_playlists_json()
-        put_cached_data(json.dumps(_json), json_fn, timestamp_fn)
+    return khan.load_topic_tree()
 
-    return KhanData(_json)
 
-
-KHAN_DATA = get_khan_data()
-
-
[email protected]('/')
[email protected]('/<category>/', name='show_category')
-def main_menu(category='_root'):
-    '''This view displays Categories or Playlists.
-
-    This method does a lookup based on the passed category/playlist name to get
-    the members. The "root" or base category is name "_root"
+def get_playable_url(video):
+    '''Returns a the direct mp4 url if present otherwise returns a URL for the
+    youtube addon.
     '''
-    items = [item.to_listitem(plugin)
-             for item in KHAN_DATA.get_items(category)]
-    return plugin.add_items(items)
+    return video['mp4_url'] or YOUTUBE_URL % video['youtube_id']
+
+
+def to_listitem(item):
+    '''Converts a khan academy dict to an xbmcswift2 item dict.'''
+    if 'mp4_url' in item.keys():
+        return {
+            'label': item['title'],
+            'path': get_playable_url(item),
+            'is_playable': True,
+            'thumbnail': item['thumbnail'],
+            'info': {
+                'plot': item['description'],
+            },
+        }
+    else:
+        return {
+            'label': item['title'],
+            'path': plugin.url_for('show_topic', topic=item['id']),
+        }
 
 
[email protected]('/play/<video_slug>/')
-def play_video(video_slug):
-    '''Resolves a video page's url to a playable video url.'''
-    # Videos are both in .mp4 format and youtube. For simplicity's sake just
-    # use mp4 for now.
-    url = 'http://www.khanacademy.org/video/%s' % video_slug
-    html = htmlify(url)
-    a = html.find('a', {'title': 'Download this lesson'})
-    plugin.set_resolved_url(a['href'])
[email protected]('/')
[email protected]('/<topic>/', name='show_topic')
+def main_menu(topic='root'):
+    '''The one and only view which displays topics hierarchically.'''
+    return [to_listitem(item) for item in get_khan_data()[topic]]
 
 
 if __name__ == '__main__':
diff --git a/plugin.video.khanacademy/addon.xml 
b/plugin.video.khanacademy/addon.xml
index 30a01ff..c7f6ed8 100644
--- a/plugin.video.khanacademy/addon.xml
+++ b/plugin.video.khanacademy/addon.xml
@@ -1,18 +1,17 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<addon id="plugin.video.khanacademy" name="Khan Academy" version="1.4.2" 
provider-name="Jonathan Beluch (jbel)">
+<addon id="plugin.video.khanacademy" name="Khan Academy" 
provider-name="Jonathan Beluch (jbel)" version="2.5.0">
   <requires>
-    <import addon="xbmc.python" version="2.0"/>
-    <import addon="script.module.beautifulsoup" version="3.0.8"/>
-    <import addon="script.module.xbmcswift" version="0.2.0"/>
-    <import addon="script.module.simplejson" version="2.0.10"/>
-    <import addon="plugin.video.youtube" version="2.9.1"/>
+    <import addon="xbmc.python" version="2.1.0" />
+    <import addon="script.module.xbmcswift2" version="1.3.1" />
+    <import addon="script.module.requests" version="1.0.4" />
+    <import addon="plugin.video.youtube" version="4.4.1" />
   </requires>
-  <extension point="xbmc.python.pluginsource" library="addon.py">
+  <extension library="addon.py" point="xbmc.python.pluginsource">
     <provides>video</provides>
   </extension>
   <extension point="xbmc.addon.metadata">
+    <language />
     <platform>all</platform>
     <summary>View lessons from http://www.khanacademy.org</summary>
     <description>From http://www.khanacademy.org/about: "The Khan Academy is 
an organization on a mission. We're a not-for-profit with the goal of changing 
education for the better by providing a free world-class education to anyone 
anywhere.[CR][CR]All of the site's resources are available to anyone. It 
doesn't matter if you are a student, teacher, home-schooler, principal, adult 
returning to the classroom after 20 years, or a friendly alien just trying to 
get a leg up in earthly biology. The Khan Academy's materials and resources are 
available to you completely free of charge."</description>
   </extension>
-</addon>
+</addon>
\ No newline at end of file
diff --git a/plugin.video.khanacademy/changelog.txt 
b/plugin.video.khanacademy/changelog.txt
index 400b802..59dc425 100644
--- a/plugin.video.khanacademy/changelog.txt
+++ b/plugin.video.khanacademy/changelog.txt
@@ -1,3 +1,8 @@
+Version 2.5.0
+* Bump major version number for Frodo.
+* Upgrade to xbmcswift2.
+* Update code to reflect remote API changes.
+
 Version 1.4.2
 * Update plugin to reflect Khan API changes
 * Use youtube for playback when an mp4 isn't available
diff --git a/plugin.video.khanacademy/resources/lib/khan.py 
b/plugin.video.khanacademy/resources/lib/khan.py
index cf70413..64dce3a 100644
--- a/plugin.video.khanacademy/resources/lib/khan.py
+++ b/plugin.video.khanacademy/resources/lib/khan.py
@@ -1,134 +1,94 @@
-try:
-    import json
-except ImportError:
-    import simplejson as json
-import time
-import urllib
-
-
-# Hierarchical list
-API_URL = 'http://www.khanacademy.org/api/v1/playlists/library'
-YOUTUBE_PLUGIN_PTN = 
'plugin://plugin.video.youtube/?action=play_video&videoid=%s'
-
-
-def download_playlists_json():
-    '''Fetches the playlist JSON from the Khan Academy API and returns the
-    parsed JSON object.
+'''
+    resources.lib.khan
+    ~~~~~~~~~~~~~~~~~~~
+
+    This module interfaces with the remote Khan Academy API.
+
+    :copyright: (c) 2013 by Jonathan Beluch
+    :license: GPLv3, see LICENSE.txt for more details.
+'''
+
+import requests
+import collections
+
+
+API_URL = 'http://www.khanacademy.org/api/v1/topictree'
+
+
+def _video(item):
+    '''Returns a video dict of values parsed from the json dict.'''
+    return {
+        'title': item['title'],
+        'description': item['description'],
+        'thumbnail': (item['download_urls'] or {}).get('png'),
+        'youtube_id': item['youtube_id'],
+        'mp4_url': (item['download_urls'] or {}).get('mp4'),
+    }
+
+
+def _topic(item):
+    '''Returns a topic dict of values parsed from the json dict.'''
+    return {
+        'id': item['id'],
+        'title': item['title'],
+    }
+
+
+_KINDS = {
+    'Topic': _topic,
+    'Video': _video,
+}
+
+
+def _flatten(item):
+    '''Returns a new dict which is a flattened version of the provided item.
+    The provided item can have an arbitrary depth, since each item can possibly
+    have a 'children' entry. Since all items have unique ids, this method
+    creates a flat dictionary, where the key is each item's unique id and the
+    value is the item's children if present.
+
+    >>> item = {
+    ...     'id': 'root',
+    ...     'children': [
+    ...         {
+    ...             'id': 'Algebra',
+    ...              'children': [
+    ...                 { 'id': 'Lesson 1'},
+    ...                 { 'id': 'Lesson 2'},
+    ...              ],
+    ...         },
+    ...         {
+    ...              'id': 'Calculus',
+    ...         },
+    ...     ]
+    ... }
+    >>> _flatten(item).keys()
+    ['root', 'Algebra']
     '''
-    conn = urllib.urlopen(API_URL)
-    resp = json.load(conn)
-    conn.close()
-    return resp
-
-
-def _try_parse(_json, *args):
-    '''Returns the parsed value or None if doesn't exist. The provided args
-    correspond to dictionary keys.
-
-    >>> _json = {'foo': {'bar': 'baz'}}
-    >>> _try_parse(_json, 'foo', 'bar')
-    baz
-    >>> _try_parse(_json, 'foo', 'missingkey')
-    None
+    tree = collections.defaultdict(list)
+    queue = [(child, 'root') for child in item['children']]
+    while queue:
+        item, parent_id = queue.pop(0)
+        tree[parent_id].append(item)
+        if 'children' in item.keys():
+            current_id = item['id']
+            queue.extend((child, current_id) for child in item['children'])
+    return tree
+
+
+def load_topic_tree():
+    '''The main entry point for this module. Returns a dict keyed by Topic id.
+    The value of the dict is the topic's children which are either topic dicts
+    or video dicts. To hierarchichally descend through topics, start with the
+    key 'root', and then look up each child topic's 'id' in this tree to get
+    its children.
     '''
-    try:
-        for key in args:
-            _json = _json[key]
-        return _json
-    except TypeError:
-        return None
-
-
-class Video(object):
-
-    def __init__(self, _json):
-        #self.key_id = _json['key_id']
-        self.title = _json['title']
-        self.readable_id = _json['readable_id']
-        self.youtube_url = YOUTUBE_PLUGIN_PTN % _json['youtube_id']
-        self.mp4_url = _try_parse(_json, 'download_urls', 'mp4')
-        self.thumbnail = _try_parse(_json, 'download_urls', 'png')
-
-
-    def to_listitem(self, plugin):
-        '''Returns a dict suitable for passing to xbmcswift.plugin.add_items'''
-        item = {
-            'label': self.title,
-            'url': self.mp4_url or self.youtube_url,
-            'is_playable': True,
-            'is_folder': False,
-        }
-        if self.thumbnail:
-            item['thumbnail'] = self.thumbnail
-        return item
+    _json = requests.get(API_URL).json()
+    flattened = _flatten(_json)
 
+    tree = {}
+    for item_id, children in flattened.items():
+        tree[item_id] = [_KINDS[child['kind']](child) for child in children
+                         if child['kind'] in _KINDS.keys()]
 
-class Playlist(object):
-
-    def __init__(self, _json):
-        self.title = _json['title']
-        self.description = _json['description']
-        self.videos = [Video(item) for item in _json['videos']]
-
-    def __iter__(self):
-        return iter(self.videos)
-
-    def to_listitem(self, plugin):
-        '''Returns a dict suitable for passing to xbmcswift.plugin.add_items'''
-        return {
-            'label': self.title,
-            'url': plugin.url_for('show_category', category=self.title),
-            'info': {'plot': self.description},
-        }
-
-
-class Category(object):
-
-    def __init__(self, _json):
-        self.name = _json['name']
-
-    def to_listitem(self, plugin):
-        '''Returns a dict suitable for passing to xbmcswift.plugin.add_items'''
-        return {
-            'label': self.name,
-            'url': plugin.url_for('show_category', category=self.name),
-        }
-
-
-class KhanData(object):
-    '''This class repurposes the Khan Academy playlist JSON into more
-    convenient data structures.
-    '''
-
-    def __init__(self, _json):
-        self._items = {}
-        self._parse(_json, '_root')
-
-    def _is_playlist(self, item):
-        return 'playlist' in item.keys()
-
-    def _create_keys(self, key):
-        if key not in self._items.keys():
-            self._items[key] = []
-
-    def _parse(self, _json, current_key):
-        '''Recursive parsing function to format the _json input in a single
-        dict keyable on item['name']
-        '''
-        self._create_keys(current_key)
-
-        for item in _json:
-            if self._is_playlist(item):
-                playlist = Playlist(item['playlist'])
-                self._items[current_key].append(playlist)
-                self._items[item['name']] = playlist
-            else:
-                category = Category(item)
-                self._items[current_key].append(category)
-                self._parse(item['items'], item['name'])
-
-    def get_items(self, key):
-        '''For a given key, returns a list of items (Category or Playlist) or
-        if the key is a playlist name, returns a Playlist object.
-        '''
-        return self._items[key]
+    return tree

http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/plugins;a=commit;h=f106c8095c4852c24cf1881a3a81e41d6e3a3214

commit f106c8095c4852c24cf1881a3a81e41d6e3a3214
Author: beenje <[email protected]>
Date:   Wed Jan 23 22:13:49 2013 +0100

    [plugin.video.ted.talks] updated to version 4.1.7

diff --git a/plugin.video.ted.talks/addon.xml b/plugin.video.ted.talks/addon.xml
index 1d81401..bdf3009 100644
--- a/plugin.video.ted.talks/addon.xml
+++ b/plugin.video.ted.talks/addon.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<addon id="plugin.video.ted.talks" name="TED Talks" version="3.1.6" 
provider-name="rwparris2, moreginger">
+<addon id="plugin.video.ted.talks" name="TED Talks" version="4.1.7" 
provider-name="rwparris2, moreginger">
   <requires>
-    <import addon="xbmc.python" version="2.0"/>
+    <import addon="xbmc.python" version="2.1.0"/>
     <import addon="script.module.simplejson" version="2.0.10"/>
     <import addon="script.module.beautifulsoup" version="3.0.8"/>
     <import addon="script.module.elementtree" version="1.2.7"/>
diff --git a/plugin.video.ted.talks/changelog.txt 
b/plugin.video.ted.talks/changelog.txt
index 8e3c822..f398be7 100644
--- a/plugin.video.ted.talks/changelog.txt
+++ b/plugin.video.ted.talks/changelog.txt
@@ -1,3 +1,6 @@
+[B]Version 3.1.7[/B]
+Fix subtitles (issue#35) thanks to omega32
+
 [B]Version 3.1.6[/B]
 Fix getting subtitles using default xbmc language (issue#30)
 
diff --git a/plugin.video.ted.talks/resources/lib/model/subtitles_scraper.py 
b/plugin.video.ted.talks/resources/lib/model/subtitles_scraper.py
index c2b8aa4..efee063 100644
--- a/plugin.video.ted.talks/resources/lib/model/subtitles_scraper.py
+++ b/plugin.video.ted.talks/resources/lib/model/subtitles_scraper.py
@@ -9,7 +9,7 @@ import urllib
 import re
 
 __friendly_message__ = 'Error showing subtitles'
-__talkIdKey__ = 'talkId'
+__talkIdKey__ = 'ti'
 __introDurationKey__ = 'introDuration'
 
 def format_time(time):
@@ -53,15 +53,28 @@ def get_flashvars(soup):
     if not flashvar_match:
         raise Exception('Could not get flashVars')
 
-    talkId_re = re.compile('"%s":(\d+)' % (__talkIdKey__))
-    introDuration_re = re.compile('"%s":(\d+)' % (__introDurationKey__))
+    talkId_re = re.compile('"?%s"?:"?(\d+)"?' % (__talkIdKey__))
     flashvars = urllib.unquote(flashvar_match.group(1).encode('ascii'))
 
     talkId_match = talkId_re.search(flashvars)
     if not talkId_match:
         raise Exception('Could not get talk ID')
 
-    introDuration_match = introDuration_re.search(flashvars)
+    input_tag2 = soup.find('script', type='text/javascript', 
text=re.compile('var talkDetails'))
+    if not input_tag2:
+        raise Exception('Could not find the talkDetails container')
+
+    talkDetails_re = re.compile('var talkDetails = (\{.*\})');
+    talkDetails_match = talkDetails_re.search(input_tag2.string)
+
+    if not talkDetails_match:
+        raise Exception('Could not get talkDetails')
+
+    talkDetails = urllib.unquote(talkDetails_match.group(1).encode('ascii'))
+
+    introDuration_re = re.compile('"%s":(\d+)' % (__introDurationKey__))
+    introDuration_match = introDuration_re.search(talkDetails)
+
     if not introDuration_match:
         raise Exception('Could not get intro duration')
 
diff --git 
a/plugin.video.ted.talks/resources/lib/model/subtitles_scraper_test.py 
b/plugin.video.ted.talks/resources/lib/model/subtitles_scraper_test.py
index 5af783c..12a7416 100644
--- a/plugin.video.ted.talks/resources/lib/model/subtitles_scraper_test.py
+++ b/plugin.video.ted.talks/resources/lib/model/subtitles_scraper_test.py
@@ -49,7 +49,7 @@ World
         self.assertEquals('15', flashvars['introDuration'])
 
         # Talk ID, need this to request subtitles.
-        self.assertEquals('1253', flashvars['talkId'])
+        self.assertEquals('1253', flashvars['ti'])
 
         expected = set(['sq', 'ar', 'hy', 'bg', 'ca', 'zh-cn', 'zh-tw', 'hr', 
'cs', 'da', 'nl', 'en', 'fr', 'ka', 'de', 'el', 'he', 'hu', 'id', 'it', 'ja', 
'ko', 'fa', 'mk', 'pl', 'pt', 'pt-br', 'ro', 'ru', 'sr', 'sk', 'es', 'th', 
'tr', 'uk', 'vi'])
         self.assertEquals(expected, set(subtitles_scraper.get_languages(soup)))
diff --git a/plugin.video.ted.talks/resources/lib/model/user.py 
b/plugin.video.ted.talks/resources/lib/model/user.py
index 60a9092..07e5ead 100644
--- a/plugin.video.ted.talks/resources/lib/model/user.py
+++ b/plugin.video.ted.talks/resources/lib/model/user.py
@@ -44,9 +44,9 @@ class User:
         finally:
             response.close()
         #set username & password in the sign in form
-        form = forms[1]
-        form["users[username]"] = username
-        form["users[password]"] = password
-        form["users[rememberme]"] = ["on"]
+        form = forms[0]
+        form["user[email]"] = username
+        form["user[password]"] = password
+        form.find_control(name="user[remember_me]", type="checkbox", 
id="user_remember_me").selected = True
         #click submit
         return self.get_HTML(form.click())

-----------------------------------------------------------------------

Summary of changes:
 plugin.video.khanacademy/addon.py                  |  133 +--
 plugin.video.khanacademy/addon.xml                 |   17 +-
 plugin.video.khanacademy/changelog.txt             |    5 +
 plugin.video.khanacademy/requirements.txt          |    3 +
 plugin.video.khanacademy/resources/lib/cache.py    |   46 -
 plugin.video.khanacademy/resources/lib/khan.py     |  220 ++--
 plugin.video.synopsi/LICENSE.txt                   |  340 +++++
 plugin.video.synopsi/README.markdown               |   10 +
 plugin.video.synopsi/_src/TODO                     |   45 +
 plugin.video.synopsi/_src/release-local.sh         |   25 +
 plugin.video.synopsi/addon.py                      |  291 ++++
 plugin.video.synopsi/addon.xml                     |   30 +
 plugin.video.synopsi/addonservice.py               |  172 +++
 plugin.video.synopsi/apiclient.py                  |  488 ++++++
 plugin.video.synopsi/app_apiclient.py              |  219 +++
 plugin.video.synopsi/cache.py                      |  471 ++++++
 plugin.video.synopsi/changelog.txt                 |   12 +
 plugin.video.synopsi/dialog.py                     |  531 +++++++
 plugin.video.synopsi/fanart.jpg                    |  Bin 0 -> 75292 bytes
 plugin.video.synopsi/icon.png                      |  Bin 0 -> 11832 bytes
 plugin.video.synopsi/library.py                    |  147 ++
 plugin.video.synopsi/loggable.py                   |   45 +
 plugin.video.synopsi/mythread.py                   |   19 +
 .../resources/language/English/strings.xml         |   26 +
 .../resources/language/Slovak/strings.xml          |   25 +
 plugin.video.synopsi/resources/settings.xml        |   45 +
 .../resources/skins/Default/720p/SelectMovie.xml   |  250 ++++
 .../resources/skins/Default/720p/SynopsiDialog.xml |  119 ++
 .../resources/skins/Default/720p/VideoInfo.xml     |  409 ++++++
 .../resources/skins/Default/720p/ViewsFileMode.xml |  613 ++++++++
 .../skins/Default/720p/ViewsVideoLibrary.xml       | 1545 ++++++++++++++++++++
 .../skins/Default/720p/customLoginDialog.xml       |  155 ++
 .../skins/Default/720p/custom_MyVideoNav.xml       |  167 +++
 .../resources/skins/Default/720p/includes.xml      |    3 +
 .../skins/Default/media/already-watched-stack.png  |  Bin 0 -> 5071 bytes
 .../resources/skins/Default/media/bgr.png          |  Bin 0 -> 3076 bytes
 .../resources/skins/Default/media/button1.png      |  Bin 0 -> 1585 bytes
 .../resources/skins/Default/media/button2.png      |  Bin 0 -> 1697 bytes
 .../resources/skins/Default/media/debug.png        |  Bin 0 -> 491 bytes
 .../resources/skins/Default/media/default.png      |  Bin 0 -> 9968 bytes
 .../resources/skins/Default/media/icon.png         |  Bin 0 -> 70062 bytes
 .../media/ondisk-AND-already-watched-stack.png     |  Bin 0 -> 7109 bytes
 .../resources/skins/Default/media/ondisk-stack.png |  Bin 0 -> 3852 bytes
 .../resources/skins/Default/media/pix.png          |  Bin 0 -> 119 bytes
 .../skins/Default/media/show_all_button.png        |  Bin 0 -> 4378 bytes
 .../resources/skins/Default/media/videos.jpg       |  Bin 0 -> 260099 bytes
 plugin.video.synopsi/scrobbler.py                  |  225 +++
 plugin.video.synopsi/service.py                    |   92 ++
 .../gui => plugin.video.synopsi/tests}/__init__.py |    0
 plugin.video.synopsi/tests/apiclient.unittest.py   |  340 +++++
 plugin.video.synopsi/tests/cache.unittest.py       |  181 +++
 plugin.video.synopsi/tests/callable.py             |   35 +
 plugin.video.synopsi/tests/common.py               |   12 +
 .../tests/data}/__init__.py                        |    0
 .../tests/data/get_all_movies.json                 |  729 +++++++++
 .../tests/data/get_all_tvshows.json                |   19 +
 plugin.video.synopsi/tests/data/local_recco.py     |   86 ++
 plugin.video.synopsi/tests/executescript.test.py   |    4 +
 plugin.video.synopsi/tests/fakeenv/xbmc.py         |   74 +
 plugin.video.synopsi/tests/fakeenv/xbmcaddon.py    |   27 +
 plugin.video.synopsi/tests/fakeenv/xbmcgui.py      |   25 +
 .../tests/fakeenv/xbmcplugin.py                    |    0
 plugin.video.synopsi/tests/fakeenv/xbmcvfs.py      |    3 +
 plugin.video.synopsi/tests/onlinecache.unittest.py |  288 ++++
 plugin.video.synopsi/tests/service-test.py         |   69 +
 plugin.video.synopsi/tests/socketserver.py         |   28 +
 plugin.video.synopsi/tests/test.py                 |  282 ++++
 plugin.video.synopsi/tests/typerror.test.py        |   17 +
 plugin.video.synopsi/tests/utilities.unittest.py   |   49 +
 plugin.video.synopsi/tests/xbmcrpc.unittest.py     |   47 +
 plugin.video.synopsi/top.py                        |    3 +
 plugin.video.synopsi/utilities.py                  |  690 +++++++++
 plugin.video.synopsi/xbmcrpc.py                    |  236 +++
 plugin.video.ted.talks/addon.xml                   |    4 +-
 plugin.video.ted.talks/changelog.txt               |    3 +
 .../resources/lib/model/subtitles_scraper.py       |   21 +-
 .../resources/lib/model/subtitles_scraper_test.py  |    2 +-
 plugin.video.ted.talks/resources/lib/model/user.py |    8 +-
 78 files changed, 9940 insertions(+), 285 deletions(-)
 create mode 100644 plugin.video.khanacademy/requirements.txt
 delete mode 100644 plugin.video.khanacademy/resources/lib/cache.py
 create mode 100644 plugin.video.synopsi/LICENSE.txt
 create mode 100644 plugin.video.synopsi/README.markdown
 create mode 100644 plugin.video.synopsi/_src/TODO
 create mode 100755 plugin.video.synopsi/_src/release-local.sh
 create mode 100644 plugin.video.synopsi/addon.py
 create mode 100644 plugin.video.synopsi/addon.xml
 create mode 100644 plugin.video.synopsi/addonservice.py
 create mode 100644 plugin.video.synopsi/apiclient.py
 create mode 100644 plugin.video.synopsi/app_apiclient.py
 create mode 100644 plugin.video.synopsi/cache.py
 create mode 100644 plugin.video.synopsi/changelog.txt
 create mode 100644 plugin.video.synopsi/dialog.py
 create mode 100644 plugin.video.synopsi/fanart.jpg
 create mode 100644 plugin.video.synopsi/icon.png
 create mode 100644 plugin.video.synopsi/library.py
 create mode 100644 plugin.video.synopsi/loggable.py
 create mode 100644 plugin.video.synopsi/mythread.py
 create mode 100644 plugin.video.synopsi/resources/language/English/strings.xml
 create mode 100644 plugin.video.synopsi/resources/language/Slovak/strings.xml
 create mode 100644 plugin.video.synopsi/resources/settings.xml
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/720p/SelectMovie.xml
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/720p/SynopsiDialog.xml
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/720p/VideoInfo.xml
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/720p/ViewsFileMode.xml
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/720p/ViewsVideoLibrary.xml
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/720p/customLoginDialog.xml
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/720p/custom_MyVideoNav.xml
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/720p/includes.xml
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/media/already-watched-stack.png
 create mode 100644 plugin.video.synopsi/resources/skins/Default/media/bgr.png
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/media/button1.png
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/media/button2.png
 create mode 100644 plugin.video.synopsi/resources/skins/Default/media/debug.png
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/media/default.png
 create mode 100644 plugin.video.synopsi/resources/skins/Default/media/icon.png
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/media/ondisk-AND-already-watched-stack.png
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/media/ondisk-stack.png
 create mode 100644 plugin.video.synopsi/resources/skins/Default/media/pix.png
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/media/show_all_button.png
 create mode 100644 
plugin.video.synopsi/resources/skins/Default/media/videos.jpg
 create mode 100644 plugin.video.synopsi/scrobbler.py
 create mode 100644 plugin.video.synopsi/service.py
 copy {plugin.audio.qobuz/resources/lib/qobuz/gui => 
plugin.video.synopsi/tests}/__init__.py (100%)
 create mode 100644 plugin.video.synopsi/tests/apiclient.unittest.py
 create mode 100644 plugin.video.synopsi/tests/cache.unittest.py
 create mode 100644 plugin.video.synopsi/tests/callable.py
 create mode 100644 plugin.video.synopsi/tests/common.py
 copy {plugin.audio.qobuz/resources/lib/qobuz/gui => 
plugin.video.synopsi/tests/data}/__init__.py (100%)
 create mode 100644 plugin.video.synopsi/tests/data/get_all_movies.json
 create mode 100644 plugin.video.synopsi/tests/data/get_all_tvshows.json
 create mode 100644 plugin.video.synopsi/tests/data/local_recco.py
 create mode 100644 plugin.video.synopsi/tests/executescript.test.py
 create mode 100644 plugin.video.synopsi/tests/fakeenv/xbmc.py
 create mode 100644 plugin.video.synopsi/tests/fakeenv/xbmcaddon.py
 create mode 100644 plugin.video.synopsi/tests/fakeenv/xbmcgui.py
 copy plugin.audio.qobuz/resources/lib/qobuz/gui/__init__.py => 
plugin.video.synopsi/tests/fakeenv/xbmcplugin.py (100%)
 create mode 100644 plugin.video.synopsi/tests/fakeenv/xbmcvfs.py
 create mode 100644 plugin.video.synopsi/tests/onlinecache.unittest.py
 create mode 100644 plugin.video.synopsi/tests/service-test.py
 create mode 100644 plugin.video.synopsi/tests/socketserver.py
 create mode 100644 plugin.video.synopsi/tests/test.py
 create mode 100644 plugin.video.synopsi/tests/typerror.test.py
 create mode 100644 plugin.video.synopsi/tests/utilities.unittest.py
 create mode 100644 plugin.video.synopsi/tests/xbmcrpc.unittest.py
 create mode 100644 plugin.video.synopsi/top.py
 create mode 100644 plugin.video.synopsi/utilities.py
 create mode 100644 plugin.video.synopsi/xbmcrpc.py


hooks/post-receive
-- 
Plugins

------------------------------------------------------------------------------
Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS,
MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current
with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft
MVPs and experts. ON SALE this month only -- learn more at:
http://p.sf.net/sfu/learnnow-d2d
_______________________________________________
Xbmc-addons mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xbmc-addons

Reply via email to