def run(self): #while xbmc is running scrobbler = Scrobbler() scrobbler.start() while (not (self.abortRequested or xbmc.abortRequested)): time.sleep(1) try: tn = telnetlib.Telnet('localhost', 9090, 10) except IOError as (errno, strerror): #connection failed, try again soon Debug("[Notification Service] Telnet too soon? ("+str(errno)+") "+strerror) time.sleep(1) continue Debug("[Notification Service] Waiting~"); bCount = 0 while (not (self.abortRequested or xbmc.abortRequested)): try: if bCount == 0: notification = "" inString = False [index, match, raw] = tn.expect(["(\\\\)|(\\\")|[{\"}]"], 0.2) #note, pre-compiled regex might be faster here notification += raw if index == -1: # Timeout continue if index == 0: # Found escaped quote match = match.group(0) if match == "\"": inString = not inString continue if match == "{": bCount += 1 if match == "}": bCount -= 1 if bCount > 0: continue if bCount < 0: bCount = 0 except EOFError: break #go out to the other loop to restart the connection Debug("[Notification Service] message: " + str(notification)) # Parse recieved notification data = json.loads(notification) # Forward notification to functions if 'method' in data and 'params' in data and 'sender' in data['params'] and data['params']['sender'] == 'xbmc': if data['method'] == 'Player.OnStop': scrobbler.playbackEnded() elif data['method'] == 'Player.OnPlay': if 'data' in data['params'] and 'item' in data['params']['data'] and 'type' in data['params']['data']['item']: scrobbler.playbackStarted(data['params']['data']) elif data['method'] == 'Player.OnPause': scrobbler.playbackPaused() elif data['method'] == 'System.OnQuit': self.abortRequested = True
class traktService: scrobbler = None updateTagsThread = None syncThread = None dispatchQueue = sqlitequeue.SqliteQueue() def __init__(self): threading.Thread.name = 'trakt' def _dispatchQueue(self, data): logger.debug("Queuing for dispatch: %s" % data) self.dispatchQueue.append(data) def _dispatch(self, data): try: logger.debug("Dispatch: %s" % data) action = data['action'] if action == 'started': del data['action'] self.scrobbler.playbackStarted(data) elif action == 'ended' or action == 'stopped': self.scrobbler.playbackEnded() elif action == 'paused': self.scrobbler.playbackPaused() elif action == 'resumed': self.scrobbler.playbackResumed() elif action == 'seek' or action == 'seekchapter': self.scrobbler.playbackSeek() elif action == 'scanFinished': if kodiUtilities.getSettingAsBool('sync_on_update'): logger.debug("Performing sync after library update.") self.doSync() elif action == 'databaseCleaned': if kodiUtilities.getSettingAsBool('sync_on_update') and (kodiUtilities.getSettingAsBool('clean_trakt_movies') or kodiUtilities.getSettingAsBool('clean_trakt_episodes')): logger.debug("Performing sync after library clean.") self.doSync() elif action == 'markWatched': del data['action'] self.doMarkWatched(data) elif action == 'manualRating': ratingData = data['ratingData'] self.doManualRating(ratingData) elif action == 'addtowatchlist': # add to watchlist del data['action'] self.doAddToWatchlist(data) elif action == 'manualSync': if not self.syncThread.isAlive(): logger.debug("Performing a manual sync.") self.doSync(manual=True, silent=data['silent'], library=data['library']) else: logger.debug("There already is a sync in progress.") elif action == 'settings': kodiUtilities.showSettings() elif action == 'auth_info': xbmc.executebuiltin('Dialog.Close(all, true)') # init traktapi class globals.traktapi = traktAPI(True) else: logger.debug("Unknown dispatch action, '%s'." % action) except Exception as ex: message = utilities.createError(ex) logger.fatal(message) def run(self): startup_delay = kodiUtilities.getSettingAsInt('startup_delay') if startup_delay: logger.debug("Delaying startup by %d seconds." % startup_delay) xbmc.sleep(startup_delay * 1000) logger.debug("Service thread starting.") # purge queue before doing anything self.dispatchQueue.purge() # setup event driven classes self.Player = traktPlayer(action=self._dispatchQueue) self.Monitor = traktMonitor(action=self._dispatchQueue) # init traktapi class globals.traktapi = traktAPI() # init sync thread self.syncThread = syncThread() # init scrobbler class self.scrobbler = Scrobbler(globals.traktapi) AddonSignals.registerSlot('service.nextup.notification', 'NEXTUPWATCHEDSIGNAL', self.callback) # start loop for events while not self.Monitor.abortRequested(): while len(self.dispatchQueue) and (not self.Monitor.abortRequested()): data = self.dispatchQueue.get() logger.debug("Queued dispatch: %s" % data) self._dispatch(data) if xbmc.Player().isPlayingVideo(): self.scrobbler.transitionCheck() if self.Monitor.waitForAbort(1): # Abort was requested while waiting. We should exit break # we are shutting down logger.debug("Beginning shut down.") # delete player/monitor del self.Player del self.Monitor # check if sync thread is running, if so, join it. if self.syncThread.isAlive(): self.syncThread.join() def doManualRating(self, data): action = data['action'] media_type = data['media_type'] summaryInfo = None if not utilities.isValidMediaType(media_type): logger.debug("doManualRating(): Invalid media type '%s' passed for manual %s." % (media_type, action)) return if not data['action'] in ['rate', 'unrate']: logger.debug("doManualRating(): Unknown action passed.") return logger.debug("Getting data for manual %s of %s: video_id: |%s| dbid: |%s|" % (action, media_type, data.get('video_id'), data.get('dbid'))) id_type = utilities.parseIdToTraktIds(str(data['video_id']), media_type)[1] if not id_type: logger.debug("doManualRating(): Unrecognized id_type: |%s|-|%s|." % (media_type, data['video_id'])) return ids = globals.traktapi.getIdLookup(data['video_id'], id_type) if not ids: logger.debug("doManualRating(): No Results for: |%s|-|%s|." % (media_type, data['video_id'])) return trakt_id = dict(ids[0].keys)['trakt'] if utilities.isEpisode(media_type): summaryInfo = globals.traktapi.getEpisodeSummary(trakt_id, data['season'], data['episode']) userInfo = globals.traktapi.getEpisodeRatingForUser(trakt_id, data['season'], data['episode'], 'trakt') elif utilities.isSeason(media_type): summaryInfo = globals.traktapi.getShowSummary(trakt_id) userInfo = globals.traktapi.getSeasonRatingForUser(trakt_id, data['season'], 'trakt') elif utilities.isShow(media_type): summaryInfo = globals.traktapi.getShowSummary(trakt_id) userInfo = globals.traktapi.getShowRatingForUser(trakt_id, 'trakt') elif utilities.isMovie(media_type): summaryInfo = globals.traktapi.getMovieSummary(trakt_id) userInfo = globals.traktapi.getMovieRatingForUser(trakt_id, 'trakt') if summaryInfo is not None: summaryInfo = summaryInfo.to_dict() summaryInfo['user'] = {'ratings': userInfo} if utilities.isEpisode(media_type): summaryInfo['season'] = data['season'] summaryInfo['number'] = data['episode'] summaryInfo['episodeid'] = data.get('dbid') elif utilities.isSeason(media_type): summaryInfo['season'] = data['season'] elif utilities.isMovie(media_type): summaryInfo['movieid'] = data.get('dbid') elif utilities.isShow(media_type): summaryInfo['tvshowid'] = data.get('dbid') if action == 'rate': if not 'rating' in data: rateMedia(media_type, [summaryInfo]) else: rateMedia(media_type, [summaryInfo], rating=data['rating']) else: logger.debug("doManualRating(): Summary info was empty, possible problem retrieving data from Trakt.tv") def doAddToWatchlist(self, data): media_type = data['media_type'] if utilities.isMovie(media_type): summaryInfo = globals.traktapi.getMovieSummary(data['id']).to_dict() if summaryInfo: s = utilities.getFormattedItemName(media_type, summaryInfo) logger.debug("doAddToWatchlist(): '%s' trying to add to users watchlist." % s) params = {'movies': [summaryInfo]} logger.debug("doAddToWatchlist(): %s" % str(params)) result = globals.traktapi.addToWatchlist(params) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s) elif utilities.isEpisode(media_type): summaryInfo = {'shows': [{'ids': utilities.parseIdToTraktIds(data['id'], media_type)[0], 'seasons': [{'number': data['season'], 'episodes': [{'number':data['number']}]}]}]} logger.debug("doAddToWatchlist(): %s" % str(summaryInfo)) s = utilities.getFormattedItemName(media_type, data) result = globals.traktapi.addToWatchlist(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s) elif utilities.isSeason(media_type): summaryInfo = {'shows': [{'ids': utilities.parseIdToTraktIds(data['id'], media_type)[0], 'seasons': [{'number': data['season']}]}]} s = utilities.getFormattedItemName(media_type, data) logger.debug("doAddToWatchlist(): '%s - Season %d' trying to add to users watchlist." % (data['id'], data['season'])) result = globals.traktapi.addToWatchlist(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s) elif utilities.isShow(media_type): summaryInfo = {'shows': [{'ids': utilities.parseIdToTraktIds(data['id'], media_type)[0]}]} s = utilities.getFormattedItemName(media_type, data) logger.debug("doAddToWatchlist(): %s" % str(summaryInfo)) result = globals.traktapi.addToWatchlist(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s) def doMarkWatched(self, data): media_type = data['media_type'] if utilities.isMovie(media_type): summaryInfo = globals.traktapi.getMovieSummary(data['id']).to_dict() if summaryInfo: if not summaryInfo['watched']: s = utilities.getFormattedItemName(media_type, summaryInfo) logger.debug("doMarkWatched(): '%s' is not watched on Trakt, marking it as watched." % s) params = {'movies': [summaryInfo]} logger.debug("doMarkWatched(): %s" % str(params)) result = globals.traktapi.addToHistory(params) if result: kodiUtilities.notification(kodiUtilities.getString(32113), s) else: kodiUtilities.notification(kodiUtilities.getString(32114), s) elif utilities.isEpisode(media_type): summaryInfo = {'shows': [{'ids':utilities.parseIdToTraktIds(data['id'],media_type)[0], 'seasons': [{'number': data['season'], 'episodes': [{'number':data['number']}]}]}]} logger.debug("doMarkWatched(): %s" % str(summaryInfo)) s = utilities.getFormattedItemName(media_type, data) result = globals.traktapi.addToHistory(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32113), s) else: kodiUtilities.notification(kodiUtilities.getString(32114), s) elif utilities.isSeason(media_type): summaryInfo = {'shows': [{'ids':utilities.parseIdToTraktIds(data['id'],media_type)[0], 'seasons': [{'number': data['season'], 'episodes': []}]}]} s = utilities.getFormattedItemName(media_type, data) for ep in data['episodes']: summaryInfo['shows'][0]['seasons'][0]['episodes'].append({'number': ep}) logger.debug("doMarkWatched(): '%s - Season %d' has %d episode(s) that are going to be marked as watched." % (data['id'], data['season'], len(summaryInfo['shows'][0]['seasons'][0]['episodes']))) self.addEpisodesToHistory(summaryInfo, s) elif utilities.isShow(media_type): summaryInfo = {'shows': [{'ids':utilities.parseIdToTraktIds(data['id'],media_type)[0], 'seasons': []}]} if summaryInfo: s = utilities.getFormattedItemName(media_type, data) logger.debug('data: %s' % data) for season in data['seasons']: episodeJson = [] for episode in data['seasons'][season]: episodeJson.append({'number': episode}) summaryInfo['shows'][0]['seasons'].append({'number': season, 'episodes': episodeJson}) self.addEpisodesToHistory(summaryInfo, s) def addEpisodesToHistory(self, summaryInfo, s): if len(summaryInfo['shows'][0]['seasons'][0]['episodes']) > 0: logger.debug("doMarkWatched(): %s" % str(summaryInfo)) result = globals.traktapi.addToHistory(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32113), kodiUtilities.getString(32115) % (result['added']['episodes'], s)) else: kodiUtilities.notification(kodiUtilities.getString(32114), s) def doSync(self, manual=False, silent=False, library="all"): self.syncThread = syncThread(manual, silent, library) self.syncThread.start() def callback(self, data): logger.debug('Callback received - Nextup skipped to the next episode') self.scrobbler.playbackEnded()
class traktService: scrobbler = None updateTagsThread = None syncThread = None dispatchQueue = sqlitequeue.SqliteQueue() def __init__(self): threading.Thread.name = 'trakt' def _dispatchQueue(self, data): logger.debug("Queuing for dispatch: %s" % data) self.dispatchQueue.append(data) def _dispatch(self, data): try: logger.debug("Dispatch: %s" % data) action = data['action'] if action == 'started': del data['action'] self.scrobbler.playbackStarted(data) elif action == 'ended' or action == 'stopped': self.scrobbler.playbackEnded() elif action == 'paused': self.scrobbler.playbackPaused() elif action == 'resumed': self.scrobbler.playbackResumed() elif action == 'seek' or action == 'seekchapter': self.scrobbler.playbackSeek() elif action == 'scanFinished': if kodiUtilities.getSettingAsBool('sync_on_update'): logger.debug("Performing sync after library update.") self.doSync() elif action == 'databaseCleaned': if kodiUtilities.getSettingAsBool('sync_on_update') and ( kodiUtilities.getSettingAsBool('clean_trakt_movies') or kodiUtilities.getSettingAsBool('clean_trakt_episodes') ): logger.debug("Performing sync after library clean.") self.doSync() elif action == 'markWatched': del data['action'] self.doMarkWatched(data) elif action == 'manualRating': ratingData = data['ratingData'] self.doManualRating(ratingData) elif action == 'addtowatchlist': # add to watchlist del data['action'] self.doAddToWatchlist(data) elif action == 'manualSync': if not self.syncThread.isAlive(): logger.debug("Performing a manual sync.") self.doSync(manual=True, silent=data['silent'], library=data['library']) else: logger.debug("There already is a sync in progress.") elif action == 'settings': kodiUtilities.showSettings() elif action == 'auth_info': xbmc.executebuiltin('Dialog.Close(all, true)') # init traktapi class globals.traktapi = traktAPI(True) else: logger.debug("Unknown dispatch action, '%s'." % action) except Exception as ex: message = utilities.createError(ex) logger.fatal(message) def run(self): startup_delay = kodiUtilities.getSettingAsInt('startup_delay') if startup_delay: logger.debug("Delaying startup by %d seconds." % startup_delay) xbmc.sleep(startup_delay * 1000) logger.debug("Service thread starting.") # purge queue before doing anything self.dispatchQueue.purge() # setup event driven classes self.Player = traktPlayer(action=self._dispatchQueue) self.Monitor = traktMonitor(action=self._dispatchQueue) # init traktapi class globals.traktapi = traktAPI() # init sync thread self.syncThread = syncThread() # init scrobbler class self.scrobbler = Scrobbler(globals.traktapi) AddonSignals.registerSlot('service.nextup.notification', 'NEXTUPWATCHEDSIGNAL', self.callback) # start loop for events while not self.Monitor.abortRequested(): while len(self.dispatchQueue) and ( not self.Monitor.abortRequested()): data = self.dispatchQueue.get() logger.debug("Queued dispatch: %s" % data) self._dispatch(data) if xbmc.Player().isPlayingVideo(): self.scrobbler.transitionCheck() if self.Monitor.waitForAbort(1): # Abort was requested while waiting. We should exit break # we are shutting down logger.debug("Beginning shut down.") # delete player/monitor del self.Player del self.Monitor # check if sync thread is running, if so, join it. if self.syncThread.isAlive(): self.syncThread.join() def doManualRating(self, data): action = data['action'] media_type = data['media_type'] summaryInfo = None if not utilities.isValidMediaType(media_type): logger.debug( "doManualRating(): Invalid media type '%s' passed for manual %s." % (media_type, action)) return if not data['action'] in ['rate', 'unrate']: logger.debug("doManualRating(): Unknown action passed.") return logger.debug( "Getting data for manual %s of %s: video_id: |%s| dbid: |%s|" % (action, media_type, data.get('video_id'), data.get('dbid'))) id_type = utilities.parseIdToTraktIds(str(data['video_id']), media_type)[1] if not id_type: logger.debug("doManualRating(): Unrecognized id_type: |%s|-|%s|." % (media_type, data['video_id'])) return ids = globals.traktapi.getIdLookup(data['video_id'], id_type) if not ids: logger.debug("doManualRating(): No Results for: |%s|-|%s|." % (media_type, data['video_id'])) return trakt_id = dict(ids[0].keys)['trakt'] if utilities.isEpisode(media_type): summaryInfo = globals.traktapi.getEpisodeSummary( trakt_id, data['season'], data['episode']) userInfo = globals.traktapi.getEpisodeRatingForUser( trakt_id, data['season'], data['episode'], 'trakt') elif utilities.isSeason(media_type): summaryInfo = globals.traktapi.getShowSummary(trakt_id) userInfo = globals.traktapi.getSeasonRatingForUser( trakt_id, data['season'], 'trakt') elif utilities.isShow(media_type): summaryInfo = globals.traktapi.getShowSummary(trakt_id) userInfo = globals.traktapi.getShowRatingForUser(trakt_id, 'trakt') elif utilities.isMovie(media_type): summaryInfo = globals.traktapi.getMovieSummary(trakt_id) userInfo = globals.traktapi.getMovieRatingForUser( trakt_id, 'trakt') if summaryInfo is not None: summaryInfo = summaryInfo.to_dict() summaryInfo['user'] = {'ratings': userInfo} if utilities.isEpisode(media_type): summaryInfo['season'] = data['season'] summaryInfo['number'] = data['episode'] summaryInfo['episodeid'] = data.get('dbid') elif utilities.isSeason(media_type): summaryInfo['season'] = data['season'] elif utilities.isMovie(media_type): summaryInfo['movieid'] = data.get('dbid') elif utilities.isShow(media_type): summaryInfo['tvshowid'] = data.get('dbid') if action == 'rate': if not 'rating' in data: rateMedia(media_type, [summaryInfo]) else: rateMedia(media_type, [summaryInfo], rating=data['rating']) else: logger.debug( "doManualRating(): Summary info was empty, possible problem retrieving data from Trakt.tv" ) def doAddToWatchlist(self, data): media_type = data['media_type'] if utilities.isMovie(media_type): summaryInfo = globals.traktapi.getMovieSummary( data['id']).to_dict() if summaryInfo: s = utilities.getFormattedItemName(media_type, summaryInfo) logger.debug( "doAddToWatchlist(): '%s' trying to add to users watchlist." % s) params = {'movies': [summaryInfo]} logger.debug("doAddToWatchlist(): %s" % str(params)) result = globals.traktapi.addToWatchlist(params) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s) elif utilities.isEpisode(media_type): summaryInfo = { 'shows': [{ 'ids': utilities.parseIdToTraktIds(data['id'], media_type)[0], 'seasons': [{ 'number': data['season'], 'episodes': [{ 'number': data['number'] }] }] }] } logger.debug("doAddToWatchlist(): %s" % str(summaryInfo)) s = utilities.getFormattedItemName(media_type, data) result = globals.traktapi.addToWatchlist(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s) elif utilities.isSeason(media_type): summaryInfo = { 'shows': [{ 'ids': utilities.parseIdToTraktIds(data['id'], media_type)[0], 'seasons': [{ 'number': data['season'] }] }] } s = utilities.getFormattedItemName(media_type, data) logger.debug( "doAddToWatchlist(): '%s - Season %d' trying to add to users watchlist." % (data['id'], data['season'])) result = globals.traktapi.addToWatchlist(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s) elif utilities.isShow(media_type): summaryInfo = { 'shows': [{ 'ids': utilities.parseIdToTraktIds(data['id'], media_type)[0] }] } s = utilities.getFormattedItemName(media_type, data) logger.debug("doAddToWatchlist(): %s" % str(summaryInfo)) result = globals.traktapi.addToWatchlist(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s) def doMarkWatched(self, data): media_type = data['media_type'] if utilities.isMovie(media_type): summaryInfo = globals.traktapi.getMovieSummary( data['id']).to_dict() if summaryInfo: if not summaryInfo['watched']: s = utilities.getFormattedItemName(media_type, summaryInfo) logger.debug( "doMarkWatched(): '%s' is not watched on Trakt, marking it as watched." % s) params = {'movies': [summaryInfo]} logger.debug("doMarkWatched(): %s" % str(params)) result = globals.traktapi.addToHistory(params) if result: kodiUtilities.notification( kodiUtilities.getString(32113), s) else: kodiUtilities.notification( kodiUtilities.getString(32114), s) elif utilities.isEpisode(media_type): summaryInfo = { 'shows': [{ 'ids': utilities.parseIdToTraktIds(data['id'], media_type)[0], 'seasons': [{ 'number': data['season'], 'episodes': [{ 'number': data['number'] }] }] }] } logger.debug("doMarkWatched(): %s" % str(summaryInfo)) s = utilities.getFormattedItemName(media_type, data) result = globals.traktapi.addToHistory(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32113), s) else: kodiUtilities.notification(kodiUtilities.getString(32114), s) elif utilities.isSeason(media_type): summaryInfo = { 'shows': [{ 'ids': utilities.parseIdToTraktIds(data['id'], media_type)[0], 'seasons': [{ 'number': data['season'], 'episodes': [] }] }] } s = utilities.getFormattedItemName(media_type, data) for ep in data['episodes']: summaryInfo['shows'][0]['seasons'][0]['episodes'].append( {'number': ep}) logger.debug( "doMarkWatched(): '%s - Season %d' has %d episode(s) that are going to be marked as watched." % (data['id'], data['season'], len(summaryInfo['shows'][0]['seasons'][0]['episodes']))) if len(summaryInfo['shows'][0]['seasons'][0]['episodes']) > 0: logger.debug("doMarkWatched(): %s" % str(summaryInfo)) result = globals.traktapi.addToHistory(summaryInfo) if result: kodiUtilities.notification( kodiUtilities.getString(32113), kodiUtilities.getString(32115) % (result['added']['episodes'], s)) else: kodiUtilities.notification(kodiUtilities.getString(32114), s) elif utilities.isShow(media_type): summaryInfo = { 'shows': [{ 'ids': utilities.parseIdToTraktIds(data['id'], media_type)[0], 'seasons': [] }] } if summaryInfo: s = utilities.getFormattedItemName(media_type, data) logger.debug('data: %s' % data) for season in data['seasons']: episodeJson = [] for episode in data['seasons'][season]: episodeJson.append({'number': episode}) summaryInfo['shows'][0]['seasons'].append({ 'number': season, 'episodes': episodeJson }) if len(summaryInfo['shows'][0]['seasons'][0]['episodes']) > 0: logger.debug("doMarkWatched(): %s" % str(summaryInfo)) result = globals.traktapi.addToHistory(summaryInfo) if result: kodiUtilities.notification( kodiUtilities.getString(32113), kodiUtilities.getString(32115) % (result['added']['episodes'], s)) else: kodiUtilities.notification( kodiUtilities.getString(32114), s) def doSync(self, manual=False, silent=False, library="all"): self.syncThread = syncThread(manual, silent, library) self.syncThread.start() def callback(self, data): logger.debug('Callback received - Nextup skipped to the next episode') self.scrobbler.playbackEnded()
def run(self): #while xbmc is running scrobbler = Scrobbler() scrobbler.start() while (not (self.abortRequested or xbmc.abortRequested)): time.sleep(1) try: tn = telnetlib.Telnet('localhost', 9090, 10) except IOError as (errno, strerror): #connection failed, try again soon Debug("[Notification Service] Telnet too soon? (" + str(errno) + ") " + strerror) time.sleep(1) continue Debug("[Notification Service] Waiting~") bCount = 0 while (not (self.abortRequested or xbmc.abortRequested)): try: if bCount == 0: notification = "" inString = False [index, match, raw] = tn.expect( ["(\\\\)|(\\\")|[{\"}]"], 0.2) #note, pre-compiled regex might be faster here notification += raw if index == -1: # Timeout continue if index == 0: # Found escaped quote match = match.group(0) if match == "\"": inString = not inString continue if match == "{": bCount += 1 if match == "}": bCount -= 1 if bCount > 0: continue if bCount < 0: bCount = 0 except EOFError: break #go out to the other loop to restart the connection Debug("[Notification Service] message: " + str(notification)) # Parse recieved notification data = json.loads(notification) # Forward notification to functions if 'method' in data and 'params' in data and 'sender' in data[ 'params'] and data['params']['sender'] == 'xbmc': if data['method'] == 'Player.OnStop': scrobbler.playbackEnded() elif data['method'] == 'Player.OnPlay': if 'data' in data['params'] and 'item' in data[ 'params']['data'] and 'id' in data['params'][ 'data']['item'] and 'type' in data[ 'params']['data']['item']: scrobbler.playbackStarted(data['params']['data']) elif data['method'] == 'Player.OnPause': scrobbler.playbackPaused() elif data['method'] == 'VideoLibrary.OnUpdate': if 'data' in data['params'] and 'playcount' in data[ 'params']['data']: instantSyncPlayCount(data) elif data['method'] == 'System.OnQuit': self.abortRequested = True
def run(self): #while xbmc is running scrobbler = Scrobbler() scrobbler.start() while (not (self.abortRequested or xbmc.abortRequested)): time.sleep(1) try: tn = telnetlib.Telnet('localhost', 9090, 10) except IOError as (errno, strerror): #connection failed, try again soon Debug("[Notification Service] Telnet too soon? ("+str(errno)+") "+strerror) time.sleep(1) continue Debug("[Notification Service] Waiting~"); bCount = 0 while (not (self.abortRequested or xbmc.abortRequested)): try: if bCount == 0: notification = "" inString = False [index, match, raw] = tn.expect(["(\\\\)|(\\\")|[{\"}]"], 0.2) #note, pre-compiled regex might be faster here notification += raw if index == -1: # Timeout continue if index == 0: # Found escaped quote match = match.group(0) if match == "\"": inString = not inString continue if match == "{": bCount += 1 if match == "}": bCount -= 1 if bCount > 0: continue if bCount < 0: bCount = 0 except EOFError: break #go out to the other loop to restart the connection Debug("[Notification Service] message: " + str(notification)) # Parse recieved notification data = json.loads(notification) # Forward notification to functions if 'method' in data and 'params' in data and 'sender' in data['params'] and data['params']['sender'] == 'xbmc': if data['method'] == 'Player.OnStop': Debug("pb ended, %s" % getSync_after_x()) scrobbler.playbackEnded(data=data) # this is using syncIncreasePlayCount already elif data['method'] == 'Player.OnPlay': if 'data' in data['params'] and 'item' in data['params']['data'] and 'id' in data['params']['data']['item'] and 'type' in data['params']['data']['item']: #fixme: look here for current position? scrobbler.playbackStarted(data['params']['data']) elif data['method'] == 'Player.OnPause': scrobbler.playbackPaused() elif data['method'] == 'VideoLibrary.OnUpdate': Debug("OnUpdate %s" % data) if 'data' in data['params'] and 'playcount' in data['params']['data']: noBugging = getNoBugging() # 'playcount' in data indicates that playcount has changed. so we received a seen status on the item if getSync_after_x() and data['params']['data']["playcount"] >= 1: # we've played a file and consider it seen syncIncreasePlayCount() Debug("syncing, playcount: %s" % data['params']['data']["playcount"]) syncAfterX(daemon=noBugging) onlyOnUnwatchMark = getInstantOnlyOnUnwatchMark() Debug("instantUpdateOnWatchMark: %s, %s" % (getInstantUpdateOnWatchMark(), onlyOnUnwatchMark)) if (getInstantUpdateOnWatchMark() and not onlyOnUnwatchMark) or (data['params']['data']["playcount"] == 0 and onlyOnUnwatchMark): instantSyncPlayCount(data) elif data['method'] == 'System.OnQuit': self.abortRequested = True