def __init__(self, xmlFile, resourcePath, forceFallback=False, media_type=None, media=None, rating_type=None, rerate=False): self.media_type = media_type self.media = media self.rating_type = rating_type self.rating = None self.rerate = rerate self.default_simple = utils.getSettingAsInt('rating_default_simple') self.default_advanced = utils.getSettingAsInt('rating_default_advanced')
def run(self): startup_delay = utilities.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) # start loop for events while not self.Monitor.abortRequested(): if not utilities.getSetting('authorization'): last_reminder = utilities.getSettingAsInt('last_reminder') now = int(time.time()) if last_reminder >= 0 and last_reminder < now - (24 * 60 * 60): gui_utils.get_pin() 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 run(self): startup_delay = utilities.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) # start loop for events while not self.Monitor.abortRequested(): if not utilities.getSetting('authorization'): last_reminder = utilities.getSettingAsInt('last_reminder') now = int(time.time()) if last_reminder >= 0 and last_reminder < now - (24 * 60 * 60): gui_utils.get_pin() 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 getAccountSettings(self, force=False): _interval = (60 * 60 * 24 * 7) - (60 * 60) # one week less one hour _next = getSettingAsInt('trakt_settings_last') + _interval stale = force if force: Debug("[traktAPI] Forcing a reload of settings from trakt.tv.") if not stale and time.time() >= _next: Debug("[traktAPI] trakt.tv account settings are stale, reloading.") stale = True if stale: if self.testAccount(): Debug("[traktAPI] Getting account settings for '%s'." % self.__username) url = "%s/account/settings/%s" % (self.__baseURL, self.__apikey) Debug("[traktAPI] getAccountSettings(url: %s)" % url) response = self.traktRequest('POST', url, hideResponse=True) if response and 'status' in response: if response['status'] == 'success': del response['status'] setSetting('trakt_settings', json.dumps(response)) setSetting('trakt_settings_last', int(time.time())) self.settings = response else: Debug("[traktAPI] Loaded cached account settings for '%s'." % self.__username) s = getSetting('trakt_settings') self.settings = json.loads(s)
def getAccountSettings(self, force): _interval = (60 * 60 * 24 * 7) - (60 * 60) # one week less one hour _next = getSettingAsInt('xbmcfilm_settings_last') + _interval stale = force if force: Debug("[XbmcFilm] Forcing a reload of settings from xbmcfilm.tv.") if not stale and time.time() >= _next: Debug("[XbmcFilm] xbmcfilm.tv account settings are stale, reloading.") stale = True if stale: if self.testAccount(): Debug("[XbmcFilm] Getting account settings for '%s'." % self.__username) url = "%s/account/settings/%s" % (self.__baseURL, self.__apikey) Debug("[XbmcFilm] getAccountSettings(url: %s)" % url) response = self.xbmcfilmRequest('POST', url, hideResponse=True) if response and 'status' in response: if response['status'] == 'success': del response['status'] setSetting('xbmcfilm_settings', json.dumps(response)) setSetting('xbmcfilm_settings_last', int(time.time())) self.settings = response else: Debug("[XbmcFilm] Loaded cached account settings for '%s'." % self.__username) s = getSetting('xbmcfilm_settings') self.settings = json.loads(s)
def run(self): startup_delay = utilities.getSettingAsInt('startup_delay') if startup_delay: utilities.Debug("Delaying startup by %d seconds." % startup_delay) xbmc.sleep(startup_delay * 1000) utilities.Debug("Service thread starting.") # 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) # start loop for events while (not xbmc.abortRequested): while not self.dispatchQueue.empty() and (not xbmc.abortRequested): data = self.dispatchQueue.get() utilities.Debug("Queued dispatch: %s" % data) self._dispatch(data) # check if we were tasked to do a manual sync if utilities.getPropertyAsBool('traktManualSync'): if not self.syncThread.isAlive(): utilities.Debug("Performing a manual sync.") self.doSync(manual=True) else: utilities.Debug("There already is a sync in progress.") utilities.clearProperty('traktManualSync') if xbmc.Player().isPlayingVideo(): self.scrobbler.update() xbmc.sleep(500) # we are shutting down utilities.Debug("Beginning shut down.") # check if watcher is set and active, if so, cancel it. if self.watcher: if self.watcher.isAlive(): self.watcher.cancel() # 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 run(self): startup_delay = utilities.getSettingAsInt('startup_delay') if startup_delay: utilities.Debug("Delaying startup by %d seconds." % startup_delay) xbmc.sleep(startup_delay * 1000) utilities.Debug("Service thread starting.") # 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) # init tagging class self.tagger = Tagger(globals.traktapi) # purge queue self.dispatchQueue.purge() # start loop for events while (not xbmc.abortRequested): while len(self.dispatchQueue) and (not xbmc.abortRequested): data = self.dispatchQueue.get() utilities.Debug("Queued dispatch: %s" % data) self._dispatch(data) if xbmc.Player().isPlayingVideo(): self.scrobbler.update() xbmc.sleep(500) # we are shutting down utilities.Debug("Beginning shut down.") # check if watcher is set and active, if so, cancel it. if self.watcher: if self.watcher.isAlive(): self.watcher.cancel() # delete player/monitor del self.Player del self.Monitor # check update tags thread. if self.updateTagsThread and self.updateTagsThread.isAlive(): self.updateTagsThread.join() # check if sync thread is running, if so, join it. if self.syncThread.isAlive(): self.syncThread.join()
def run(self): startup_delay = utilities.getSettingAsInt('startup_delay') if startup_delay: utilities.Debug("Delaying startup by %d seconds." % startup_delay) xbmc.sleep(startup_delay * 1000) utilities.Debug("Service thread starting.") # 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) # init tagging class self.tagger = Tagger(globals.traktapi) # purge queue self.dispatchQueue.purge() # start loop for events while (not xbmc.abortRequested): while len(self.dispatchQueue) and (not xbmc.abortRequested): data = self.dispatchQueue.get() utilities.Debug("Queued dispatch: %s" % data) self._dispatch(data) if xbmc.Player().isPlayingVideo(): self.scrobbler.update() xbmc.sleep(500) # we are shutting down utilities.Debug("Beginning shut down.") # check if watcher is set and active, if so, cancel it. if self.watcher: if self.watcher.isAlive(): self.watcher.cancel() # delete player/monitor del self.Player del self.Monitor # check update tags thread. if self.updateTagsThread and self.updateTagsThread.isAlive(): self.updateTagsThread.join() # check if sync thread is running, if so, join it. if self.syncThread.isAlive(): self.syncThread.join()
def getArguments(): data = None default_actions = {0: "sync", 1: "managelists"} default = utils.getSettingAsInt("default_action") if len(sys.argv) == 1: data = {"action": default_actions[default]} else: data = {} for item in sys.argv: values = item.split("=") if len(values) == 2: data[values[0].lower()] = values[1] data["action"] = data["action"].lower() return data
def getArguments(): data = None default_actions = {0: "sync", 1: "managelists"} default = utils.getSettingAsInt('default_action') if len(sys.argv) == 1: data = {'action': default_actions[default]} else: data = {} for item in sys.argv: values = item.split("=") if len(values) == 2: data[values[0].lower()] = values[1] data['action'] = data['action'].lower() return data
def __init__(self): Debug("[traktAPI] Initializing.") # Get user login data self.__username = getSetting('username') self.__password = getSetting('password') self.__token = getSetting('token') # Configure logging.basicConfig(level=logging.INFO) Trakt.configuration.defaults.http( retry=True, max_retries=getSettingAsInt('retries')) Trakt.configuration.defaults.client(id=self.__apikey) if not self.__token: self.getToken()
def run(self): startup_delay = utilities.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) # start loop for events while not xbmc.abortRequested: while len(self.dispatchQueue) and (not xbmc.abortRequested): data = self.dispatchQueue.get() logger.debug("Queued dispatch: %s" % data) self._dispatch(data) if xbmc.Player().isPlayingVideo(): self.scrobbler.transitionCheck() xbmc.sleep(500) # 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 onPlayBackStarted(self): xbmc.sleep(1000) self.type = None self.id = None # take the user start scrobble offset into account scrobbleStartOffset = utilities.getSettingAsInt('scrobble_start_offset')*60 if scrobbleStartOffset > 0: waitFor = 10 waitedFor = 0 # check each 10 seconds if we can abort or proceed while not xbmc.abortRequested and scrobbleStartOffset > waitedFor: waitedFor += waitFor time.sleep(waitFor) if not self.isPlayingVideo(): logger.debug('[traktPlayer] Playback stopped before reaching the scrobble offset') return # only do anything if we're playing a video if self.isPlayingVideo(): # get item data from json rpc result = utilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'Player.GetItem', 'params': {'playerid': 1}, 'id': 1}) if result: logger.debug("[traktPlayer] onPlayBackStarted() - %s" % result) # check for exclusion _filename = None try: _filename = self.getPlayingFile() except: logger.debug("[traktPlayer] onPlayBackStarted() - Exception trying to get playing filename, player suddenly stopped.") return if utilities.checkExclusion(_filename): logger.debug("[traktPlayer] onPlayBackStarted() - '%s' is in exclusion settings, ignoring." % _filename) return self.type = result['item']['type'] data = {'action': 'started'} # check type of item if 'id' not in result['item']: # do a deeper check to see if we have enough data to perform scrobbles logger.debug("[traktPlayer] onPlayBackStarted() - Started playing a non-library file, checking available data.") season = xbmc.getInfoLabel('VideoPlayer.Season') episode = xbmc.getInfoLabel('VideoPlayer.Episode') showtitle = xbmc.getInfoLabel('VideoPlayer.TVShowTitle') year = xbmc.getInfoLabel('VideoPlayer.Year') video_ids = xbmcgui.Window(10000).getProperty('script.trakt.ids') if video_ids: data['video_ids'] = json.loads(video_ids) logger.debug("[traktPlayer] info - ids: %s, showtitle: %s, Year: %s, Season: %s, Episode: %s" % (video_ids, showtitle, year, season, episode)) if season and episode and (showtitle or video_ids): # we have season, episode and either a show title or video_ids, can scrobble this as an episode self.type = 'episode' data['type'] = 'episode' data['season'] = int(season) data['episode'] = int(episode) data['showtitle'] = showtitle data['title'] = xbmc.getInfoLabel('VideoPlayer.Title') if year.isdigit(): data['year'] = int(year) logger.debug("[traktPlayer] onPlayBackStarted() - Playing a non-library 'episode' - %s - S%02dE%02d - %s." % (data['showtitle'], data['season'], data['episode'], data['title'])) elif (year or video_ids) and not season and not showtitle: # we have a year or video_id and no season/showtitle info, enough for a movie self.type = 'movie' data['type'] = 'movie' if year.isdigit(): data['year'] = int(year) data['title'] = xbmc.getInfoLabel('VideoPlayer.Title') logger.debug("[traktPlayer] onPlayBackStarted() - Playing a non-library 'movie' - %s (%s)." % (data['title'], data.get('year', 'NaN'))) elif showtitle: title, season, episode = utilities.regex_tvshow(False, showtitle) data['type'] = 'episode' data['season'] = int(season) data['episode'] = int(episode) data['showtitle'] = title data['title'] = title logger.debug("[traktPlayer] onPlayBackStarted() - Title: %s, showtitle: %s, season: %d, episode: %d" % (title, showtitle, season, episode)) else: logger.debug("[traktPlayer] onPlayBackStarted() - Non-library file, not enough data for scrobbling, skipping.") return elif self.type == 'episode' or self.type == 'movie': # get library id self.id = result['item']['id'] data['id'] = self.id data['type'] = self.type if self.type == 'episode': logger.debug("[traktPlayer] onPlayBackStarted() - Doing multi-part episode check.") result = utilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodeDetails', 'params': {'episodeid': self.id, 'properties': ['tvshowid', 'season', 'episode', 'file']}, 'id': 1}) if result: logger.debug("[traktPlayer] onPlayBackStarted() - %s" % result) tvshowid = int(result['episodedetails']['tvshowid']) season = int(result['episodedetails']['season']) currentfile = result['episodedetails']['file'] result = utilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': {'tvshowid': tvshowid, 'season': season, 'properties': ['episode', 'file'], 'sort': {'method': 'episode'}}, 'id': 1}) if result: logger.debug("[traktPlayer] onPlayBackStarted() - %s" % result) # make sure episodes array exists in results if 'episodes' in result: multi = [] for i in range(result['limits']['start'], result['limits']['total']): if currentfile == result['episodes'][i]['file']: multi.append(result['episodes'][i]['episodeid']) if len(multi) > 1: data['multi_episode_data'] = multi data['multi_episode_count'] = len(multi) logger.debug("[traktPlayer] onPlayBackStarted() - This episode is part of a multi-part episode.") else: logger.debug("[traktPlayer] onPlayBackStarted() - This is a single episode.") else: logger.debug("[traktPlayer] onPlayBackStarted() - Video type '%s' unrecognized, skipping." % self.type) return pl = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) plSize = len(pl) if plSize > 1: pos = pl.getposition() if not self.plIndex is None: logger.debug("[traktPlayer] onPlayBackStarted() - User manually skipped to next (or previous) video, forcing playback ended event.") self.onPlayBackEnded() self.plIndex = pos logger.debug("[traktPlayer] onPlayBackStarted() - Playlist contains %d item(s), and is currently on item %d" % (plSize, (pos + 1))) self._playing = True # send dispatch self.action(data)
def onPlayBackStarted(self): xbmc.sleep(1000) self.type = None self.id = None # take the user start scrobble offset into account scrobbleStartOffset = utilities.getSettingAsInt( 'scrobble_start_offset') * 60 if scrobbleStartOffset > 0: waitFor = 10 waitedFor = 0 # check each 10 seconds if we can abort or proceed while not xbmc.abortRequested and scrobbleStartOffset > waitedFor: waitedFor += waitFor time.sleep(waitFor) if not self.isPlayingVideo(): logger.debug( '[traktPlayer] Playback stopped before reaching the scrobble offset' ) return # only do anything if we're playing a video if self.isPlayingVideo(): # get item data from json rpc result = utilities.kodiJsonRequest({ 'jsonrpc': '2.0', 'method': 'Player.GetItem', 'params': { 'playerid': 1 }, 'id': 1 }) if result: logger.debug("[traktPlayer] onPlayBackStarted() - %s" % result) # check for exclusion _filename = None try: _filename = self.getPlayingFile() except: logger.debug( "[traktPlayer] onPlayBackStarted() - Exception trying to get playing filename, player suddenly stopped." ) return if utilities.checkExclusion(_filename): logger.debug( "[traktPlayer] onPlayBackStarted() - '%s' is in exclusion settings, ignoring." % _filename) return self.type = result['item']['type'] data = {'action': 'started'} # check type of item if 'id' not in result['item']: # do a deeper check to see if we have enough data to perform scrobbles logger.debug( "[traktPlayer] onPlayBackStarted() - Started playing a non-library file, checking available data." ) season = xbmc.getInfoLabel('VideoPlayer.Season') episode = xbmc.getInfoLabel('VideoPlayer.Episode') showtitle = xbmc.getInfoLabel('VideoPlayer.TVShowTitle') year = xbmc.getInfoLabel('VideoPlayer.Year') video_ids = xbmcgui.Window(10000).getProperty( 'script.trakt.ids') if video_ids: data['video_ids'] = json.loads(video_ids) logger.debug( "[traktPlayer] info - ids: %s, showtitle: %s, Year: %s, Season: %s, Episode: %s" % (video_ids, showtitle, year, season, episode)) if season and episode and (showtitle or video_ids): # we have season, episode and either a show title or video_ids, can scrobble this as an episode self.type = 'episode' data['type'] = 'episode' data['season'] = int(season) data['episode'] = int(episode) data['showtitle'] = showtitle data['title'] = xbmc.getInfoLabel('VideoPlayer.Title') if year.isdigit(): data['year'] = int(year) logger.debug( "[traktPlayer] onPlayBackStarted() - Playing a non-library 'episode' - %s - S%02dE%02d - %s." % (data['showtitle'], data['season'], data['episode'], data['title'])) elif (year or video_ids) and not season and not showtitle: # we have a year or video_id and no season/showtitle info, enough for a movie self.type = 'movie' data['type'] = 'movie' if year.isdigit(): data['year'] = int(year) data['title'] = xbmc.getInfoLabel('VideoPlayer.Title') logger.debug( "[traktPlayer] onPlayBackStarted() - Playing a non-library 'movie' - %s (%s)." % (data['title'], data.get('year', 'NaN'))) elif showtitle: title, season, episode = utilities.regex_tvshow( False, showtitle) data['type'] = 'episode' data['season'] = int(season) data['episode'] = int(episode) data['showtitle'] = title data['title'] = title logger.debug( "[traktPlayer] onPlayBackStarted() - Title: %s, showtitle: %s, season: %d, episode: %d" % (title, showtitle, season, episode)) else: logger.debug( "[traktPlayer] onPlayBackStarted() - Non-library file, not enough data for scrobbling, skipping." ) return elif self.type == 'episode' or self.type == 'movie': # get library id self.id = result['item']['id'] data['id'] = self.id data['type'] = self.type if self.type == 'episode': logger.debug( "[traktPlayer] onPlayBackStarted() - Doing multi-part episode check." ) result = utilities.kodiJsonRequest({ 'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodeDetails', 'params': { 'episodeid': self.id, 'properties': ['tvshowid', 'season', 'episode', 'file'] }, 'id': 1 }) if result: logger.debug( "[traktPlayer] onPlayBackStarted() - %s" % result) tvshowid = int( result['episodedetails']['tvshowid']) season = int(result['episodedetails']['season']) currentfile = result['episodedetails']['file'] result = utilities.kodiJsonRequest({ 'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': { 'tvshowid': tvshowid, 'season': season, 'properties': ['episode', 'file'], 'sort': { 'method': 'episode' } }, 'id': 1 }) if result: logger.debug( "[traktPlayer] onPlayBackStarted() - %s" % result) # make sure episodes array exists in results if 'episodes' in result: multi = [] for i in range(result['limits']['start'], result['limits']['total']): if currentfile == result['episodes'][ i]['file']: multi.append(result['episodes'][i] ['episodeid']) if len(multi) > 1: data['multi_episode_data'] = multi data['multi_episode_count'] = len( multi) logger.debug( "[traktPlayer] onPlayBackStarted() - This episode is part of a multi-part episode." ) else: logger.debug( "[traktPlayer] onPlayBackStarted() - This is a single episode." ) else: logger.debug( "[traktPlayer] onPlayBackStarted() - Video type '%s' unrecognized, skipping." % self.type) return pl = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) plSize = len(pl) if plSize > 1: pos = pl.getposition() if not self.plIndex is None: logger.debug( "[traktPlayer] onPlayBackStarted() - User manually skipped to next (or previous) video, forcing playback ended event." ) self.onPlayBackEnded() self.plIndex = pos logger.debug( "[traktPlayer] onPlayBackStarted() - Playlist contains %d item(s), and is currently on item %d" % (plSize, (pos + 1))) self._playing = True # send dispatch self.action(data)
def traktRequest(self, method, url, args=None, returnStatus=False, returnOnFailure=False, silent=True, passVersions=False, hideResponse=False): raw = None data = None jdata = {} retries = getSettingAsInt('retries') if args is None: args = {} if not (method == 'POST' or method == 'GET'): Debug("[traktAPI] traktRequest(): Unknown method '%s'." % method) return None if method == 'POST': # debug log before username and sha1hash are injected Debug("[traktAPI] traktRequest(): Request data: '%s'." % str(json.dumps(args))) # inject username/pass into json data args['username'] = self.__username args['password'] = self.__password # check if plugin version needs to be passed if passVersions: args['plugin_version'] = __addonversion__ args['media_center_version'] = xbmc.getInfoLabel( 'system.buildversion') args['media_center_date'] = xbmc.getInfoLabel( 'system.builddate') # convert to json data jdata = json.dumps(args) Debug( "[traktAPI] traktRequest(): Starting retry loop, maximum %i retries." % retries) # start retry loop for i in range(retries): Debug("[traktAPI] traktRequest(): (%i) Request URL '%s'" % (i, url)) # check if we are closing if xbmc.abortRequested: Debug("[traktAPI] traktRequest(): (%i) xbmc.abortRequested" % i) break try: # get data from trakt.tv raw = self.__getData(url, jdata) 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) notification('trakt', getString(1110)) return elif isinstance(e, traktNetworkError): Debug("[traktAPI] traktRequest(): (%i) Network error: %s" % (i, e.value)) if e.timeout: notification('trakt', getString(1108) + " (timeout)") # can't connect to trakt xbmc.sleep(5000) elif isinstance(e, traktUnknownError): Debug( "[traktAPI] traktRequest(): (%i) Other problem (%s)" % (i, e.value)) else: pass xbmc.sleep(1000) continue # check if we are closing if xbmc.abortRequested: Debug("[traktAPI] traktRequest(): (%i) xbmc.abortRequested" % i) break # check that returned data is not empty if not raw: Debug("[traktAPI] traktRequest(): (%i) JSON Response empty" % i) xbmc.sleep(1000) continue try: # get json formatted data data = json.loads(raw) if hideResponse: Debug( "[traktAPI] traktRequest(): (%i) JSON response recieved, response not logged" % i) else: 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)) if not silent: notification('trakt', getString(1109) + ": Bad response from trakt") # Error # check for the status variable in JSON data if data and 'status' in data: if data['status'] == 'success': break elif returnOnFailure and data['status'] == 'failure': Debug( "[traktAPI] traktRequest(): Return on error set, breaking retry." ) break elif 'error' in data and data['status'] == 'failure': Debug( "[traktAPI] traktRequest(): (%i) JSON Error '%s' -> '%s'" % (i, data['status'], data['error'])) xbmc.sleep(1000) continue else: pass # check to see if we have data, an empty array is still valid data, so check for None only if not data is None: Debug( "[traktAPI] traktRequest(): Have JSON data, breaking retry." ) break xbmc.sleep(500)
def traktRequest(self, method, url, args=None, returnStatus=False, returnOnFailure=False, silent=True, hideResponse=False): data = None retries = getSettingAsInt('retries') if args is None: args = {} if not (method == 'POST' or method == 'GET' or method == 'PUT' or method == 'DELETE'): Debug("[traktAPI] traktRequest(): Unknown method '%s'." % method) return None # debug log before username and token are injected Debug("[traktAPI] traktRequest(): Request data: '%s'." % str(json.dumps(args))) # convert to json data jdata = json.dumps(args) Debug( "[traktAPI] traktRequest(): Starting retry loop, maximum %i retries." % retries) # start retry loop for i in range(retries): Debug("[traktAPI] traktRequest(): (%i) Request URL '%s'" % (i, url)) # check if we are closing if xbmc.abortRequested: Debug("[traktAPI] traktRequest(): (%i) xbmc.abortRequested" % i) break try: # get data from trakt.tv data = None try: Debug("[traktAPI] __getData(): urllib2.Request(%s)" % url) headers = { 'trakt-user-login': self.__username, 'trakt-user-token': self.__token, 'Content-type': 'application/json', 'trakt-api-key': self.__apikey, 'trakt-api-version': '2' } if jdata is None: req = Request(url, headers) else: req = Request(url, jdata, headers) req.get_method = lambda: method Debug("[traktAPI] __getData(): urllib2.urlopen()") t1 = time.time() response = urlopen(req, timeout=self.__timeout) t2 = time.time() Debug("[traktAPI] __getData(): response.read()") data = response.read() Debug("[traktAPI] __getData(): Response Code: %i" % response.getcode()) Debug("[traktAPI] __getData(): Response Time: %0.2f ms" % ((t2 - t1) * 1000)) Debug("[traktAPI] __getData(): Response Headers: %s" % str(response.info().dict)) except BadStatusLine as e: raise traktUnknownError( "BadStatusLine: '%s' from URL: '%s'" % (e.line, url)) except IOError as e: if hasattr(e, 'code'): # error 401 or 503, possibly others # read the error document, strip newlines, this will make an html page 1 line error_data = e.read().replace("\n", "").replace("\r", "") if e.code == 401: # authentication problem raise traktAuthProblem(error_data) elif e.code == 503: # server busy problem raise traktServerBusy(error_data) else: 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)) else: raise traktUnknownError(e.message) raw = data except traktError as 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)) notification('trakt', getString(1110)) return elif isinstance(e, traktNetworkError): Debug("[traktAPI] traktRequest(): (%i) Network error: %s" % (i, e.value)) if e.timeout: notification('trakt', getString(1108) + " (timeout)") # can't connect to trakt xbmc.sleep(5000) elif isinstance(e, traktUnknownError): Debug( "[traktAPI] traktRequest(): (%i) Other problem (%s)" % (i, e.value)) else: pass xbmc.sleep(1000) continue # check if we are closing if xbmc.abortRequested: Debug("[traktAPI] traktRequest(): (%i) xbmc.abortRequested" % i) break # check that returned data is not empty if not raw: Debug("[traktAPI] traktRequest(): (%i) JSON Response empty" % i) xbmc.sleep(1000) continue try: # get json formatted data data = json.loads(raw) if hideResponse: Debug( "[traktAPI] traktRequest(): (%i) JSON response recieved, response not logged" % i) else: 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)) if not silent: notification('trakt', getString(1109) + ": Bad response from trakt") # Error # check for the status variable in JSON data if data and 'status' in data: if data['status'] == 'success': break elif returnOnFailure and data['status'] == 'failure': Debug( "[traktAPI] traktRequest(): Return on error set, breaking retry." ) break elif 'error' in data and data['status'] == 'failure': Debug( "[traktAPI] traktRequest(): (%i) JSON Error '%s' -> '%s'" % (i, data['status'], data['error'])) xbmc.sleep(1000) continue else: pass # check to see if we have data, an empty array is still valid data, so check for None only if not data is None: Debug( "[traktAPI] traktRequest(): Have JSON data, breaking retry." ) break xbmc.sleep(500) # handle scenario where all retries fail if data is None: Debug( "[traktAPI] traktRequest(): JSON Request failed, data is still empty after retries." ) return None if 'status' in data: if data['status'] == 'failure': Debug("[traktAPI] traktRequest(): Error: %s" % str(data['error'])) if returnStatus or returnOnFailure: return data if not silent: notification('trakt', getString(1109) + ": " + str(data['error'])) # Error return None elif data['status'] == 'success': Debug( "[traktAPI] traktRequest(): JSON request was successful.") return data
def traktRequest(self, method, url, args=None, returnStatus=False, returnOnFailure=False, silent=True, passVersions=False, hideResponse=False): raw = None data = None jdata = {} retries = getSettingAsInt('retries') if args is None: args = {} if not (method == 'POST' or method == 'GET'): Debug("[traktAPI] traktRequest(): Unknown method '%s'." % method) return None if method == 'POST': # debug log before username and sha1hash are injected Debug("[traktAPI] traktRequest(): Request data: '%s'." % str(json.dumps(args))) # inject username/pass into json data args['username'] = self.__username args['password'] = self.__password # check if plugin version needs to be passed if passVersions: args['plugin_version'] = __addonversion__ args['media_center_version'] = xbmc.getInfoLabel('system.buildversion') args['media_center_date'] = xbmc.getInfoLabel('system.builddate') # convert to json data jdata = json.dumps(args) Debug("[traktAPI] traktRequest(): Starting retry loop, maximum %i retries." % retries) # start retry loop for i in range(retries): Debug("[traktAPI] traktRequest(): (%i) Request URL '%s'" % (i, url)) # check if we are closing if xbmc.abortRequested: Debug("[traktAPI] traktRequest(): (%i) xbmc.abortRequested" % i) break try: # get data from trakt.tv raw = self.__getData(url, jdata) except traktError, e: if isinstance(e, traktServerBusy): Debug("[traktAPI] traktRequest(): (%i) Server Busy (%s)" % (i, e.value)) elif isinstance(e, traktAuthProblem): Debug("[traktAPI] traktRequest(): (%i) Authentication Failure (%s)" % (i, e.value)) setSetting('account_valid', False) notification('trakt', getString(1110)) return elif isinstance(e, traktNetworkError): Debug("[traktAPI] traktRequest(): (%i) Network error: %s" % (i, e.value)) if e.timeout: notification('trakt', getString(1108) + " (timeout)") # can't connect to trakt xbmc.sleep(5000) elif isinstance(e, traktUnknownError): Debug("[traktAPI] traktRequest(): (%i) Other problem (%s)" % (i, e.value)) else: pass xbmc.sleep(1000) continue # check if we are closing if xbmc.abortRequested: Debug("[traktAPI] traktRequest(): (%i) xbmc.abortRequested" % i) break # check that returned data is not empty if not raw: Debug("[traktAPI] traktRequest(): (%i) JSON Response empty" % i) xbmc.sleep(1000) continue try: # get json formatted data data = json.loads(raw) if hideResponse: Debug("[traktAPI] traktRequest(): (%i) JSON response recieved, response not logged" % i) else: 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)) 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['status'] == 'success': break elif returnOnFailure and data['status'] == 'failure': Debug("[traktAPI] traktRequest(): Return on error set, breaking retry.") break else: Debug("[traktAPI] traktRequest(): (%i) JSON Error '%s' -> '%s'" % (i, data['status'], data['error'])) xbmc.sleep(1000) continue # check to see if we have data, an empty array is still valid data, so check for None only if not data is None: Debug("[traktAPI] traktRequest(): Have JSON data, breaking retry.") break xbmc.sleep(500)