def __init__(self, show_progress=False, api=None): self.traktapi = api self.show_progress = show_progress self.notify = utilities.getSettingAsBool('show_sync_notifications') self.simulate = utilities.getSettingAsBool('simulate_sync') if self.simulate: Debug("[Sync] Sync is configured to be simulated.")
def run(self): sync = Sync(show_progress=self._isManual, run_silent=self._runSilent, library=self._library, api=globals.traktapi) sync.sync() if utilities.getSettingAsBool('tagging_enable') and utilities.getSettingAsBool('tagging_tag_after_sync'): q = queue.SqliteQueue() q.append({'action': 'updatetags'})
def __scrobble(self, status): if not self.curVideoInfo: return logger.debug("scrobble()") scrobbleMovieOption = utilities.getSettingAsBool('scrobble_movie') scrobbleEpisodeOption = utilities.getSettingAsBool('scrobble_episode') watchedPercent = self.__calculateWatchedPercent() if utilities.isMovie(self.curVideo['type']) and scrobbleMovieOption: response = self.traktapi.scrobbleMovie(self.curVideoInfo, watchedPercent, status) if not response is None: self.__scrobbleNotification(response) logger.debug("Scrobble response: %s" % str(response)) return response elif utilities.isEpisode(self.curVideo['type']) and scrobbleEpisodeOption: if self.isMultiPartEpisode: logger.debug("Multi-part episode, scrobbling part %d of %d." % (self.curMPEpisode + 1, self.curVideo['multi_episode_count'])) adjustedDuration = int(self.videoDuration / self.curVideo['multi_episode_count']) watchedPercent = ((self.watchedTime - (adjustedDuration * self.curMPEpisode)) / adjustedDuration) * 100 response = self.traktapi.scrobbleEpisode(self.traktShowSummary, self.curVideoInfo, watchedPercent, status) if not response is None: self.__scrobbleNotification(response) logger.debug("Scrobble response: %s" % str(response)) return response
def run(self): 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'): q = queue.SqliteQueue() q.append({'action': 'updateTags'})
def __scrobble(self, status): if not self.curVideoInfo: return logger.debug("scrobble()") scrobbleMovieOption = utilities.getSettingAsBool("scrobble_movie") scrobbleEpisodeOption = utilities.getSettingAsBool("scrobble_episode") watchedPercent = self.__calculateWatchedPercent() if utilities.isMovie(self.curVideo["type"]) and scrobbleMovieOption: response = self.traktapi.scrobbleMovie(self.curVideoInfo, watchedPercent, status) if not response is None: self.__scrobbleNotification(response) logger.debug("Scrobble response: %s" % str(response)) return response elif utilities.isEpisode(self.curVideo["type"]) and scrobbleEpisodeOption: if self.isMultiPartEpisode: logger.debug( "Multi-part episode, scrobbling part %d of %d." % (self.curMPEpisode + 1, self.curVideo["multi_episode_count"]) ) adjustedDuration = int(self.videoDuration / self.curVideo["multi_episode_count"]) watchedPercent = ((self.watchedTime - (adjustedDuration * self.curMPEpisode)) / adjustedDuration) * 100 response = self.traktapi.scrobbleEpisode(self.traktShowSummary, self.curVideoInfo, watchedPercent, status) if response is not None: self.__scrobbleNotification(response) logger.debug("Scrobble response: %s" % str(response)) return response
def __preFetchUserRatings(self, result): if result: if utilities.isMovie( self.curVideo['type']) and utilities.getSettingAsBool( 'rate_movie'): # pre-get summary information, for faster rating dialog. logger.debug( "Movie rating is enabled, pre-fetching summary information." ) self.curVideoInfo = result['movie'] self.curVideoInfo['user'] = { 'ratings': self.traktapi.getMovieRatingForUser( result['movie']['ids']['trakt'], 'trakt') } elif utilities.isEpisode( self.curVideo['type']) and utilities.getSettingAsBool( 'rate_episode'): # pre-get summary information, for faster rating dialog. logger.debug( "Episode rating is enabled, pre-fetching summary information." ) self.curVideoInfo = result['episode'] self.curVideoInfo['user'] = { 'ratings': self.traktapi.getEpisodeRatingForUser( result['show']['ids']['trakt'], self.curVideoInfo['season'], self.curVideoInfo['number'], 'trakt') } logger.debug('Pre-Fetch result: %s; Info: %s' % (result, self.curVideoInfo))
def syncCheck(self, media_type): if media_type == 'movies': return utilities.getSettingAsBool('add_movies_to_trakt') or utilities.getSettingAsBool('trakt_movie_playcount') or utilities.getSettingAsBool('xbmc_movie_playcount') or utilities.getSettingAsBool('clean_trakt_movies') else: return utilities.getSettingAsBool('add_episodes_to_trakt') or utilities.getSettingAsBool('trakt_episode_playcount') or utilities.getSettingAsBool('xbmc_episode_playcount') or utilities.getSettingAsBool('clean_trakt_episodes') return False
def __syncWatchedCheck(self, media_type): if media_type == 'movies': return utilities.getSettingAsBool( 'trakt_movie_playcount') or utilities.getSettingAsBool( 'kodi_movie_playcount') else: return utilities.getSettingAsBool( 'trakt_episode_playcount') or utilities.getSettingAsBool( 'kodi_episode_playcount')
def __syncCollectionCheck(self, media_type): if media_type == 'movies': return utilities.getSettingAsBool( 'add_movies_to_trakt') or utilities.getSettingAsBool( 'clean_trakt_movies') else: return utilities.getSettingAsBool( 'add_episodes_to_trakt') or utilities.getSettingAsBool( 'clean_trakt_episodes')
def __init__(self, show_progress=False, run_silent=False, library="all", api=None): self.traktapi = api self.show_progress = show_progress self.run_silent = run_silent self.library = library if self.show_progress and self.run_silent: logger.debug("Sync is being run silently.") self.sync_on_update = utilities.getSettingAsBool('sync_on_update') self.notify = utilities.getSettingAsBool('show_sync_notifications') self.notify_during_playback = not (xbmc.Player().isPlayingVideo() and utilities.getSettingAsBool("hide_notifications_playback"))
def __init__(self, show_progress=False, api=None): self.traktapi = api self.show_progress = show_progress self.notify = utilities.getSettingAsBool('show_sync_notifications') self.simulate = utilities.getSettingAsBool('simulate_sync') if self.simulate: Debug("[Sync] Sync is configured to be simulated.") if self.show_progress: progress.create('%s %s' % (utilities.getString(1400), utilities.getString(1402)), line1=' ', line2=' ', line3=' ')
def _dispatch(self, data): try: utilities.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 == 'databaseUpdated': if utilities.getSettingAsBool('sync_on_update'): utilities.Debug("Performing sync after library update.") self.doSync() elif action == 'databaseCleaned': if utilities.getSettingAsBool('sync_on_update') and (utilities.getSettingAsBool('clean_trakt_movies') or utilities.getSettingAsBool('clean_trakt_episodes')): utilities.Debug("Performing sync after library clean.") self.doSync() elif action == 'settingsChanged': utilities.Debug("Settings changed, reloading.") globals.traktapi.updateSettings() elif action == 'markWatched': del data['action'] self.doMarkWatched(data) elif action == 'manualRating': ratingData = data['ratingData'] self.doManualRating(ratingData) elif action == 'manualSync': if not self.syncThread.isAlive(): utilities.Debug("Performing a manual sync.") self.doSync(manual=True, silent=data['silent'], library=data['library']) else: utilities.Debug("There already is a sync in progress.") elif action == 'settings': utilities.showSettings() elif action == 'scanStarted': pass else: utilities.Debug("Unknown dispatch action, '%s'." % action) except Exception as ex: template = ( "[TRAKT] EXCEPTION Thrown (PythonToCppException) : -->Python callback/script returned the following error<--\n" " - NOTE: IGNORING THIS CAN LEAD TO MEMORY LEAKS!\n" "Error Type: <type '{0}'>\n" "Error Contents: {1!r}\n" "{2}" "-->End of Python script error report<--" ) message = template.format(type(ex).__name__, ex.args, traceback.format_exc()) xbmc.log(message, level=xbmc.LOGDEBUG)
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 == 'databaseUpdated': if utilities.getSettingAsBool('sync_on_update'): logger.debug("Performing sync after library update.") self.doSync() elif action == 'databaseCleaned': if utilities.getSettingAsBool('sync_on_update') and ( utilities.getSettingAsBool('clean_trakt_movies') or utilities.getSettingAsBool('clean_trakt_episodes')): logger.debug("Performing sync after library clean.") self.doSync() elif action == 'settingsChanged': logger.debug("Settings changed, reloading.") globals.traktapi.updateSettings() 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': utilities.showSettings() elif action == 'scanStarted': pass else: logger.debug("Unknown dispatch action, '%s'." % action) except Exception as ex: message = utilities.createError(ex) logger.fatal(message)
def watching(self): if not self.isPlaying: return if not self.curVideoInfo: return Debug("[Scrobbler] watching()") self.update(True) duration = self.videoDuration / 60 watchedPercent = (self.watchedTime / self.videoDuration) * 100 if self.isMultiPartEpisode: Debug("[Scrobbler] Multi-part episode, watching part %d of %d." % ( self.curMPEpisode + 1, self.curVideo['multi_episode_count'])) # recalculate watchedPercent and duration for multi-part adjustedDuration = int(self.videoDuration / self.curVideo['multi_episode_count']) duration = adjustedDuration / 60 watchedPercent = ((self.watchedTime - (adjustedDuration * self.curMPEpisode)) / adjustedDuration) * 100 response = 'yep' if response != None: if self.curVideoInfo['tvdb_id'] is None: if 'status' in response and response['status'] == "success": if 'show' in response and 'tvdb_id' in response['show']: 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']}} utilities.xbmcJsonRequest(req) # get summary data now if we are rating this episode if utilities.getSettingAsBool('rate_episode') and self.traktSummaryInfo is None: self.traktSummaryInfo = self.traktapi.getEpisodeSummary(self.curVideoInfo['tvdb_id'], self.curVideoInfo['season'], self.curVideoInfo['episode']) Debug("[Scrobbler] Watch response: %s" % str(response)) match = utilities.getEpisodeDetailsFromXbmc(self.curMPEpisode, ['showtitle', 'season', 'episode', 'tvshowid', 'uniqueid']) else: match = utilities.getEpisodeDetailsFromXbmc(self.curVideo['id'], ['showtitle', 'season', 'episode', 'tvshowid', 'uniqueid']) elif 'showtitle' in self.curVideoData and 'season' in self.curVideoData and 'episode' in self.curVideoData: match = {} match['tvdb_id'] = None match['year'] = None match['showtitle'] = self.curVideoData['showtitle'] match['season'] = self.curVideoData['season'] match['episode'] = self.curVideoData['episode'] match['uniqueid'] = None if match == None: return
def scrobble(self): if not self.curVideoInfo: return Debug("[Scrobbler] scrobble()") scrobbleMovieOption = utilities.getSettingAsBool('scrobble_movie') scrobbleEpisodeOption = utilities.getSettingAsBool('scrobble_episode') duration = self.videoDuration / 60 watchedPercent = (self.watchedTime / self.videoDuration) * 100 if utilities.isMovie(self.curVideo['type']) and scrobbleMovieOption: response = self.traktapi.scrobbleMovie(self.curVideoInfo, duration, watchedPercent) if not response is None and 'status' in response: if response['status'] == "success": self.watchlistTagCheck() Debug("[Scrobbler] Scrobble response: %s" % str(response)) elif response['status'] == "failure": 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 utilities.isEpisode( self.curVideo['type']) and scrobbleEpisodeOption: if self.isMultiPartEpisode: Debug( "[Scrobbler] Multi-part episode, scrobbling part %d of %d." % (self.curMPEpisode + 1, self.curVideo['multi_episode_count'])) adjustedDuration = int(self.videoDuration / self.curVideo['multi_episode_count']) duration = adjustedDuration / 60 watchedPercent = ((self.watchedTime - (adjustedDuration * self.curMPEpisode)) / adjustedDuration) * 100 response = self.traktapi.scrobbleEpisode(self.curVideoInfo, duration, watchedPercent) if not response is None and 'status' in response: if response['status'] == "success": Debug("[Scrobbler] Scrobble response: %s" % str(response)) elif response['status'] == "failure": if response['error'].startswith("scrobbled") and response[ 'error'].endswith("already"): Debug( "[Scrobbler] Episode was just recently scrobbled, attempting to cancel watching instead." ) self.stoppedWatching()
def stoppedWatching(self): Debug("[Scrobbler] stoppedWatching()") scrobbleMovieOption = utilities.getSettingAsBool("scrobble_movie") scrobbleEpisodeOption = utilities.getSettingAsBool("scrobble_episode") if utilities.isMovie(self.curVideo['type']) and scrobbleMovieOption: response = self.traktapi.cancelWatchingMovie() if response != None: Debug("[Scrobbler] Cancel watch response: %s" % str(response)) elif utilities.isEpisode(self.curVideo['type']) and scrobbleEpisodeOption: response = self.traktapi.cancelWatchingEpisode() if response != None: Debug("[Scrobbler] Cancel watch response: %s" % str(response))
def scrobble(self, status): if not self.curVideoInfo: return Debug("[Scrobbler] scrobble()") scrobbleMovieOption = utilities.getSettingAsBool('scrobble_movie') scrobbleEpisodeOption = utilities.getSettingAsBool('scrobble_episode') duration = self.videoDuration / 60 watchedPercent = (self.watchedTime / self.videoDuration) * 100 if utilities.isMovie(self.curVideo['type']) and scrobbleMovieOption: response = self.traktapi.scrobbleMovie(self.curVideoInfo, watchedPercent, status) if not response is None and 'status' in response: if response['status'] == "success": self.watchlistTagCheck() response['title'] = response['movie']['title'] response['year'] = response['movie']['year'] self.scrobbleNotification(response) Debug("[Scrobbler] Scrobble response: %s" % str(response)) elif response['status'] == "failure": 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: Debug( "[Scrobbler] Multi-part episode, scrobbling part %d of %d." % (self.curMPEpisode + 1, self.curVideo['multi_episode_count'])) adjustedDuration = int(self.videoDuration / self.curVideo['multi_episode_count']) duration = adjustedDuration / 60 watchedPercent = ((self.watchedTime - (adjustedDuration * self.curMPEpisode)) / adjustedDuration) * 100 response = self.traktapi.scrobbleEpisode(self.curVideoInfo, watchedPercent, status) if not response is None and 'status' in response: if response['status'] == "success": response['episode']['season'] = response['season'] self.scrobbleNotification(response) Debug("[Scrobbler] Scrobble response: %s" % str(response)) elif response['status'] == "failure": Debug( "[Scrobbler] Show '%s' was not found on trakt.tv, possible malformed XBMC metadata." % self.curVideoInfo['showtitle'])
def __preFetchUserRatings(self, result): if result: if utilities.isMovie(self.curVideo['type']) and utilities.getSettingAsBool('rate_movie'): # pre-get summary information, for faster rating dialog. logger.debug("Movie rating is enabled, pre-fetching summary information.") self.curVideoInfo = result['movie'] self.curVideoInfo['user'] = {'ratings': self.traktapi.getMovieRatingForUser(result['movie']['ids']['trakt'], 'trakt')} elif utilities.isEpisode(self.curVideo['type']) and utilities.getSettingAsBool('rate_episode'): # pre-get summary information, for faster rating dialog. logger.debug("Episode rating is enabled, pre-fetching summary information.") self.curVideoInfo = result['episode'] self.curVideoInfo['user'] = {'ratings': self.traktapi.getEpisodeRatingForUser(result['show']['ids']['trakt'], self.curVideoInfo['season'], self.curVideoInfo['number'], 'trakt')} logger.debug('Pre-Fetch result: %s; Info: %s' % (result, self.curVideoInfo))
def scrobble(self): if not self.curVideoInfo: return Debug("[Scrobbler] scrobble()") scrobbleMovieOption = utilities.getSettingAsBool("scrobble_movie") scrobbleEpisodeOption = utilities.getSettingAsBool("scrobble_episode") duration = self.videoDuration / 60 watchedPercent = (self.watchedTime / self.videoDuration) * 100 if utilities.isMovie(self.curVideo["type"]) and scrobbleMovieOption: response = self.traktapi.scrobbleMovie(self.curVideoInfo, duration, watchedPercent) if not response is None and "status" in response: if response["status"] == "success": self.watchlistTagCheck() Debug("[Scrobbler] Scrobble response: %s" % str(response)) elif response["status"] == "failure": 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: Debug( "[Scrobbler] Multi-part episode, scrobbling part %d of %d." % (self.curMPEpisode + 1, self.curVideo["multi_episode_count"]) ) adjustedDuration = int(self.videoDuration / self.curVideo["multi_episode_count"]) duration = adjustedDuration / 60 watchedPercent = ((self.watchedTime - (adjustedDuration * self.curMPEpisode)) / adjustedDuration) * 100 response = self.traktapi.scrobbleEpisode(self.curVideoInfo, duration, watchedPercent) if not response is None and "status" in response: if response["status"] == "success": Debug("[Scrobbler] Scrobble response: %s" % str(response)) elif response["status"] == "failure": 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 _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 == 'databaseUpdated': if utilities.getSettingAsBool('sync_on_update'): logger.debug("Performing sync after library update.") self.doSync() elif action == 'databaseCleaned': if utilities.getSettingAsBool('sync_on_update') and (utilities.getSettingAsBool('clean_trakt_movies') or utilities.getSettingAsBool('clean_trakt_episodes')): logger.debug("Performing sync after library clean.") self.doSync() elif action == 'settingsChanged': logger.debug("Settings changed, reloading.") globals.traktapi.updateSettings() 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': utilities.showSettings() elif action == 'scanStarted': pass else: logger.debug("Unknown dispatch action, '%s'." % action) except Exception as ex: message = utilities.createError(ex) logger.fatal(message)
def watching(self): if not self.isPlaying: return if not self.curVideoInfo: return Debug("[Scrobbler] watching()") scrobbleMovieOption = utilities.getSettingAsBool('scrobble_movie') scrobbleEpisodeOption = utilities.getSettingAsBool('scrobble_episode') self.update(True) duration = self.videoDuration / 60 watchedPercent = (self.watchedTime / self.videoDuration) * 100 if utilities.isMovie(self.curVideo['type']) and scrobbleMovieOption: response = self.traktapi.watchingMovie(self.curVideoInfo, duration, watchedPercent) if response != None: if self.curVideoInfo['imdbnumber'] is None: if 'status' in response and response['status'] == "success": if 'movie' in response and 'imdb_id' in response['movie']: self.curVideoInfo['imdbnumber'] = response['movie']['imdb_id'] # get summary data now if we are rating this movie if utilities.getSettingAsBool('rate_movie') and self.traktSummaryInfo is None: self.traktSummaryInfo = self.traktapi.getMovieSummary(self.curVideoInfo['imdbnumber']) Debug("[Scrobbler] Watch response: %s" % str(response)) elif utilities.isEpisode(self.curVideo['type']) and scrobbleEpisodeOption: if self.isMultiPartEpisode: Debug("[Scrobbler] Multi-part episode, watching part %d of %d." % (self.curMPEpisode + 1, self.curVideo['multi_episode_count'])) # recalculate watchedPercent and duration for multi-part adjustedDuration = int(self.videoDuration / self.curVideo['multi_episode_count']) duration = adjustedDuration / 60 watchedPercent = ((self.watchedTime - (adjustedDuration * self.curMPEpisode)) / adjustedDuration) * 100 response = self.traktapi.watchingEpisode(self.curVideoInfo, duration, watchedPercent) if response != None: if self.curVideoInfo['tvdb_id'] is None: if 'status' in response and response['status'] == "success": if 'show' in response and 'tvdb_id' in response['show']: self.curVideoInfo['tvdb_id'] = response['show']['tvdb_id'] # get summary data now if we are rating this episode if utilities.getSettingAsBool('rate_episode') and self.traktSummaryInfo is None: self.traktSummaryInfo = self.traktapi.getEpisodeSummary(self.curVideoInfo['tvdb_id'], self.curVideoInfo['season'], self.curVideoInfo['episode']) Debug("[Scrobbler] Watch response: %s" % str(response))
def scrobbleNotification(self, info): if not self.curVideoInfo: return if utilities.getSettingAsBool("scrobble_notification"): s = utilities.getFormattedItemName(self.curVideo['type'], info) utilities.notification(utilities.getString(1049), s)
def __init__(self, show_progress=False, api=None): self.traktapi = api self.show_progress = show_progress self.notify = utilities.getSettingAsBool('show_sync_notifications') self.simulate = utilities.getSettingAsBool('simulate_sync') if self.simulate: Debug("[Sync] Sync is configured to be simulated.") _opts = ['ExcludePathOption', 'ExcludePathOption2', 'ExcludePathOption3'] _vals = ['ExcludePath', 'ExcludePath2', 'ExcludePath3'] self.exclusions = [] for i in range(3): if utilities.getSettingAsBool(_opts[i]): _path = utilities.getSetting(_vals[i]) if _path != "": self.exclusions.append(_path)
def check(self, id, rating=0): ok1,ok3=None,None db_rating=self._get(id) title=titlesync(id) if getSettingAsBool("silentoffline"): if db_rating==None and rating>=0: showMessage(__language__(30520),__language__(30522) % (str(rating))) ok1=True elif db_rating>=0 and rating!=db_rating: showMessage(__language__(30520),__language__(30523) % (str(rating))) ok3=True elif db_rating!=None and rating==db_rating: showMessage(__language__(30520),__language__(30524) % (str(rating))) else: if db_rating==None and rating>=0: ok1=self.dialog.yesno(__language__(30520),__language__(30525) % (str(rating)), unicode(title)) elif db_rating and rating!=db_rating: ok3=self.dialog.yesno(__language__(30520),__language__(30526) % (str(db_rating), str(rating)),unicode(title)) elif db_rating==0 and rating!=db_rating: ok3=True elif db_rating!=None and rating==db_rating: showMessage(__language__(30520),__language__(30527) % (str(rating))) if ok1: self._add(id, rating) return True if ok3: self._delete(id) self._add(id, rating) return True
def __traktLoadMoviesPlaybackProgress(self): if utilities.getSettingAsBool('trakt_movie_playback') and not self.__isCanceled(): self.__updateProgress(25, line2=utilities.getString(32122)) logger.debug('[Movies Sync] Getting playback progress from Trakt.tv') try: traktProgressMovies = self.traktapi.getMoviePlaybackProgress() except Exception: logger.debug("[Movies Sync] Invalid Trakt.tv playback progress list, possible error getting data from Trakt, aborting Trakt.tv playback update.") return False i = 0 x = float(len(traktProgressMovies)) moviesProgress = {'movies': []} for movie in traktProgressMovies: i += 1 y = ((i / x) * 25) + 11 self.__updateProgress(int(y), line2=utilities.getString(32123) % (i, x)) #will keep the data in python structures - just like the KODI response movie = movie.to_dict() moviesProgress['movies'].append(movie) self.__updateProgress(36, line2=utilities.getString(32124)) return moviesProgress
def __addMoviesToKodiWatched(self, traktMovies, kodiMovies): if utilities.getSettingAsBool('kodi_movie_playcount') and not self.__isCanceled(): updateKodiTraktMovies = copy.deepcopy(traktMovies) updateKodiKodiMovies = copy.deepcopy(kodiMovies) kodiMoviesToUpdate = self.__compareMovies(updateKodiTraktMovies, updateKodiKodiMovies, watched=True, restrict=True) if len(kodiMoviesToUpdate) == 0: self.__updateProgress(84, line2=utilities.getString(32088)) logger.debug("[Movies Sync] Kodi movie playcount is up to date.") return titles = ", ".join(["%s" % (m['title']) for m in kodiMoviesToUpdate]) logger.debug("[Movies Sync] %i movie(s) playcount will be updated in Kodi" % len(kodiMoviesToUpdate)) logger.debug("[Movies Sync] Movies to add: %s" % titles) self.__updateProgress(73, line2=utilities.getString(32065) % len(kodiMoviesToUpdate)) #split movie list into chunks of 50 chunksize = 50 chunked_movies = utilities.chunks([{"jsonrpc": "2.0", "method": "VideoLibrary.SetMovieDetails", "params": {"movieid": kodiMoviesToUpdate[i]['movieid'], "playcount": kodiMoviesToUpdate[i]['plays'], "lastplayed": utilities.convertUtcToDateTime(kodiMoviesToUpdate[i]['last_watched_at'])}, "id": i} for i in range(len(kodiMoviesToUpdate))], chunksize) i = 0 x = float(len(kodiMoviesToUpdate)) for chunk in chunked_movies: if self.__isCanceled(): return i += 1 y = ((i / x) * 11) + 73 self.__updateProgress(int(y), line2=utilities.getString(32089) % ((i)*chunksize if (i)*chunksize < x else x, x)) utilities.kodiJsonRequest(chunk) self.__updateProgress(84, line2=utilities.getString(32090) % len(kodiMoviesToUpdate))
def __traktLoadShowsPlaybackProgress(self): if utilities.getSettingAsBool('trakt_episode_playback') and not self.__isCanceled(): self.__updateProgress(10, line1=utilities.getString(1485), line2=utilities.getString(32119)) logger.debug('[Playback Sync] Getting playback progress from Trakt.tv') try: traktProgressShows = self.traktapi.getEpisodePlaybackProgress() except Exception: logger.debug("[Playback Sync] Invalid Trakt.tv progress list, possible error getting data from Trakt, aborting Trakt.tv playback update.") return False i = 0 x = float(len(traktProgressShows)) showsProgress = {'shows': []} for show in traktProgressShows: i += 1 y = ((i / x) * 20) + 6 self.__updateProgress(int(y), line2=utilities.getString(32120) % (i, x)) #will keep the data in python structures - just like the KODI response show = show.to_dict() showsProgress['shows'].append(show) self.__updateProgress(32, line2=utilities.getString(32121)) return showsProgress
def __scrobbleNotification(self, info): if not self.curVideoInfo: return if utilities.getSettingAsBool("scrobble_notification"): s = utilities.getFormattedItemName(self.curVideo["type"], info[self.curVideo["type"]]) utilities.notification(utilities.getString(32015), s)
def __addMovieProgressToKodi(self, traktMovies, kodiMovies): if utilities.getSettingAsBool('trakt_movie_playback') and traktMovies and not self.__isCanceled(): updateKodiTraktMovies = copy.deepcopy(traktMovies) updateKodiKodiMovies = copy.deepcopy(kodiMovies) kodiMoviesToUpdate = self.__compareMovies(updateKodiTraktMovies['movies'], updateKodiKodiMovies, restrict=True, playback=True) if len(kodiMoviesToUpdate) == 0: self.__updateProgress(99, line2=utilities.getString(32125)) logger.debug("[Movies Sync] Kodi movie playbacks are up to date.") return logger.debug("[Movies Sync] %i movie(s) playbacks will be updated in Kodi" % len(kodiMoviesToUpdate)) self.__updateProgress(85, line2=utilities.getString(32126) % len(kodiMoviesToUpdate)) #need to calculate the progress in int from progress in percent from Trakt #split movie list into chunks of 50 chunksize = 50 chunked_movies = utilities.chunks([{"jsonrpc": "2.0", "id": i, "method": "VideoLibrary.SetMovieDetails", "params": {"movieid": kodiMoviesToUpdate[i]['movieid'], "resume": {"position": kodiMoviesToUpdate[i]['runtime']/100.0*kodiMoviesToUpdate[i]['progress']}}} for i in range(len(kodiMoviesToUpdate))], chunksize) i = 0 x = float(len(kodiMoviesToUpdate)) for chunk in chunked_movies: if self.__isCanceled(): return i += 1 y = ((i / x) * 14) + 85 self.__updateProgress(int(y), line2=utilities.getString(32127) % ((i)*chunksize if (i)*chunksize < x else x, x)) utilities.kodiJsonRequest(chunk) self.__updateProgress(99, line2=utilities.getString(32128) % len(kodiMoviesToUpdate))
def testAccount(self, force=False): if self.__username == "": notification('trakt', getString( 1106)) # please enter your Username and Password in settings setSetting('account_valid', False) return False elif self.__password == "": notification( "trakt", getString(1107)) # please enter your Password in settings setSetting('account_valid', False) return False if not getSettingAsBool('account_valid') or force: Debug("[traktAPI] Testing account '%s'." % self.__username) url = "%s/account/test/%s" % (self.__baseURL, self.__apikey) Debug("[traktAPI] testAccount(url: %s)" % url) args = json.dumps({ 'username': self.__username, 'password': self.__password }) response = None try: # get data from trakt.tv response = self.__getData(url, args) except traktError, e: if isinstance(e, traktAuthProblem): Debug( "[traktAPI] testAccount(): Account '%s' failed authentication. (%s)" % (self.__username, e.value)) elif isinstance(e, traktServerBusy): Debug("[traktAPI] testAccount(): Server Busy (%s)" % e.value) elif isinstance(e, traktNetworkError): Debug("[traktAPI] testAccount(): Network error: %s" % e.value) elif isinstance(e, traktUnknownError): Debug("[traktAPI] testAccount(): Other problem (%s)" % e.value) else: pass if response: data = None try: data = json.loads(response) except ValueError: pass if 'status' in data: if data['status'] == 'success': setSetting('account_valid', True) Debug( "[traktAPI] testAccount(): Account '%s' is valid." % self.__username) return True
def __addMoviesToTraktCollection(self, kodiMovies, traktMovies): if utilities.getSettingAsBool('add_movies_to_trakt') and not self.__isCanceled(): addTraktMovies = copy.deepcopy(traktMovies) addKodiMovies = copy.deepcopy(kodiMovies) traktMoviesToAdd = self.__compareMovies(addKodiMovies, addTraktMovies) self.sanitizeMovies(traktMoviesToAdd) logger.debug("[Movies Sync] Compared movies, found %s to add." % len(traktMoviesToAdd)) if len(traktMoviesToAdd) == 0: self.__updateProgress(48, line2=utilities.getString(32084)) logger.debug("[Movies Sync] Trakt.tv movie collection is up to date.") return titles = ", ".join(["%s" % (m['title']) for m in traktMoviesToAdd]) logger.debug("[Movies Sync] %i movie(s) will be added to Trakt.tv collection." % len(traktMoviesToAdd)) logger.debug("[Movies Sync] Movies to add : %s" % titles) self.__updateProgress(37, line2=utilities.getString(32063) % len(traktMoviesToAdd)) moviesToAdd = {'movies': traktMoviesToAdd} #logger.debug("Movies to add: %s" % moviesToAdd) try: self.traktapi.addToCollection(moviesToAdd) except Exception as ex: message = utilities.createError(ex) logging.fatal(message) self.__updateProgress(48, line2=utilities.getString(32085) % len(traktMoviesToAdd))
def __deleteMoviesFromTraktCollection(self, traktMovies, kodiMovies): if utilities.getSettingAsBool('clean_trakt_movies') and not self.__isCanceled(): removeTraktMovies = copy.deepcopy(traktMovies) removeKodiMovies = copy.deepcopy(kodiMovies) logger.debug("[Movies Sync] Starting to remove.") traktMoviesToRemove = self.__compareMovies(removeTraktMovies, removeKodiMovies) self.sanitizeMovies(traktMoviesToRemove) logger.debug("[Movies Sync] Compared movies, found %s to remove." % len(traktMoviesToRemove)) if len(traktMoviesToRemove) == 0: self.__updateProgress(60, line2=utilities.getString(32091)) logger.debug("[Movies Sync] Trakt.tv movie collection is clean, no movies to remove.") return titles = ", ".join(["%s" % (m['title']) for m in traktMoviesToRemove]) logger.debug("[Movies Sync] %i movie(s) will be removed from Trakt.tv collection." % len(traktMoviesToRemove)) logger.debug("[Movies Sync] Movies removed: %s" % titles) self.__updateProgress(49, line2=utilities.getString(32076) % len(traktMoviesToRemove)) moviesToRemove = {'movies': traktMoviesToRemove} try: self.traktapi.removeFromCollection(moviesToRemove) except Exception as ex: message = utilities.createError(ex) logging.fatal(message) self.__updateProgress(60, line2=utilities.getString(32092) % len(traktMoviesToRemove))
def __addMoviesToTraktWatched(self, kodiMovies, traktMovies, fromPercent, toPercent): if utilities.getSettingAsBool( 'trakt_movie_playcount') and not self.sync.IsCanceled(): updateTraktTraktMovies = copy.deepcopy(traktMovies) updateTraktKodiMovies = copy.deepcopy(kodiMovies) traktMoviesToUpdate = self.__compareMovies(updateTraktKodiMovies, updateTraktTraktMovies, watched=True) self.sanitizeMovies(traktMoviesToUpdate) if len(traktMoviesToUpdate) == 0: self.sync.UpdateProgress(toPercent, line2=utilities.getString(32086)) logger.debug( "[Movies Sync] Trakt.tv movie playcount is up to date") return titles = ", ".join( ["%s" % (m['title']) for m in traktMoviesToUpdate]) logger.debug( "[Movies Sync] %i movie(s) playcount will be updated on Trakt.tv" % len(traktMoviesToUpdate)) logger.debug("[Movies Sync] Movies updated: %s" % titles) self.sync.UpdateProgress(fromPercent, line2=utilities.getString(32064) % len(traktMoviesToUpdate)) # Send request to update playcounts on Trakt.tv chunksize = 200 chunked_movies = utilities.chunks( [movie for movie in traktMoviesToUpdate], chunksize) errorcount = 0 i = 0 x = float(len(traktMoviesToUpdate)) for chunk in chunked_movies: if self.sync.IsCanceled(): return i += 1 y = ((i / x) * (toPercent - fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line2=utilities.getString(32093) % ((i) * chunksize if (i) * chunksize < x else x, x)) params = {'movies': chunk} # logger.debug("moviechunk: %s" % params) try: self.sync.traktapi.addToHistory(params) except Exception as ex: message = utilities.createError(ex) logging.fatal(message) errorcount += 1 logger.debug("[Movies Sync] Movies updated: %d error(s)" % errorcount) self.sync.UpdateProgress(toPercent, line2=utilities.getString(32087) % len(traktMoviesToUpdate))
def __deleteEpisodesFromTraktCollection(self, traktShows, kodiShows): if utilities.getSettingAsBool('clean_trakt_episodes') and not self.__isCanceled(): removeTraktShows = copy.deepcopy(traktShows) removeKodiShows = copy.deepcopy(kodiShows) traktShowsRemove = self.__compareShows(removeTraktShows, removeKodiShows) self.sanitizeShows(traktShowsRemove) if len(traktShowsRemove['shows']) == 0: self.__updateProgress(65, line1=utilities.getString(32077), line2=utilities.getString(32110)) logger.debug('[Episodes Sync] Trakt.tv episode collection is clean, no episodes to remove.') return logger.debug("[Episodes Sync] %i show(s) will have episodes removed from Trakt.tv collection." % len(traktShowsRemove['shows'])) for show in traktShowsRemove['shows']: logger.debug("[Episodes Sync] Episodes removed: %s" % self.__getShowAsString(show, short=True)) self.__updateProgress(50, line1=utilities.getString(32077), line2=utilities.getString(32111) % self.__countEpisodes(traktShowsRemove), line3=" ") logger.debug("[traktRemoveEpisodes] Shows to remove %s" % traktShowsRemove) try: self.traktapi.removeFromCollection(traktShowsRemove) except Exception as ex: message = utilities.createError(ex) logging.fatal(message) self.__updateProgress(65, line2=utilities.getString(32112) % self.__countEpisodes(traktShowsRemove), line3=" ")
def __syncEpisodes(self): if not self.show_progress and self.sync_on_update and self.notify and self.notify_during_playback: notification('%s %s' % (utilities.getString(1400), utilities.getString(1406)), utilities.getString(1420)) #Sync started if self.show_progress and not self.run_silent: progress.create("%s %s" % (utilities.getString(1400), utilities.getString(1406)), line1=" ", line2=" ", line3=" ") kodiShows = self.__kodiLoadShows() if not isinstance(kodiShows, list) and not kodiShows: Debug("[Episodes Sync] Kodi 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['shows'], 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('clean_trakt_episodes') and not self.__isCanceled(): traktShowsRemove = self.__compareShows(traktShows, kodiShows) self.__traktRemoveEpisodes(traktShowsRemove) if utilities.getSettingAsBool('trakt_episode_playcount') and not self.__isCanceled(): traktShowsUpdate = self.__compareShows(kodiShows, traktShows, watched=True) self.__traktUpdateEpisodes(traktShowsUpdate) if utilities.getSettingAsBool('kodi_episode_playcount') and not self.__isCanceled(): kodiShowsUpadate = self.__compareShows(traktShows, kodiShows, watched=True, restrict=True) self.__kodiUpdateEpisodes(kodiShowsUpadate) if utilities.getSettingAsBool('add_episodes_to_trakt') and not self.__isCanceled(): traktShowsAdd = self.__compareShows(kodiShows, traktShows) self.__traktAddEpisodes(traktShowsAdd) if not self.show_progress and self.sync_on_update and self.notify and self.notify_during_playback: notification('%s %s' % (utilities.getString(1400), utilities.getString(1406)), utilities.getString(1421)) #Sync complete if not self.__isCanceled() and self.show_progress and not self.run_silent: self.__updateProgress(100, line1=" ", line2=utilities.getString(1442), line3=" ") progress.close() Debug("[Episodes Sync] Shows on trakt.tv (%d), shows in Kodi (%d)." % (len(traktShows['shows']), len(kodiShows['shows']))) Debug("[Episodes Sync] Episodes on trakt.tv (%d), episodes in Kodi (%d)." % (self.__countEpisodes(traktShows), self.__countEpisodes(kodiShows))) Debug("[Episodes Sync] Complete.")
def cancelWatching(self, type): if self.testAccount(): url = "%s/%s/cancelwatching/%s" % (self.__baseURL, type, self.__apikey) Debug("[XbmcFilm] cancelWatching(url: %s)" % url) if getSettingAsBool('simulate_scrobbling'): return {'status': 'success'} else: return self.xbmcfilmRequest('POST', url)
def scrobble(self, type, data): if self.testAccount(): url = "%s/%s/scrobble/%s" % (self.__baseURL, type, self.__apikey) Debug("[XbmcFilm] scrobble(url: %s, data: %s)" % (url, str(data))) if getSettingAsBool('simulate_scrobbling'): return {'status': 'success'} else: return self.xbmcfilmRequest('POST', url, data, returnOnFailure=True, passVersions=True)
def ratingCheck(media_type, summary_info, watched_time, total_time, playlist_length): """Check if a video should be rated and if so launches the rating dialog""" utils.Debug("[Rating] Rating Check called for '%s'" % media_type); if not utils.getSettingAsBool("rate_%s" % media_type): utils.Debug("[Rating] '%s' is configured to not be rated." % media_type) return if summary_info is None: utils.Debug("[Rating] Summary information is empty, aborting.") return watched = (watched_time / total_time) * 100 if watched >= utils.getSettingAsFloat("rate_min_view_time"): if (playlist_length <= 1) or utils.getSettingAsBool("rate_each_playlist_item"): rateMedia(media_type, summary_info) else: utils.Debug("[Rating] Rate each playlist item is disabled.") else: utils.Debug("[Rating] '%s' does not meet minimum view time for rating (watched: %0.2f%%, minimum: %0.2f%%)" % (media_type, watched, utils.getSettingAsFloat("rate_min_view_time")))
def watching(self, type, data): if self.testAccount(): url = "%s/%s/watching/%s" % (self.__baseURL, type, self.__apikey) Debug("[XbmcFilm] watching(url: %s, data: %s)" % (url, str(data))) if getSettingAsBool('simulate_scrobbling'): return {'status': 'success'} else: return self.xbmcfilmRequest('POST', url, data, passVersions=True)
def watching(self, type, data): if self.testAccount(): url = "%s/%s/watching/%s" % (self.__baseURL, type, self.__apikey) Debug("[traktAPI] watching(url: %s, data: %s)" % (url, str(data))) if getSettingAsBool('simulate_scrobbling'): return {'status': 'success'} else: return self.traktRequest('POST', url, data, passVersions=True)
def playbackSeek(self): if not self.isPlaying: return Debug("[Scrobbler] playbackSeek()") self.update(True) if utilities.getSettingAsBool('watching_call_on_seek'): self.watching()
def scrobble(self, type, data): if self.testAccount(): url = "%s/%s/scrobble/%s" % (self.__baseURL, type, self.__apikey) Debug("[traktAPI] scrobble(url: %s, data: %s)" % (url, str(data))) if getSettingAsBool('simulate_scrobbling'): return {'status': 'success'} else: return self.traktRequest('POST', url, data, returnOnFailure=True, passVersions=True)
def cancelWatching(self, type): if self.testAccount(): url = "%s/%s/cancelwatching/%s" % (self.__baseURL, type, self.__apikey) Debug("[traktAPI] cancelWatching(url: %s)" % url) if getSettingAsBool('simulate_scrobbling'): return {'status': 'success'} else: return self.traktRequest('POST', url)
def syncEpisodes(self): if not self.show_progress and self.sync_on_update and self.notify and self.notify_during_playback: notification('%s %s' % (utilities.getString(1400), utilities.getString(1406)), utilities.getString(1420)) #Sync started 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(): traktShowsAdd = self.compareShows(xbmcShows, traktShows) self.traktAddEpisodes(traktShowsAdd) if utilities.getSettingAsBool('trakt_episode_playcount') and not self.isCanceled(): traktShowsUpdate = self.compareShows(xbmcShows, traktShows, watched=True) self.traktUpdateEpisodes(traktShowsUpdate) if utilities.getSettingAsBool('xbmc_episode_playcount') and not self.isCanceled(): xbmcShowsUpadate = self.compareShows(traktShows, xbmcShows, watched=True, restrict=True) self.xbmcUpdateEpisodes(xbmcShowsUpadate) if utilities.getSettingAsBool('clean_trakt_episodes') and not self.isCanceled(): traktShowsRemove = self.compareShows(traktShows, xbmcShows) self.traktRemoveEpisodes(traktShowsRemove) if not self.show_progress and self.sync_on_update and self.notify and self.notify_during_playback: notification('%s %s' % (utilities.getString(1400), utilities.getString(1406)), utilities.getString(1421)) #Sync complete if not self.isCanceled() and self.show_progress and not self.run_silent: self.updateProgress(100, line1=" ", line2=utilities.getString(1442), line3=" ") progress.close() Debug("[Episodes Sync] Shows on trakt.tv (%d), shows in XBMC (%d)." % (len(utilities.findAllInList(traktShows, 'in_collection', True)), len(xbmcShows))) Debug("[Episodes Sync] Episodes on trakt.tv (%d), episodes in XBMC (%d)." % (self.countEpisodes(traktShows), self.countEpisodes(xbmcShows))) Debug("[Episodes Sync] Complete.")
def syncMovies(self): if not self.show_progress and self.sync_on_update and self.notify and self.notify_during_playback: notification('%s %s' % (utilities.getString(1400), utilities.getString(1402)), utilities.getString(1420)) #Sync started 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(): traktMoviesToAdd = self.compareMovies(xbmcMovies, traktMovies) self.traktAddMovies(traktMoviesToAdd) if utilities.getSettingAsBool('trakt_movie_playcount') and not self.isCanceled(): traktMoviesToUpdate = self.compareMovies(xbmcMovies, traktMovies, watched=True) self.traktUpdateMovies(traktMoviesToUpdate) if utilities.getSettingAsBool('xbmc_movie_playcount') and not self.isCanceled(): xbmcMoviesToUpdate = self.compareMovies(traktMovies, xbmcMovies, watched=True, restrict=True) self.xbmcUpdateMovies(xbmcMoviesToUpdate) if utilities.getSettingAsBool('clean_trakt_movies') and not self.isCanceled(): traktMoviesToRemove = self.compareMovies(traktMovies, xbmcMovies) self.traktRemoveMovies(traktMoviesToRemove) if not self.isCanceled() and self.show_progress and not self.run_silent: self.updateProgress(100, line1=utilities.getString(1431), line2=" ", line3=" ") progress.close() if not self.show_progress and self.sync_on_update and self.notify and self.notify_during_playback: notification('%s %s' % (utilities.getString(1400), utilities.getString(1402)), utilities.getString(1421)) #Sync complete Debug("[Movies Sync] Movies on trakt.tv (%d), movies in XBMC (%d)." % (len(traktMovies), self.countMovies(xbmcMovies))) Debug("[Movies Sync] Complete.")
def __addMoviesToKodiWatched(self, traktMovies, kodiMovies): if utilities.getSettingAsBool( 'kodi_movie_playcount') and not self.__isCanceled(): updateKodiTraktMovies = copy.deepcopy(traktMovies) updateKodiKodiMovies = copy.deepcopy(kodiMovies) kodiMoviesToUpdate = self.__compareMovies(updateKodiTraktMovies, updateKodiKodiMovies, watched=True, restrict=True) if len(kodiMoviesToUpdate) == 0: self.__updateProgress(99, line2=utilities.getString(32088)) logger.debug( "[Movies Sync] Kodi movie playcount is up to date.") return titles = ", ".join( ["%s" % (m['title']) for m in kodiMoviesToUpdate]) logger.debug( "[Movies Sync] %i movie(s) playcount will be updated in Kodi" % len(kodiMoviesToUpdate)) logger.debug("[Movies Sync] Movies to add: %s" % titles) self.__updateProgress(83, line2=utilities.getString(32065) % len(kodiMoviesToUpdate)) #split movie list into chunks of 50 chunksize = 50 chunked_movies = utilities.chunks([{ "jsonrpc": "2.0", "method": "VideoLibrary.SetMovieDetails", "params": { "movieid": kodiMoviesToUpdate[i]['movieid'], "playcount": kodiMoviesToUpdate[i]['plays'] }, "id": i } for i in range(len(kodiMoviesToUpdate))], chunksize) i = 0 x = float(len(kodiMoviesToUpdate)) for chunk in chunked_movies: if self.__isCanceled(): return i += 1 y = ((i / x) * 16) + 83 self.__updateProgress(int(y), line2=utilities.getString(32089) % ((i) * chunksize if (i) * chunksize < x else x, x)) utilities.kodiJsonRequest(chunk) self.__updateProgress(99, line2=utilities.getString(32090) % len(kodiMoviesToUpdate))
def __preFetchUserRatings(self, result): if result: if utilities.isMovie( self.curVideo['type']) and utilities.getSettingAsBool( 'rate_movie'): # pre-get sumamry information, for faster rating dialog. logger.debug( "Movie rating is enabled, pre-fetching summary information." ) if result['movie']['ids']['imdb']: self.curVideoInfo['user'] = { 'ratings': self.traktapi.getMovieRatingForUser( result['movie']['ids']['imdb']) } self.curVideoInfo['ids'] = result['movie']['ids'] else: logger.debug( "'%s (%d)' has no valid id, can't get rating." % (self.curVideoInfo['title'], self.curVideoInfo['year'])) elif utilities.isEpisode( self.curVideo['type']) and utilities.getSettingAsBool( 'rate_episode'): # pre-get sumamry information, for faster rating dialog. logger.debug( "Episode rating is enabled, pre-fetching summary information." ) if result['show']['ids']['tvdb']: self.curVideoInfo['user'] = { 'ratings': self.traktapi.getEpisodeRatingForUser( result['show']['ids']['tvdb'], self.curVideoInfo['season'], self.curVideoInfo['number']) } self.curVideoInfo['ids'] = result['episode']['ids'] else: logger.debug( "'%s - S%02dE%02d' has no valid id, can't get rating." % (self.curVideoInfo['showtitle'], self.curVideoInfo['season'], self.curVideoInfo['episode']))
def __syncMovies(self): if not self.show_progress and self.sync_on_update and self.notify and self.notify_during_playback: notification('%s %s' % (utilities.getString(1400), utilities.getString(1402)), utilities.getString(1420)) #Sync started if self.show_progress and not self.run_silent: progress.create("%s %s" % (utilities.getString(1400), utilities.getString(1402)), line1=" ", line2=" ", line3=" ") kodiMovies = self.__kodiLoadMovies() if not isinstance(kodiMovies, list) and not kodiMovies: Debug("[Movies Sync] Kodi 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('clean_trakt_movies') and not self.__isCanceled(): Debug("[Movies Sync] Starting to remove.") traktMoviesToRemove = self.__compareMovies(traktMovies, kodiMovies) Debug("[Movies Sync] Compared movies, found %s to remove." % traktMoviesToRemove) self.__traktRemoveMovies(traktMoviesToRemove) if utilities.getSettingAsBool('kodi_movie_playcount') and not self.__isCanceled(): kodiMoviesToUpdate = self.__compareMovies(traktMovies, kodiMovies, watched=True, restrict=True) self.__kodiUpdateMovies(kodiMoviesToUpdate) if utilities.getSettingAsBool('add_movies_to_trakt') and not self.__isCanceled(): traktMoviesToAdd = self.__compareMovies(kodiMovies, traktMovies) Debug("[Movies Sync] Compared movies, found %s to add." % traktMoviesToAdd) self.__traktAddMovies(traktMoviesToAdd) if not self.__isCanceled() and self.show_progress and not self.run_silent: self.__updateProgress(100, line1=utilities.getString(1431), line2=" ", line3=" ") progress.close() if not self.show_progress and self.sync_on_update and self.notify and self.notify_during_playback: notification('%s %s' % (utilities.getString(1400), utilities.getString(1402)), utilities.getString(1421)) #Sync complete Debug("[Movies Sync] Movies on trakt.tv (%d), movies in Kodi (%d)." % (self.__countMovies(traktMovies), len(kodiMovies))) Debug("[Movies Sync] Complete.")
def cancelWatching(self, type): if self.testAccount(): url = "%s/%s/cancelwatching/%s" % (self.__baseURL, type, self.__apikey) Debug("[traktAPI] cancelWatching(url: %s)" % url) if getSettingAsBool('simulate_scrobbling'): Debug("[traktAPI] Simulating response.") return {'status': 'success'} else: return self.traktRequest('POST', url)
def __init__(self, show_progress=False, run_silent=False, library="all", api=None): self.traktapi = api self.show_progress = show_progress self.run_silent = run_silent self.library = library if self.show_progress and self.run_silent: Debug("[Sync] Sync is being run silently.") self.sync_on_update = utilities.getSettingAsBool('sync_on_update') self.notify = utilities.getSettingAsBool('show_sync_notifications') self.notify_during_playback = not (xbmc.Player().isPlayingVideo() and utilities.getSettingAsBool("hide_notifications_playback")) _opts = ['ExcludePathOption', 'ExcludePathOption2', 'ExcludePathOption3'] _vals = ['ExcludePath', 'ExcludePath2', 'ExcludePath3'] self.exclusions = [] for i in range(3): if utilities.getSettingAsBool(_opts[i]): _path = utilities.getSetting(_vals[i]) if _path != "": self.exclusions.append(_path)
def playbackResumed(self): if not self.isPlaying: return Debug("[Scrobbler] playbackResumed()") if self.isPaused: p = time.time() - self.pausedAt Debug("[Scrobbler] Resumed after: %s" % str(p)) self.pausedAt = 0 self.isPaused = False self.update(True) if utilities.getSettingAsBool('watching_call_on_resume'): self.watching()