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
def main(): register_exception_handler() assert get_access_token() scrobble_queue = Queue() scrobbler = Scrobbler(scrobble_queue) scrobbler.start() for Mon in get_monitors(): mon = Mon(scrobble_queue) mon.start()
class NotificationService: _scrobbler = None def __init__(self): self.run() def _dispatch(self, data): Debug("[Notification] Dispatch: %s" % data) xbmc.sleep(500) action = data["action"] if action == "started": p = {"item": {"type": data["type"], "id": data["id"]}} self._scrobbler.playbackStarted(p) elif action == "ended" or action == "stopped": self._scrobbler.playbackEnded() elif action == "paused": self._scrobbler.playbackPaused() elif action == "resumed": self._scrobbler.playbackResumed() elif action == "databaseUpdated": if do_sync('movies'): movies = SyncMovies(show_progress=False) movies.Run() if do_sync('episodes'): episodes = SyncEpisodes(show_progress=False) episodes.Run() elif action == "scanStarted": Debug("[Notification] Dispatch: scanStarted") else: Debug("[Notification] '%s' unknown dispatch action!" % action) def run(self): Debug("[Notification] Starting") # setup event driven classes self.Player = traktPlayer(action = self._dispatch) self.Monitor = traktMonitor(action = self._dispatch) # initalize scrobbler class self._scrobbler = Scrobbler() self._scrobbler.start() # start loop for events while (not xbmc.abortRequested): xbmc.sleep(500) # we aborted if xbmc.abortRequested: Debug("[Notification] abortRequested received, shutting down.") # join scrobbler, to wait for termination Debug("[Notification] Joining scrobbler thread to wait for exit.") self._scrobbler.join()
class NotificationService(threading.Thread): """ Receives XBMC notifications and passes them off as needed """ TELNET_ADDRESS = 'localhost' TELNET_PORT = 9090 _abortRequested = False _scrobbler = None _notificationBuffer = "" def _forward(self, notification): """ Fowards the notification recieved to a function on the scrobbler """ if not ('method' in notification and 'params' in notification and 'sender' in notification['params'] and notification['params']['sender'] == 'xbmc'): return if notification['method'] == 'Player.OnStop': self._scrobbler.playbackEnded() elif notification['method'] == 'Player.OnPlay': if 'data' in notification['params'] and 'item' in notification['params']['data'] and 'type' in notification['params']['data']['item']: self._scrobbler.playbackStarted(notification['params']['data']) elif notification['method'] == 'Player.OnPause': self._scrobbler.playbackPaused() elif notification['method'] == 'VideoLibrary.OnScanFinished': if do_sync('movies'): movies = SyncMovies(show_progress=False) movies.Run() if do_sync('episodes'): episodes = SyncEpisodes(show_progress=False) episodes.Run() elif notification['method'] == 'System.OnQuit': self._abortRequested = True def _readNotification(self, telnet): """ Read a notification from the telnet connection, blocks until the data is available, or else raises an EOFError if the connection is lost """ while True: try: addbuffer = telnet.read_some() except socket.timeout: continue if addbuffer == "": raise EOFError self._notificationBuffer += addbuffer try: data, offset = json.JSONDecoder().raw_decode(self._notificationBuffer) self._notificationBuffer = self._notificationBuffer[offset:] except ValueError: continue return data def run(self): #while xbmc is running self._scrobbler = Scrobbler() self._scrobbler.start() while not (self._abortRequested or xbmc.abortRequested): try: #try to connect, catch errors and retry every 5 seconds telnet = telnetlib.Telnet(self.TELNET_ADDRESS, self.TELNET_PORT) #if connection succeeds while not (self._abortRequested or xbmc.abortRequested): try: #read notification data data = self._readNotification(telnet) Debug("[Notification Service] message: " + str(data)) self._forward(data) except EOFError: #if we end up here, it means the connection was lost or reset, # so we empty out the buffer, and exit this loop, which retries # the connection in the outer loop self._notificationBuffer = "" break except: time.sleep(5) continue telnet.close() self._scrobbler.abortRequested = True Debug("Notification service stopping")
class NotificationService(threading.Thread): """ Receives XBMC notifications and passes them off as needed """ TELNET_ADDRESS = 'localhost' TELNET_PORT = 9090 abort_requested = False _scrobbler = None _notification_buffer = "" def _forward(self, notification): """ Fowards the notification recieved to a function on the scrobbler """ if not ('method' in notification and 'params' in notification and 'sender' in notification['params'] and notification['params']['sender'] == 'xbmc'): return if notification['method'] == 'Player.OnStop': self._scrobbler.playback_ended() elif notification['method'] == 'Player.OnPlay': if 'data' in notification['params'] and 'item' in notification['params']['data'] and 'id' in notification['params']['data']['item'] and 'type' in notification['params']['data']['item']: self._scrobbler.playback_started(notification['params']['data']) elif notification['method'] == 'Player.OnPause': self._scrobbler.playback_paused() elif notification['method'] == 'System.OnQuit': self.abort_requested = True def _read_notification(self, telnet): """ Read a notification from the telnet connection, blocks until the data is available, or else raises an EOFError if the connection is lost """ while True: try: addbuffer = telnet.read_some() except socket.timeout: continue if addbuffer == "": raise EOFError self._notification_buffer += addbuffer try: data, offset = json.JSONDecoder().raw_decode(self._notification_buffer) self._notification_buffer = self._notification_buffer[offset:] except ValueError: continue return data def run(self): self._scrobbler = Scrobbler() self._scrobbler.start() telnet = telnetlib.Telnet(self.TELNET_ADDRESS, self.TELNET_PORT) while not (self.abort_requested or xbmc.abortRequested): try: data = self._read_notification(telnet) except EOFError: telnet = telnetlib.Telnet(self.TELNET_ADDRESS, self.TELNET_PORT) self._notification_buffer = "" continue Debug("[Notification Service] message: " + str(data)) self._forward(data) telnet.close() self._scrobbler.abortRequested = True Debug("Notification service stopping")
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
class NotificationService(threading.Thread): """ Receives XBMC notifications and passes them off as needed """ TELNET_ADDRESS = 'localhost' TELNET_PORT = 9090 _abortRequested = False _scrobbler = None _notificationBuffer = "" def _forward(self, notification): """ Fowards the notification recieved to a function on the scrobbler """ if not ('method' in notification and 'params' in notification and 'sender' in notification['params'] and notification['params']['sender'] == 'xbmc'): return if notification['method'] == 'Player.OnStop': self._scrobbler.playbackEnded() elif notification['method'] == 'Player.OnPlay': if 'data' in notification['params'] and 'item' in notification[ 'params']['data'] and 'type' in notification['params'][ 'data']['item']: self._scrobbler.playbackStarted(notification['params']['data']) elif notification['method'] == 'Player.OnPause': self._scrobbler.playbackPaused() elif notification['method'] == 'VideoLibrary.OnScanFinished': if do_sync('movies'): movies = SyncMovies(show_progress=False) movies.Run() if do_sync('episodes'): episodes = SyncEpisodes(show_progress=False) episodes.Run() elif notification['method'] == 'System.OnQuit': self._abortRequested = True def _readNotification(self, telnet): """ Read a notification from the telnet connection, blocks until the data is available, or else raises an EOFError if the connection is lost """ while True: try: addbuffer = telnet.read_some() except socket.timeout: continue if addbuffer == "": raise EOFError self._notificationBuffer += addbuffer try: data, offset = json.JSONDecoder().raw_decode( self._notificationBuffer) self._notificationBuffer = self._notificationBuffer[offset:] except ValueError: continue return data def run(self): #while xbmc is running self._scrobbler = Scrobbler() self._scrobbler.start() while not (self._abortRequested or xbmc.abortRequested): try: #try to connect, catch errors and retry every 5 seconds telnet = telnetlib.Telnet(self.TELNET_ADDRESS, self.TELNET_PORT) #if connection succeeds while not (self._abortRequested or xbmc.abortRequested): try: #read notification data data = self._readNotification(telnet) Debug("[Notification Service] message: " + str(data)) self._forward(data) except EOFError: #if we end up here, it means the connection was lost or reset, # so we empty out the buffer, and exit this loop, which retries # the connection in the outer loop self._notificationBuffer = "" break except: time.sleep(5) continue telnet.close() self._scrobbler.abortRequested = True Debug("Notification service stopping")