The branch, frodo has been updated
       via  6e500fe08e9370cf75d3f2e3a564e443809b09f8 (commit)
      from  7ad4e2a109ae06fdefb8ba39f531b3c18671830f (commit)

- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/scripts;a=commit;h=6e500fe08e9370cf75d3f2e3a564e443809b09f8

commit 6e500fe08e9370cf75d3f2e3a564e443809b09f8
Author: Martijn Kaijser <mcm.kaij...@gmail.com>
Date:   Wed Sep 11 09:58:54 2013 +0200

    [script.trakt] 2.3.1

diff --git a/script.trakt/addon.xml b/script.trakt/addon.xml
index d7aa5e4..853aedf 100644
--- a/script.trakt/addon.xml
+++ b/script.trakt/addon.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<addon id="script.trakt" name="trakt" version="2.3.0" provider-name="trakt.tv">
+<addon id="script.trakt" name="trakt" version="2.3.1" provider-name="trakt.tv">
        <requires>
                <import addon="xbmc.python" version="2.1.0"/>
                <import addon="script.module.simplejson" version="2.0.10"/>
diff --git a/script.trakt/changelog.txt b/script.trakt/changelog.txt
index f2e037f..eebe516 100644
--- a/script.trakt/changelog.txt
+++ b/script.trakt/changelog.txt
@@ -1,3 +1,8 @@
+version 2.3.1
+  - improved API error handling and debugging
+  - new context menu action via RunScript(script.trakt,action=contextmenu)
+  - silent option for manual sync via 
RunScript(script.trakt,action=sync,silent=True)
+
 version 2.3.0
   - moved debug settings to their own menu (nate1280)
   - new togglewatched action for skins/keymaps (nate1280)
diff --git a/script.trakt/resources/language/English/strings.xml 
b/script.trakt/resources/language/English/strings.xml
index 94baf2e..18f9fda 100644
--- a/script.trakt/resources/language/English/strings.xml
+++ b/script.trakt/resources/language/English/strings.xml
@@ -7,6 +7,7 @@
        <string id="1017">Number of Retries</string>
        <string id="1018">Startup Delay</string>
        <string id="1019">Force a reload of settings from trakt.tv, save 
settings when finished</string>
+       <string id="1020">Default script action</string>
        
        <!-- Rating Settings -->
        <string id="1030">Rating</string>
@@ -23,6 +24,8 @@
        <string id="1043">Minimum percent watched to scrobble</string>
        <string id="1044">During scrobbling, update ID for library movie if ID 
is missing</string>
        <string id="1045">During scrobbling, update ID for library tv show if 
ID is missing</string>
+       <string id="1046">Send watching call on seek</string>
+       <string id="1047">Send watching call on resume</string>
        <string id="1050">Exclusions</string>
        <string id="1051">Exclude Live TV</string>
        <string id="1052">Exclude HTTP sources</string> 
@@ -216,4 +219,17 @@
        <string id="1704">Simulate tagging</string>
        <string id="1720">Logging</string>
        <string id="1721">Simulate settings, if enabled will not make changes 
in XBMC or trakt.tv</string>
+
+       <!-- Context Menu Entries -->
+       <string id="2000">Manage Movie's Lists</string>
+       <string id="2001">Manage Show's Lists</string>
+       <string id="2010">Remove from Watchlist</string>
+       <string id="2020">Add to Watchlist</string>
+       <string id="2030">Rate this Movie</string>
+       <string id="2031">Rate this Show</string>
+       <string id="2032">Rate this Episode</string>
+       <string id="2040">Toggle Watched</string>
+       <string id="2050">Manage All Lists</string>
+       <string id="2060">Update All Tags</string>
+       <string id="2070">Synchronize Library</string>
 </strings>
diff --git a/script.trakt/resources/settings.xml 
b/script.trakt/resources/settings.xml
index 5538e42..006a434 100644
--- a/script.trakt/resources/settings.xml
+++ b/script.trakt/resources/settings.xml
@@ -5,6 +5,7 @@
                <setting id="password" type="text" option="hidden" label="1014" 
default="" />
                <setting id="retries" type="slider" label="1017" range="1,1,10" 
default="5" option="int"/>
                <setting id="startup_delay" type="slider" label="1018" 
range="0,30" default="0" option="int"/>
+               <setting id="default_action" type="enum" label="1020" 
values="Manual Sync|Manage Lists" default="0" />
                <setting type="action" label="1019" 
action="RunScript(script.trakt,action=loadsettings)"/>
        </category>
        <category label="1050"><!-- Exclusions -->
@@ -23,6 +24,8 @@
                <setting id="scrobble_min_view_time" type="slider" label="1043" 
range="0,5,100" default="80"/>
                <setting id="update_imdb_id" type="bool" label="1044" 
default="false"/>
                <setting id="update_tvdb_id" type="bool" label="1045" 
default="false"/>
+               <setting id="watching_call_on_seek" type="bool" label="1046" 
default="true"/>
+               <setting id="watching_call_on_resume" type="bool" label="1047" 
default="true"/>
        </category>
        <category label="1400"><!-- Synchronize -->
                <setting label="1410" type="lsep"/><!-- Service -->
diff --git a/script.trakt/script.py b/script.trakt/script.py
index a1ec449..afd9b28 100644
--- a/script.trakt/script.py
+++ b/script.trakt/script.py
@@ -6,6 +6,7 @@ import sys
 import queue
 import tagging
 import time
+from traktContextMenu import traktContextMenu
 
 try:
        import simplejson as json
@@ -27,9 +28,10 @@ def getMediaType():
 
 def getArguments():
        data = None
-       
+       default_actions = {0: "sync", 1: "managelists"}
+       default = utils.getSettingAsInt('default_action')
        if len(sys.argv) == 1:
-               data = {'action': "sync"}
+               data = {'action': default_actions[default]}
        else:
                data = {}
                for item in sys.argv:
@@ -45,8 +47,57 @@ def Main():
        args = getArguments()
        data = {}
 
+       if args['action'] == 'contextmenu':
+               buttons = []
+               media_type = getMediaType()
+
+               if utils.getSettingAsBool('tagging_enable'):
+                       if utils.isMovie(media_type):
+                               buttons.append("itemlists")
+                               dbid = int(xbmc.getInfoLabel('ListItem.DBID'))
+                               result = utils.getMovieDetailsFromXbmc(dbid, 
['tag'])
+                               if tagging.hasTraktWatchlistTag(result['tag']):
+                                       buttons.append("removefromlist")
+                               else:
+                                       buttons.append("addtolist")
+                       elif utils.isShow(media_type):
+                               buttons.append("itemlists")
+                               dbid = int(xbmc.getInfoLabel('ListItem.DBID'))
+                               result = utils.getShowDetailsFromXBMC(dbid, 
['tag'])
+                               if tagging.hasTraktWatchlistTag(result['tag']):
+                                       buttons.append("removefromlist")
+                               else:
+                                       buttons.append("addtolist")
+
+               if media_type in ['movie', 'show', 'episode']:
+                       buttons.append("rate")
+
+               if media_type in ['movie', 'show', 'season', 'episode']:
+                       buttons.append("togglewatched")
+
+               if utils.getSettingAsBool('tagging_enable'):
+                       buttons.append("managelists")
+                       buttons.append("updatetags")
+               buttons.append("sync")
+
+               contextMenu = traktContextMenu(media_type=media_type, 
buttons=buttons)
+               contextMenu.doModal()
+               _action = contextMenu.action
+               del contextMenu
+
+               if _action is None:
+                       return
+
+               utils.Debug("'%s' selected from trakt.tv action menu" % _action)
+               args['action'] = _action
+               if _action in ['addtolist', 'removefromlist']:
+                       args['list'] = "watchlist"
+
        if args['action'] == 'sync':
                data = {'action': 'manualSync'}
+               data['silent'] = False
+               if 'silent' in args:
+                       data['silent'] = (args['silent'].lower() == 'true')
 
        elif args['action'] == 'loadsettings':
                data = {'action': 'loadsettings', 'force': True}
diff --git a/script.trakt/scrobbler.py b/script.trakt/scrobbler.py
index 7206a88..823d9b3 100755
--- a/script.trakt/scrobbler.py
+++ b/script.trakt/scrobbler.py
@@ -117,6 +117,7 @@ class Scrobbler():
                                        self.curVideoInfo = 
utilities.getMovieDetailsFromXbmc(self.curVideo['id'], ['imdbnumber', 'title', 
'year'])
                                        if 
utilities.getSettingAsBool('rate_movie'):
                                                # pre-get sumamry information, 
for faster rating dialog.
+                                               Debug("[Scrobbler] Movie rating 
is enabled, pre-fetching summary information.")
                                                imdb_id = 
self.curVideoInfo['imdbnumber']
                                                if imdb_id.startswith("tt") or 
imdb_id.isdigit():
                                                        self.traktSummaryInfo = 
self.traktapi.getMovieSummary(self.curVideoInfo['imdbnumber'])
@@ -135,6 +136,7 @@ class Scrobbler():
                                        self.curVideoInfo = 
utilities.getEpisodeDetailsFromXbmc(self.curVideo['id'], ['showtitle', 
'season', 'episode', 'tvshowid', 'uniqueid'])
                                        if 
utilities.getSettingAsBool('rate_episode'):
                                                # pre-get sumamry information, 
for faster rating dialog.
+                                               Debug("[Scrobbler] Episode 
rating is enabled, pre-fetching summary information.")
                                                tvdb_id = 
self.curVideoInfo['tvdb_id']
                                                if tvdb_id.isdigit() or 
tvdb_id.startswith("tt"):
                                                        self.traktSummaryInfo = 
self.traktapi.getEpisodeSummary(tvdb_id, self.curVideoInfo['season'], 
self.curVideoInfo['episode'])
@@ -173,7 +175,8 @@ class Scrobbler():
                        self.pausedAt = 0
                        self.isPaused = False
                        self.update(True)
-                       self.watching()
+                       if 
utilities.getSettingAsBool('watching_call_on_resume'):
+                               self.watching()
 
        def playbackPaused(self):
                if not self.isPlaying:
@@ -191,7 +194,8 @@ class Scrobbler():
 
                Debug("[Scrobbler] playbackSeek()")
                self.update(True)
-               self.watching()
+               if utilities.getSettingAsBool('watching_call_on_seek'):
+                       self.watching()
 
        def playbackEnded(self):
                if not self.isPlaying:
@@ -239,9 +243,10 @@ class Scrobbler():
                                                        
self.curVideoInfo['imdbnumber'] = response['movie']['imdb_id']
                                                        if 'id' in 
self.curVideo and utilities.getSettingAsBool('update_imdb_id'):
                                                                req = 
{"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.SetMovieDetails", "params": 
{"movieid" : self.curVideoInfo['movieid'], "imdbnumber": 
self.curVideoInfo['imdbnumber']}}
-                                                               
utils.xbmcJsonRequest(req)
+                                                               
utilities.xbmcJsonRequest(req)
                                                        # get summary data now 
if we are rating this movie
                                                        if 
utilities.getSettingAsBool('rate_movie') and self.traktSummaryInfo is None:
+                                                               
Debug("[Scrobbler] Movie rating is enabled, pre-fetching summary information.")
                                                                
self.traktSummaryInfo = 
self.traktapi.getMovieSummary(self.curVideoInfo['imdbnumber'])
 
                                Debug("[Scrobbler] Watch response: %s" % 
str(response))
@@ -262,9 +267,10 @@ class Scrobbler():
                                                        
self.curVideoInfo['tvdb_id'] = response['show']['tvdb_id']
                                                        if 'id' in 
self.curVideo and utilities.getSettingAsBool('update_tvdb_id'):
                                                                req = 
{"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.SetTVShowDetails", 
"params": {"tvshowid" : self.curVideoInfo['tvshowid'], "imdbnumber": 
self.curVideoInfo['tvdb_id']}}
-                                                               
utils.xbmcJsonRequest(req)
+                                                               
utilities.xbmcJsonRequest(req)
                                                        # get summary data now 
if we are rating this episode
                                                        if 
utilities.getSettingAsBool('rate_episode') and self.traktSummaryInfo is None:
+                                                               
Debug("[Scrobbler] Episode rating is enabled, pre-fetching summary 
information.")
                                                                
self.traktSummaryInfo = 
self.traktapi.getEpisodeSummary(self.curVideoInfo['tvdb_id'], 
self.curVideoInfo['season'], self.curVideoInfo['episode'])
 
                                Debug("[Scrobbler] Watch response: %s" % 
str(response))
@@ -304,6 +310,8 @@ class Scrobbler():
                                        if 
response['error'].startswith("scrobbled") and 
response['error'].endswith("already"):
                                                Debug("[Scrobbler] Movie was 
just recently scrobbled, attempting to cancel watching instead.")
                                                self.stoppedWatching()
+                                       elif response['error'] == "movie not 
found":
+                                               Debug("[Scrobbler] Movie '%s' 
was not found on trakt.tv, possible malformed XBMC metadata." % 
self.curVideoInfo['title'])
 
                elif utilities.isEpisode(self.curVideo['type']) and 
scrobbleEpisodeOption:
                        if self.isMultiPartEpisode:
@@ -320,6 +328,8 @@ class Scrobbler():
                                        if 
response['error'].startswith("scrobbled") and 
response['error'].endswith("already"):
                                                Debug("[Scrobbler] Episode was 
just recently scrobbled, attempting to cancel watching instead.")
                                                self.stoppedWatching()
+                                       elif response['error'] == "show not 
found":
+                                               Debug("[Scrobbler] Show '%s' 
was not found on trakt.tv, possible malformed XBMC metadata." % 
self.curVideoInfo['showtitle'])
 
        def watchlistTagCheck(self):
                if not utilities.isMovie(self.curVideo['type']):
@@ -343,7 +353,7 @@ class Scrobbler():
                                tagging.xbmcSetTags(id, self.curVideo['type'], 
s, tags)
 
                else:
-                       utils.Debug("No data was returned from XBMC, aborting 
tag udpate.")
+                       utilities.Debug("No data was returned from XBMC, 
aborting tag udpate.")
 
        def check(self):
                scrobbleMinViewTimeOption = 
utilities.getSettingAsFloat("scrobble_min_view_time")
diff --git a/script.trakt/service.py b/script.trakt/service.py
index 410a109..1144585 100644
--- a/script.trakt/service.py
+++ b/script.trakt/service.py
@@ -72,7 +72,7 @@ class traktService:
                elif action == 'manualSync':
                        if not self.syncThread.isAlive():
                                utilities.Debug("Performing a manual sync.")
-                               self.doSync(manual=True)
+                               self.doSync(manual=True, silent=data['silent'])
                        else:
                                utilities.Debug("There already is a sync in 
progress.")
                elif action == 'updatetags':
@@ -345,21 +345,22 @@ class traktService:
                                                if markedNotification:
                                                        
utilities.notification(utilities.getString(1550), utilities.getString(1552) % 
(len(params['episodes']), s))
 
-       def doSync(self, manual=False):
-               self.syncThread = syncThread(manual)
+       def doSync(self, manual=False, silent=False):
+               self.syncThread = syncThread(manual, silent)
                self.syncThread.start()
 
 class syncThread(threading.Thread):
 
        _isManual = False
 
-       def __init__(self, isManual=False):
+       def __init__(self, isManual=False, runSilent=False):
                threading.Thread.__init__(self)
                self.name = "trakt-sync"
                self._isManual = isManual
+               self._runSilent = runSilent
 
        def run(self):
-               sync = Sync(show_progress=self._isManual, api=globals.traktapi)
+               sync = Sync(show_progress=self._isManual, 
run_silent=self._runSilent, api=globals.traktapi)
                sync.sync()
                
                if utilities.getSettingAsBool('tagging_enable') and 
utilities.getSettingAsBool('tagging_tag_after_sync'):
diff --git a/script.trakt/sync.py b/script.trakt/sync.py
index 428deb5..97eeccd 100644
--- a/script.trakt/sync.py
+++ b/script.trakt/sync.py
@@ -10,9 +10,12 @@ progress = xbmcgui.DialogProgress()
 
 class Sync():
 
-       def __init__(self, show_progress=False, api=None):
+       def __init__(self, show_progress=False, run_silent=False, api=None):
                self.traktapi = api
                self.show_progress = show_progress
+               self.run_silent = run_silent
+               if self.show_progress and self.run_silent:
+                       Debug("[Sync] Sync is being run silently.")
                self.notify = 
utilities.getSettingAsBool('show_sync_notifications')
                self.simulate = utilities.getSettingAsBool('simulate_sync')
                if self.simulate:
@@ -28,7 +31,7 @@ class Sync():
                                        self.exclusions.append(_path)
 
        def isCanceled(self):
-               if self.show_progress and progress.iscanceled():
+               if self.show_progress and not self.run_silent and 
progress.iscanceled():
                        Debug("[Sync] Sync was canceled by user.")
                        return True
                elif xbmc.abortRequested:
@@ -38,7 +41,7 @@ class Sync():
                        return False
 
        def updateProgress(self, *args, **kwargs):
-               if self.show_progress:
+               if self.show_progress and not self.run_silent:
                        kwargs['percent'] = args[0]
                        progress.update(**kwargs)
 
@@ -417,17 +420,21 @@ class Sync():
        def syncEpisodes(self):
                if not self.show_progress and 
utilities.getSettingAsBool('sync_on_update') and self.notify:
                        notification('%s %s' % (utilities.getString(1400), 
utilities.getString(1406)), utilities.getString(1420)) #Sync started
-               if self.show_progress:
+               if self.show_progress and not self.run_silent:
                        progress.create("%s %s" % (utilities.getString(1400), 
utilities.getString(1406)), line1=" ", line2=" ", line3=" ")
 
                xbmcShows = self.xbmcLoadShows()
                if not isinstance(xbmcShows, list) and not xbmcShows:
                        Debug("[Episodes Sync] XBMC show list is empty, 
aborting tv show Sync.")
+                       if self.show_progress and not self.run_silent:
+                               progress.close()
                        return
 
                traktShows = self.traktLoadShows()
                if not isinstance(traktShows, list):
                        Debug("[Episodes Sync] Error getting trakt.tv show 
list, aborting tv show sync.")
+                       if self.show_progress and not self.run_silent:
+                               progress.close()
                        return
 
                if utilities.getSettingAsBool('add_episodes_to_trakt') and not 
self.isCanceled():
@@ -443,13 +450,13 @@ class Sync():
                        self.xbmcUpdateEpisodes(xbmcShowsUpadate)
 
                if utilities.getSettingAsBool('clean_trakt_episodes') and not 
self.isCanceled():
-                       raktShowsRemove = self.compareShows(traktShows, 
xbmcShows)
-                       self.traktRemoveEpisodes(raktShowsRemove)
+                       traktShowsRemove = self.compareShows(traktShows, 
xbmcShows)
+                       self.traktRemoveEpisodes(traktShowsRemove)
 
                if not self.show_progress and 
utilities.getSettingAsBool('sync_on_update') and self.notify:
                        notification('%s %s' % (utilities.getString(1400), 
utilities.getString(1406)), utilities.getString(1421)) #Sync complete
 
-               if not self.isCanceled() and self.show_progress:
+               if not self.isCanceled() and self.show_progress and not 
self.run_silent:
                        self.updateProgress(100, line1=" ", 
line2=utilities.getString(1442), line3=" ")
                        progress.close()
 
@@ -554,6 +561,7 @@ class Sync():
                        del(movie['imdbnumber'])
                        del(movie['lastplayed'])
                        del(movie['label'])
+                       del(movie['file'])
 
                        xbmc_movies.append(movie)
 
@@ -699,17 +707,21 @@ class Sync():
        def syncMovies(self):
                if not self.show_progress and 
utilities.getSettingAsBool('sync_on_update') and self.notify:
                        notification('%s %s' % (utilities.getString(1400), 
utilities.getString(1402)), utilities.getString(1420)) #Sync started
-               if self.show_progress:
+               if self.show_progress and not self.run_silent:
                        progress.create("%s %s" % (utilities.getString(1400), 
utilities.getString(1402)), line1=" ", line2=" ", line3=" ")
 
                xbmcMovies = self.xbmcLoadMovies()
                if not isinstance(xbmcMovies, list) and not xbmcMovies:
                        Debug("[Movies Sync] XBMC movie list is empty, aborting 
movie Sync.")
+                       if self.show_progress and not self.run_silent:
+                               progress.close()
                        return
 
                traktMovies = self.traktLoadMovies()
                if not isinstance(traktMovies, list):
                        Debug("[Movies Sync] Error getting trakt.tv movie list, 
aborting movie Sync.")
+                       if self.show_progress and not self.run_silent:
+                               progress.close()
                        return
 
                if utilities.getSettingAsBool('add_movies_to_trakt') and not 
self.isCanceled():
@@ -728,7 +740,7 @@ class Sync():
                        traktMoviesToRemove = self.compareMovies(traktMovies, 
xbmcMovies)
                        self.traktRemoveMovies(traktMoviesToRemove)
 
-               if not self.isCanceled() and self.show_progress:
+               if not self.isCanceled() and self.show_progress and not 
self.run_silent:
                        self.updateProgress(100, 
line1=utilities.getString(1431), line2=" ", line3=" ")
                        progress.close()
 
diff --git a/script.trakt/traktapi.py b/script.trakt/traktapi.py
index 40079e2..f9a514d 100644
--- a/script.trakt/traktapi.py
+++ b/script.trakt/traktapi.py
@@ -38,6 +38,7 @@ class traktError(Exception):
 class traktAuthProblem(traktError): pass
 class traktServerBusy(traktError): pass
 class traktUnknownError(traktError): pass
+class traktNotFoundError(traktError): pass
 class traktNetworkError(traktError):
        def __init__(self, value, timeout):
                super(traktNetworkError, self).__init__(value)
@@ -94,7 +95,12 @@ class traktAPI(object):
                                elif e.code == 503: # server busy problem
                                        raise traktServerBusy(error_data)
                                else:
-                                       raise traktUnknownError(error_data, 
e.code)
+                                       try:
+                                               _data = json.loads(error_data)
+                                               if 'status' in _data:
+                                                       data = error_data
+                                       except ValueError:
+                                               raise 
traktUnknownError(error_data, e.code)
 
                        elif hasattr(e, 'reason'): # usually a read timeout, or 
unable to reach host
                                raise traktNetworkError(str(e.reason), 
isinstance(e.reason, socket.timeout))
@@ -161,6 +167,7 @@ class traktAPI(object):
                        except traktError, e:
                                if isinstance(e, traktServerBusy):
                                        Debug("[traktAPI] traktRequest(): (%i) 
Server Busy (%s)" % (i, e.value))
+                                       xbmc.sleep(5000)
                                elif isinstance(e, traktAuthProblem):
                                        Debug("[traktAPI] traktRequest(): (%i) 
Authentication Failure (%s)" % (i, e.value))
                                        setSetting('account_valid', False)
@@ -199,12 +206,12 @@ class traktAPI(object):
                                        Debug("[traktAPI] traktRequest(): (%i) 
JSON response: '%s'" % (i, str(data)))
                        except ValueError:
                                # malformed json response
-                               Debug("[traktAPI] traktRequest(): (%i) Bad JSON 
response: '%s'", (i, raw))
+                               Debug("[traktAPI] traktRequest(): (%i) Bad JSON 
response: '%s'" % (i, raw))
                                if not silent:
                                        notification('trakt', getString(1109) + 
": Bad response from trakt") # Error
                                
                        # check for the status variable in JSON data
-                       if 'status' in data:
+                       if data and 'status' in data:
                                if data['status'] == 'success':
                                        break
                                elif returnOnFailure and data['status'] == 
'failure':
diff --git a/script.trakt/utilities.py b/script.trakt/utilities.py
index e6e2806..ec67d4e 100755
--- a/script.trakt/utilities.py
+++ b/script.trakt/utilities.py
@@ -16,6 +16,9 @@ except ImportError:
 # read settings
 __addon__ = xbmcaddon.Addon('script.trakt')
 
+# make strptime call prior to doing anything, to try and prevent threading 
errors
+time.strptime("1970-01-01 12:00:00", "%Y-%m-%d %H:%M:%S")
+
 def Debug(msg, force = False):
        if(getSettingAsBool('debug') or force):
                try:

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

Summary of changes:
 script.trakt/.gitignore                            |    4 +
 script.trakt/addon.xml                             |    2 +-
 script.trakt/changelog.txt                         |    5 +
 .../resources/language/English/strings.xml         |   16 ++++
 script.trakt/resources/settings.xml                |    3 +
 .../skins/Default/720p/traktContextMenu.xml        |   85 ++++++++++++++++++++
 script.trakt/script.py                             |   55 ++++++++++++-
 script.trakt/scrobbler.py                          |   20 ++++-
 script.trakt/service.py                            |   11 ++-
 script.trakt/sync.py                               |   30 +++++--
 script.trakt/traktContextMenu.py                   |   82 +++++++++++++++++++
 script.trakt/traktapi.py                           |   13 +++-
 script.trakt/utilities.py                          |    3 +
 13 files changed, 304 insertions(+), 25 deletions(-)
 create mode 100644 script.trakt/.gitignore
 create mode 100644 
script.trakt/resources/skins/Default/720p/traktContextMenu.xml
 create mode 100644 script.trakt/traktContextMenu.py


hooks/post-receive
-- 
Scripts

------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. Consolidate legacy IT systems to a single system of record for IT
2. Standardize and globalize service processes across IT
3. Implement zero-touch automation to replace manual, redundant tasks
http://pubads.g.doubleclick.net/gampad/clk?id=51271111&iu=/4140/ostg.clktrk
_______________________________________________
Xbmc-addons mailing list
Xbmc-addons@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/xbmc-addons

Reply via email to