def __traktLoadShowsPlaybackProgress(self, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_episode_playback') and not self.sync.IsCanceled(): self.sync.UpdateProgress(fromPercent, line1=kodiUtilities.getString( 1485), line2=kodiUtilities.getString(32119)) logger.debug( '[Playback Sync] Getting playback progress from Trakt.tv') try: traktProgressShows = self.sync.traktapi.getEpisodePlaybackProgress() except Exception as ex: logger.debug( "[Playback Sync] Invalid Trakt.tv progress list, possible error getting data from Trakt, aborting Trakt.tv playback update. Error: %s" % ex) return False i = 0 x = float(len(traktProgressShows)) showsProgress = {'shows': []} for show in traktProgressShows: i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress( int(y), line2=kodiUtilities.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.sync.UpdateProgress( toPercent, line2=kodiUtilities.getString(32121)) return showsProgress
def login(self): # Request new device code with Trakt.configuration.http(timeout=90): code = Trakt['oauth/device'].code() if not code: logger.debug('Error can not reach trakt') notification(getString(32024), getString(32023)) else: # Construct device authentication poller poller = Trakt['oauth/device'].poll(**code)\ .on('aborted', self.on_aborted)\ .on('authenticated', self.on_authenticated)\ .on('expired', self.on_expired)\ .on('poll', self.on_poll) # Start polling for authentication token poller.start(daemon=False) logger.debug('Enter the code "%s" at %s to authenticate your account' % ( code.get('user_code'), code.get('verification_url') )) self.authDialog = deviceAuthDialog.DeviceAuthDialog('script-trakt-DeviceAuthDialog.xml', __addon__.getAddonInfo('path'), code=code.get('user_code'), url=code.get('verification_url')) self.authDialog.doModal() del self.authDialog
def __deleteMoviesFromTraktCollection(self, traktMovies, kodiMovies, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('clean_trakt_movies') and not self.sync.IsCanceled(): removeTraktMovies = copy.deepcopy(traktMovies) removeKodiMovies = copy.deepcopy(kodiMovies) logger.debug("[Movies Sync] Starting to remove.") traktMoviesToRemove = utilities.compareMovies( removeTraktMovies, removeKodiMovies, kodiUtilities.getSettingAsBool("scrobble_fallback")) utilities.sanitizeMovies(traktMoviesToRemove) logger.debug("[Movies Sync] Compared movies, found %s to remove." % len(traktMoviesToRemove)) if len(traktMoviesToRemove) == 0: self.sync.UpdateProgress(toPercent, line2=kodiUtilities.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.sync.UpdateProgress(fromPercent, line2=kodiUtilities.getString(32076) % len(traktMoviesToRemove)) moviesToRemove = {'movies': traktMoviesToRemove} try: self.sync.traktapi.removeFromCollection(moviesToRemove) except Exception as ex: message = utilities.createError(ex) logging.fatal(message) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32092) % len(traktMoviesToRemove))
def __deleteEpisodesFromTraktCollection(self, traktShows, kodiShows, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('clean_trakt_episodes') and not self.sync.IsCanceled(): removeTraktShows = copy.deepcopy(traktShows) removeKodiShows = copy.deepcopy(kodiShows) traktShowsRemove = utilities.compareEpisodes( removeTraktShows, removeKodiShows, kodiUtilities.getSettingAsBool("scrobble_fallback")) utilities.sanitizeShows(traktShowsRemove) if len(traktShowsRemove['shows']) == 0: self.sync.UpdateProgress(toPercent, line1=kodiUtilities.getString( 32077), line2=kodiUtilities.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.sync.UpdateProgress(fromPercent, line1=kodiUtilities.getString( 32077), line2=kodiUtilities.getString(32111) % utilities.countEpisodes(traktShowsRemove)) logger.debug("[traktRemoveEpisodes] Shows to remove %s" % traktShowsRemove) try: self.sync.traktapi.removeFromCollection(traktShowsRemove) except Exception as ex: message = utilities.createError(ex) logging.fatal(message) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString( 32112) % utilities.countEpisodes(traktShowsRemove))
def __addMoviesToTraktCollection(self, kodiMovies, traktMovies, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('add_movies_to_trakt') and not self.sync.IsCanceled(): addTraktMovies = copy.deepcopy(traktMovies) addKodiMovies = copy.deepcopy(kodiMovies) traktMoviesToAdd = utilities.compareMovies( addKodiMovies, addTraktMovies, kodiUtilities.getSettingAsBool("scrobble_fallback")) utilities.sanitizeMovies(traktMoviesToAdd) logger.debug("[Movies Sync] Compared movies, found %s to add." % len(traktMoviesToAdd)) if len(traktMoviesToAdd) == 0: self.sync.UpdateProgress(toPercent, line2=kodiUtilities.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.sync.UpdateProgress(fromPercent, line2=kodiUtilities.getString(32063) % len(traktMoviesToAdd)) moviesToAdd = {'movies': traktMoviesToAdd} # logger.debug("Movies to add: %s" % moviesToAdd) try: self.sync.traktapi.addToCollection(moviesToAdd) except Exception as ex: message = utilities.createError(ex) logging.fatal(message) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32085) % len(traktMoviesToAdd))
def __syncEpisodeRatings(self, traktShows, kodiShows, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_sync_ratings') and traktShows and not self.sync.IsCanceled(): updateKodiTraktShows = copy.deepcopy(traktShows) updateKodiKodiShows = copy.deepcopy(kodiShows) traktShowsToUpdate = utilities.compareEpisodes( updateKodiKodiShows, updateKodiTraktShows, kodiUtilities.getSettingAsBool("scrobble_fallback"), rating=True) if len(traktShowsToUpdate['shows']) == 0: self.sync.UpdateProgress( toPercent, line1='', line2=kodiUtilities.getString(32181)) logger.debug( "[Episodes Sync] Trakt episode ratings are up to date.") else: logger.debug("[Episodes Sync] %i show(s) will have episode ratings added on Trakt" % len( traktShowsToUpdate['shows'])) self.sync.UpdateProgress(fromPercent, line1='', line2=kodiUtilities.getString( 32182) % len(traktShowsToUpdate['shows'])) self.sync.traktapi.addRating(traktShowsToUpdate) kodiShowsUpdate = utilities.compareEpisodes(updateKodiTraktShows, updateKodiKodiShows, kodiUtilities.getSettingAsBool( "scrobble_fallback"), restrict=True, rating=True) if len(kodiShowsUpdate['shows']) == 0: self.sync.UpdateProgress( toPercent, line1='', line2=kodiUtilities.getString(32173)) logger.debug( "[Episodes Sync] Kodi episode ratings are up to date.") else: logger.debug("[Episodes Sync] %i show(s) will have episode ratings added in Kodi" % len( kodiShowsUpdate['shows'])) for s in ["%s" % self.__getShowAsString(s, short=True) for s in kodiShowsUpdate['shows']]: logger.debug("[Episodes Sync] Episodes updated: %s" % s) episodes = [] for show in kodiShowsUpdate['shows']: for season in show['seasons']: for episode in season['episodes']: episodes.append( {'episodeid': episode['ids']['episodeid'], 'rating': episode['rating']}) # split episode list into chunks of 50 chunksize = 50 chunked_episodes = utilities.chunks([{"jsonrpc": "2.0", "id": i, "method": "VideoLibrary.SetEpisodeDetails", "params": {"episodeid": episodes[i]['episodeid'], "userrating": episodes[i]['rating']}} for i in range(len(episodes))], chunksize) i = 0 x = float(len(episodes)) for chunk in chunked_episodes: if self.sync.IsCanceled(): return i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line1='', line2=kodiUtilities.getString( 32174) % ((i) * chunksize if (i) * chunksize < x else x, x)) kodiUtilities.kodiJsonRequest(chunk) self.sync.UpdateProgress( toPercent, line2=kodiUtilities.getString(32175) % len(episodes))
def __get_settings(self): """get users settings and launch actions""" logger.debug("reading settings") self.service = globals.Service( getSettingAsBool("betaactive"), getSettingAsBool("betafirst"), getSetting("betauser"), getSetting("betapass"), getSettingAsBool("betabulk"), getSettingAsBool("betamark"), getSettingAsBool("betaunmark"), getSettingAsBool("betafollow"), getSettingAsBool("betanotify"), getSettingAsBool("betaupdate"), ) if self.service.active and self.service.user and self.service.password: globals.betaseriesapi = ServiceApi(self) globals.betaseriesapi._service_authenticate( self.service.user, self.service.password ) self.Player = MyPlayer( action=globals.betaseriesapi._service_betaserie, service=self.service ) if self.service.notify: notification(getString(32010), getString(30003))
def __deleteEpisodesFromTraktCollection(self, traktShows, kodiShows, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('clean_trakt_episodes') and not self.sync.IsCanceled(): removeTraktShows = copy.deepcopy(traktShows) removeKodiShows = copy.deepcopy(kodiShows) traktShowsRemove = self.__compareEpisodes(removeTraktShows, removeKodiShows) utilities.sanitizeShows(traktShowsRemove) if len(traktShowsRemove['shows']) == 0: self.sync.UpdateProgress(toPercent, line1=kodiUtilities.getString(32077), line2=kodiUtilities.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.sync.UpdateProgress(fromPercent, line1=kodiUtilities.getString(32077), line2=kodiUtilities.getString(32111) % self.__countEpisodes(traktShowsRemove)) logger.debug("[traktRemoveEpisodes] Shows to remove %s" % traktShowsRemove) try: self.sync.traktapi.removeFromCollection(traktShowsRemove) except Exception as ex: message = utilities.createError(ex) logging.fatal(message) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32112) % self.__countEpisodes(traktShowsRemove))
def __addMovieProgressToKodi(self, traktMovies, kodiMovies, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_movie_playback') and traktMovies and not self.sync.IsCanceled(): updateKodiTraktMovies = copy.deepcopy(traktMovies) updateKodiKodiMovies = copy.deepcopy(kodiMovies) kodiMoviesToUpdate = utilities.compareMovies(updateKodiTraktMovies['movies'], updateKodiKodiMovies, kodiUtilities.getSettingAsBool("scrobble_fallback"), restrict=True, playback=True) if len(kodiMoviesToUpdate) == 0: self.sync.UpdateProgress(toPercent, line1='', line2=kodiUtilities.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.sync.UpdateProgress(fromPercent, line1='', line2=kodiUtilities.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'], "total": kodiMoviesToUpdate[i]['runtime']}}} for i in range(len(kodiMoviesToUpdate))], chunksize) i = 0 x = float(len(kodiMoviesToUpdate)) for chunk in chunked_movies: if self.sync.IsCanceled(): return i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line2=kodiUtilities.getString(32127) % ((i) * chunksize if (i) * chunksize < x else x, x)) kodiUtilities.kodiJsonRequest(chunk) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32128) % len(kodiMoviesToUpdate))
def __addMoviesToKodiWatched(self, traktMovies, kodiMovies, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('kodi_movie_playcount') and not self.sync.IsCanceled(): updateKodiTraktMovies = copy.deepcopy(traktMovies) updateKodiKodiMovies = copy.deepcopy(kodiMovies) kodiMoviesToUpdate = utilities.compareMovies(updateKodiTraktMovies, updateKodiKodiMovies, kodiUtilities.getSettingAsBool( "scrobble_fallback"), watched=True, restrict=True) if len(kodiMoviesToUpdate) == 0: self.sync.UpdateProgress(toPercent, line2=kodiUtilities.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.sync.UpdateProgress(fromPercent, line2=kodiUtilities.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.sync.IsCanceled(): return i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line2=kodiUtilities.getString(32089) % ((i) * chunksize if (i) * chunksize < x else x, x)) kodiUtilities.kodiJsonRequest(chunk) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32090) % len(kodiMoviesToUpdate))
def __traktLoadMoviesPlaybackProgress(self, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_movie_playback') and not self.sync.IsCanceled(): self.sync.UpdateProgress(fromPercent, line2=kodiUtilities.getString(32122)) logger.debug('[Movies Sync] Getting playback progress from Trakt.tv') try: traktProgressMovies = self.sync.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) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line2=kodiUtilities.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.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32124)) return moviesProgress
def __traktLoadShowsPlaybackProgress(self, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_episode_playback') and not self.sync.IsCanceled(): self.sync.UpdateProgress(fromPercent, line1=kodiUtilities.getString(1485), line2=kodiUtilities.getString(32119)) logger.debug('[Playback Sync] Getting playback progress from Trakt.tv') try: traktProgressShows = self.sync.traktapi.getEpisodePlaybackProgress() except Exception as ex: logger.debug("[Playback Sync] Invalid Trakt.tv progress list, possible error getting data from Trakt, aborting Trakt.tv playback update. Error: %s" % ex) return False i = 0 x = float(len(traktProgressShows)) showsProgress = {'shows': []} for show in traktProgressShows: i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line2=kodiUtilities.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.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32121)) return showsProgress
def __traktLoadMovies(self): self.sync.UpdateProgress(10, line1=kodiUtilities.getString(32079), line2=kodiUtilities.getString(32081)) logger.debug("[Movies Sync] Getting movie collection from Trakt.tv") traktMovies = {} traktMovies = self.sync.traktapi.getMoviesCollected(traktMovies) self.sync.UpdateProgress(17, line2=kodiUtilities.getString(32082)) traktMovies = self.sync.traktapi.getMoviesWatched(traktMovies) if kodiUtilities.getSettingAsBool('trakt_sync_ratings'): traktMovies = self.sync.traktapi.getMoviesRated(traktMovies) traktMovies = list(traktMovies.items()) self.sync.UpdateProgress(24, line2=kodiUtilities.getString(32083)) movies = [] for _, movie in traktMovies: movie = movie.to_dict() movies.append(movie) return movies
def login(self): # Request new device code with Trakt.configuration.http(timeout=90): code = Trakt['oauth/device'].code() if not code: logger.debug('Error can not reach trakt') notification(getString(32024), getString(32023)) else: # Construct device authentication poller poller = Trakt['oauth/device'].poll(**code)\ .on('aborted', self.on_aborted)\ .on('authenticated', self.on_authenticated)\ .on('expired', self.on_expired)\ .on('poll', self.on_poll) # Start polling for authentication token poller.start(daemon=False) logger.debug( 'Enter the code "%s" at %s to authenticate your account' % (code.get('user_code'), code.get('verification_url'))) self.authDialog = deviceAuthDialog.DeviceAuthDialog( 'script-trakt-DeviceAuthDialog.xml', __addon__.getAddonInfo('path'), code=code.get('user_code'), url=code.get('verification_url')) self.authDialog.doModal() del self.authDialog
def __traktLoadMoviesPlaybackProgress(self, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_movie_playback') and not self.sync.IsCanceled(): self.sync.UpdateProgress( fromPercent, line2=kodiUtilities.getString(32122)) logger.debug( '[Movies Sync] Getting playback progress from Trakt.tv') try: traktProgressMovies = self.sync.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) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress( int(y), line2=kodiUtilities.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.sync.UpdateProgress( toPercent, line2=kodiUtilities.getString(32124)) return moviesProgress
def __addMoviesToTraktWatched(self, kodiMovies, traktMovies, fromPercent, toPercent): if kodiUtilities.getSettingAsBool( 'trakt_movie_playcount') and not self.sync.IsCanceled(): updateTraktTraktMovies = copy.deepcopy(traktMovies) updateTraktKodiMovies = copy.deepcopy(kodiMovies) traktMoviesToUpdate = utilities.compareMovies( updateTraktKodiMovies, updateTraktTraktMovies, watched=True) utilities.sanitizeMovies(traktMoviesToUpdate) if len(traktMoviesToUpdate) == 0: self.sync.UpdateProgress(toPercent, line2=kodiUtilities.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=kodiUtilities.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=kodiUtilities.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=kodiUtilities.getString(32087) % len(traktMoviesToUpdate))
def __syncShowsRatings(self, traktShows, kodiShows, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_sync_ratings') and traktShows and not self.sync.IsCanceled(): updateKodiTraktShows = copy.deepcopy(traktShows) updateKodiKodiShows = copy.deepcopy(kodiShows) traktShowsToUpdate = utilities.compareShows( updateKodiKodiShows, updateKodiTraktShows, kodiUtilities.getSettingAsBool("scrobble_fallback"), rating=True) if len(traktShowsToUpdate['shows']) == 0: self.sync.UpdateProgress( toPercent, line1='', line2=kodiUtilities.getString(32181)) logger.debug( "[Episodes Sync] Trakt show ratings are up to date.") else: logger.debug("[Episodes Sync] %i show(s) will have show ratings added on Trakt" % len( traktShowsToUpdate['shows'])) self.sync.UpdateProgress(fromPercent, line1='', line2=kodiUtilities.getString( 32182) % len(traktShowsToUpdate['shows'])) self.sync.traktapi.addRating(traktShowsToUpdate) # needs to be restricted, because we can't add a rating to an episode which is not in our Kodi collection kodiShowsUpdate = utilities.compareShows(updateKodiTraktShows, updateKodiKodiShows, kodiUtilities.getSettingAsBool( "scrobble_fallback"), rating=True, restrict=True) if len(kodiShowsUpdate['shows']) == 0: self.sync.UpdateProgress( toPercent, line1='', line2=kodiUtilities.getString(32176)) logger.debug( "[Episodes Sync] Kodi show ratings are up to date.") else: logger.debug("[Episodes Sync] %i show(s) will have show ratings added in Kodi" % len( kodiShowsUpdate['shows'])) shows = [] for show in kodiShowsUpdate['shows']: shows.append( {'tvshowid': show['tvshowid'], 'rating': show['rating']}) # split episode list into chunks of 50 chunksize = 50 chunked_episodes = utilities.chunks([{"jsonrpc": "2.0", "id": i, "method": "VideoLibrary.SetTVShowDetails", "params": {"tvshowid": shows[i]['tvshowid'], "userrating": shows[i]['rating']}} for i in range(len(shows))], chunksize) i = 0 x = float(len(shows)) for chunk in chunked_episodes: if self.sync.IsCanceled(): return i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line1='', line2=kodiUtilities.getString( 32177) % ((i) * chunksize if (i) * chunksize < x else x, x)) kodiUtilities.kodiJsonRequest(chunk) self.sync.UpdateProgress( toPercent, line2=kodiUtilities.getString(32178) % len(shows))
def onInit(self): instuction = self.getControl(INSTRUCTION_LABEL) authcode = self.getControl(AUTHCODE_LABEL) warning = self.getControl(WARNING_LABEL) instuction.setLabel( getString(32159).format("[COLOR red]" + self.url + "[/COLOR]")) authcode.setLabel(self.code) warning.setLabel(getString(32162))
def __kodiLoadShows(self): self.sync.UpdateProgress(1, line1=kodiUtilities.getString( 32094), line2=kodiUtilities.getString(32095)) logger.debug("[Episodes Sync] Getting show data from Kodi") data = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetTVShows', 'params': { 'properties': ['title', 'uniqueid', 'year', 'userrating']}, 'id': 0}) if data['limits']['total'] == 0: logger.debug("[Episodes Sync] Kodi json request was empty.") return None, None tvshows = kodiUtilities.kodiRpcToTraktMediaObjects(data) logger.debug( "[Episode Sync] Getting shows from kodi finished %s" % tvshows) if tvshows is None: return None, None self.sync.UpdateProgress(2, line2=kodiUtilities.getString(32096)) resultCollected = {'shows': []} resultWatched = {'shows': []} i = 0 x = float(len(tvshows)) logger.debug("[Episodes Sync] Getting episode data from Kodi") for show_col1 in tvshows: i += 1 y = ((i / x) * 8) + 2 self.sync.UpdateProgress( int(y), line2=kodiUtilities.getString(32097) % (i, x)) show = {'title': show_col1['title'], 'ids': show_col1['ids'], 'year': show_col1['year'], 'rating': show_col1['rating'], 'tvshowid': show_col1['tvshowid'], 'seasons': []} data = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': {'tvshowid': show_col1['tvshowid'], 'properties': [ 'season', 'episode', 'playcount', 'uniqueid', 'lastplayed', 'file', 'dateadded', 'runtime', 'userrating']}, 'id': 0}) if not data: logger.debug( "[Episodes Sync] There was a problem getting episode data for '%s', aborting sync." % show['title']) return None, None elif 'episodes' not in data: logger.debug( "[Episodes Sync] '%s' has no episodes in Kodi." % show['title']) continue if 'tvshowid' in show_col1: del(show_col1['tvshowid']) showWatched = copy.deepcopy(show) data2 = copy.deepcopy(data) show['seasons'] = kodiUtilities.kodiRpcToTraktMediaObjects(data) showWatched['seasons'] = kodiUtilities.kodiRpcToTraktMediaObjects( data2, 'watched') resultCollected['shows'].append(show) resultWatched['shows'].append(showWatched) self.sync.UpdateProgress(10, line2=kodiUtilities.getString(32098)) return resultCollected, resultWatched
def addEpisodesToHistory(self, summaryInfo, s): if len(summaryInfo['shows'][0]['seasons'][0]['episodes']) > 0: logger.debug("doMarkWatched(): %s" % str(summaryInfo)) result = globals.traktapi.addToHistory(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32113), kodiUtilities.getString(32115) % (result['added']['episodes'], s)) else: kodiUtilities.notification(kodiUtilities.getString(32114), s)
def addEpisodesToHistory(self, summaryInfo, s): if len(summaryInfo['shows'][0]['seasons'][0]['episodes']) > 0: logger.debug("doMarkWatched(): %s" % str(summaryInfo)) result = globals.traktapi.addToHistory(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString( 32113), kodiUtilities.getString(32115) % (result['added']['episodes'], s)) else: kodiUtilities.notification(kodiUtilities.getString(32114), s)
def __init__(self, sync, progress): self.sync = sync if not self.sync.show_progress and sync.sync_on_update and sync.notify and self.sync.notify_during_playback: kodiUtilities.notification( '%s %s' % (kodiUtilities.getString(32045), kodiUtilities.getString(32046)), kodiUtilities.getString(32061)) # Sync started if sync.show_progress and not sync.run_silent: progress.create( "%s %s" % (kodiUtilities.getString(32045), kodiUtilities.getString(32046)), "") kodiMovies = self.__kodiLoadMovies() if not isinstance(kodiMovies, list) and not kodiMovies: logger.debug( "[Movies Sync] Kodi movie list is empty, aborting movie Sync.") if sync.show_progress and not sync.run_silent: progress.close() return try: traktMovies = self.__traktLoadMovies() except Exception: logger.debug( "[Movies Sync] Error getting Trakt.tv movie list, aborting movie Sync." ) if sync.show_progress and not sync.run_silent: progress.close() return traktMoviesProgress = self.__traktLoadMoviesPlaybackProgress(25, 36) self.__addMoviesToTraktCollection(kodiMovies, traktMovies, 37, 47) self.__deleteMoviesFromTraktCollection(traktMovies, kodiMovies, 48, 58) self.__addMoviesToTraktWatched(kodiMovies, traktMovies, 59, 69) self.__addMoviesToKodiWatched(traktMovies, kodiMovies, 70, 80) self.__addMovieProgressToKodi(traktMoviesProgress, kodiMovies, 81, 91) self.__syncMovieRatings(traktMovies, kodiMovies, 92, 99) if sync.show_progress and not sync.run_silent: self.sync.UpdateProgress(100, line1=kodiUtilities.getString(32066), line2=" ", line3=" ") progress.close() if not sync.show_progress and sync.sync_on_update and sync.notify and sync.notify_during_playback: kodiUtilities.notification( '%s %s' % (kodiUtilities.getString(32045), kodiUtilities.getString(32046)), kodiUtilities.getString(32062)) # Sync complete logger.debug( "[Movies Sync] Movies on Trakt.tv (%d), movies in Kodi (%d)." % (len(traktMovies), len(kodiMovies))) logger.debug("[Movies Sync] Complete.")
def on_authenticated(self, token): """Triggered when device authentication has been completed :param token: Authentication token details :type token: dict """ self.authorization = token setSetting('authorization', dumps(self.authorization)) logger.debug('Authentication complete: %r' % token) self.authDialog.close() notification(getString(32157), getString(32152), 3000) self.updateUser()
def __kodiLoadShows(self): self.sync.UpdateProgress(1, line1=kodiUtilities.getString(32094), line2=kodiUtilities.getString(32095)) logger.debug("[Episodes Sync] Getting show data from Kodi") data = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetTVShows', 'params': {'properties': ['title', 'imdbnumber', 'year', 'userrating']}, 'id': 0}) if data['limits']['total'] == 0: logger.debug("[Episodes Sync] Kodi json request was empty.") return None, None tvshows = kodiUtilities.kodiRpcToTraktMediaObjects(data) logger.debug("[Episode Sync] Getting shows from kodi finished %s" % tvshows) if tvshows is None: return None, None self.sync.UpdateProgress(2, line2=kodiUtilities.getString(32096)) resultCollected = {'shows': []} resultWatched = {'shows': []} i = 0 x = float(len(tvshows)) logger.debug("[Episodes Sync] Getting episode data from Kodi") for show_col1 in tvshows: i += 1 y = ((i / x) * 8) + 2 self.sync.UpdateProgress(int(y), line2=kodiUtilities.getString(32097) % (i, x)) show = {'title': show_col1['title'], 'ids': {}, 'year': show_col1['year'], 'rating': show_col1['rating'], 'tvshowid': show_col1['tvshowid'], 'seasons': []} if 'ids' in show_col1 and 'tvdb' in show_col1['ids']: show['ids'] = {'tvdb': show_col1['ids']['tvdb']} data = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': {'tvshowid': show_col1['tvshowid'], 'properties': ['season', 'episode', 'playcount', 'uniqueid', 'lastplayed', 'file', 'dateadded', 'runtime', 'userrating']}, 'id': 0}) if not data: logger.debug("[Episodes Sync] There was a problem getting episode data for '%s', aborting sync." % show['title']) return None, None elif 'episodes' not in data: logger.debug("[Episodes Sync] '%s' has no episodes in Kodi." % show['title']) continue if 'tvshowid' in show_col1: del(show_col1['tvshowid']) showWatched = copy.deepcopy(show) data2 = copy.deepcopy(data) show['seasons'] = kodiUtilities.kodiRpcToTraktMediaObjects(data) showWatched['seasons'] = kodiUtilities.kodiRpcToTraktMediaObjects(data2, 'watched') resultCollected['shows'].append(show) resultWatched['shows'].append(showWatched) self.sync.UpdateProgress(10, line2=kodiUtilities.getString(32098)) return resultCollected, resultWatched
def onClick(self, control): logger.debug('onClick: %s' % (control)) if control == LATER_BUTTON: notification(getString(32157), getString(32150), 5000) setSetting('last_reminder', str(int(time.time()))) if control == NEVER_BUTTON: notification(getString(32157), getString(32151), 5000) setSetting('last_reminder', '-1') if control in [LATER_BUTTON, NEVER_BUTTON]: self.close()
def __syncEpisodeRatings(self, traktShows, kodiShows, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_sync_ratings') and traktShows and not self.sync.IsCanceled(): updateKodiTraktShows = copy.deepcopy(traktShows) updateKodiKodiShows = copy.deepcopy(kodiShows) traktShowsToUpdate = utilities.compareEpisodes( updateKodiKodiShows, updateKodiTraktShows, kodiUtilities.getSettingAsBool("scrobble_fallback"), rating=True) if len(traktShowsToUpdate['shows']) == 0: self.sync.UpdateProgress(toPercent, line1='', line2=kodiUtilities.getString(32181)) logger.debug("[Episodes Sync] Trakt episode ratings are up to date.") else: logger.debug("[Episodes Sync] %i show(s) will have episode ratings added on Trakt" % len(traktShowsToUpdate['shows'])) self.sync.UpdateProgress(fromPercent, line1='', line2=kodiUtilities.getString(32182) % len(traktShowsToUpdate['shows'])) self.sync.traktapi.addRating(traktShowsToUpdate) kodiShowsUpdate = utilities.compareEpisodes(updateKodiTraktShows, updateKodiKodiShows, kodiUtilities.getSettingAsBool( "scrobble_fallback"), restrict=True, rating=True) if len(kodiShowsUpdate['shows']) == 0: self.sync.UpdateProgress(toPercent, line1='', line2=kodiUtilities.getString(32173)) logger.debug("[Episodes Sync] Kodi episode ratings are up to date.") else: logger.debug("[Episodes Sync] %i show(s) will have episode ratings added in Kodi" % len(kodiShowsUpdate['shows'])) for s in ["%s" % self.__getShowAsString(s, short=True) for s in kodiShowsUpdate['shows']]: logger.debug("[Episodes Sync] Episodes updated: %s" % s) episodes = [] for show in kodiShowsUpdate['shows']: for season in show['seasons']: for episode in season['episodes']: episodes.append({'episodeid': episode['ids']['episodeid'], 'rating': episode['rating']}) # split episode list into chunks of 50 chunksize = 50 chunked_episodes = utilities.chunks([{"jsonrpc": "2.0", "id": i, "method": "VideoLibrary.SetEpisodeDetails", "params": {"episodeid": episodes[i]['episodeid'], "userrating": episodes[i]['rating']}} for i in range(len(episodes))], chunksize) i = 0 x = float(len(episodes)) for chunk in chunked_episodes: if self.sync.IsCanceled(): return i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line1='', line2=kodiUtilities.getString(32174) % ((i) * chunksize if (i) * chunksize < x else x, x)) kodiUtilities.kodiJsonRequest(chunk) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32175) % len(episodes))
def doAddToWatchlist(self, data): media_type = data['media_type'] if utilities.isMovie(media_type): temp_ids, id_type = utilities.parseIdToTraktIds( str(utilities.best_id(data['ids'], media_type)), media_type) best_id = temp_ids[id_type] summaryInfo = globals.traktapi.getMovieSummary( best_id).to_dict() if summaryInfo: s = utilities.getFormattedItemName(media_type, summaryInfo) logger.debug( "doAddToWatchlist(): '%s' trying to add to users watchlist." % s) params = {'movies': [summaryInfo]} logger.debug("doAddToWatchlist(): %s" % str(params)) result = globals.traktapi.addToWatchlist(params) if result: kodiUtilities.notification( kodiUtilities.getString(32165), s) else: kodiUtilities.notification( kodiUtilities.getString(32166), s) elif utilities.isEpisode(media_type): summaryInfo = {'shows': [{'ids': data['ids'], 'seasons': [{'number': data['season'], 'episodes': [{'number': data['number']}]}]}]} logger.debug("doAddToWatchlist(): %s" % str(summaryInfo)) s = utilities.getFormattedItemName(media_type, data) result = globals.traktapi.addToWatchlist(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s) elif utilities.isSeason(media_type): summaryInfo = {'shows': [{'ids': data['ids'], 'seasons': [{'number': data['season']}]}]} s = utilities.getFormattedItemName(media_type, data) logger.debug("doAddToWatchlist(): '%s - Season %d' trying to add to users watchlist." % (ids, data['season'])) result = globals.traktapi.addToWatchlist(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s) elif utilities.isShow(media_type): summaryInfo = { 'shows': [{'ids': data['ids']}]} s = utilities.getFormattedItemName(media_type, data) logger.debug("doAddToWatchlist(): %s" % str(summaryInfo)) result = globals.traktapi.addToWatchlist(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s)
def __kodiLoadMovies(self): self.sync.UpdateProgress(1, line2=kodiUtilities.getString(32079)) logger.debug("[Movies Sync] Getting movie data from Kodi") data = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'id': 0, 'method': 'VideoLibrary.GetMovies', 'params': {'properties': ['title', 'imdbnumber', 'uniqueid', 'year', 'playcount', 'lastplayed', 'file', 'dateadded', 'runtime', 'userrating']}}) if data['limits']['total'] == 0: logger.debug("[Movies Sync] Kodi JSON request was empty.") return kodi_movies = kodiUtilities.kodiRpcToTraktMediaObjects(data) self.sync.UpdateProgress(10, line2=kodiUtilities.getString(32080)) return kodi_movies
def doMarkWatched(self, data): media_type = data['media_type'] if utilities.isMovie(media_type): summaryInfo = globals.traktapi.getMovieSummary(data['id']).to_dict() if summaryInfo: if not summaryInfo['watched']: s = utilities.getFormattedItemName(media_type, summaryInfo) logger.debug("doMarkWatched(): '%s' is not watched on Trakt, marking it as watched." % s) params = {'movies': [summaryInfo]} logger.debug("doMarkWatched(): %s" % str(params)) result = globals.traktapi.addToHistory(params) if result: kodiUtilities.notification(kodiUtilities.getString(32113), s) else: kodiUtilities.notification(kodiUtilities.getString(32114), s) elif utilities.isEpisode(media_type): summaryInfo = {'shows': [{'ids':utilities.parseIdToTraktIds(data['id'],media_type)[0], 'seasons': [{'number': data['season'], 'episodes': [{'number':data['number']}]}]}]} logger.debug("doMarkWatched(): %s" % str(summaryInfo)) s = utilities.getFormattedItemName(media_type, data) result = globals.traktapi.addToHistory(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32113), s) else: kodiUtilities.notification(kodiUtilities.getString(32114), s) elif utilities.isSeason(media_type): summaryInfo = {'shows': [{'ids':utilities.parseIdToTraktIds(data['id'],media_type)[0], 'seasons': [{'number': data['season'], 'episodes': []}]}]} s = utilities.getFormattedItemName(media_type, data) for ep in data['episodes']: summaryInfo['shows'][0]['seasons'][0]['episodes'].append({'number': ep}) logger.debug("doMarkWatched(): '%s - Season %d' has %d episode(s) that are going to be marked as watched." % (data['id'], data['season'], len(summaryInfo['shows'][0]['seasons'][0]['episodes']))) self.addEpisodesToHistory(summaryInfo, s) elif utilities.isShow(media_type): summaryInfo = {'shows': [{'ids':utilities.parseIdToTraktIds(data['id'],media_type)[0], 'seasons': []}]} if summaryInfo: s = utilities.getFormattedItemName(media_type, data) logger.debug('data: %s' % data) for season in data['seasons']: episodeJson = [] for episode in data['seasons'][season]: episodeJson.append({'number': episode}) summaryInfo['shows'][0]['seasons'].append({'number': season, 'episodes': episodeJson}) self.addEpisodesToHistory(summaryInfo, s)
def __addEpisodeProgressToKodi(self, traktShows, kodiShows, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_episode_playback') and traktShows and not self.sync.IsCanceled(): updateKodiTraktShows = copy.deepcopy(traktShows) updateKodiKodiShows = copy.deepcopy(kodiShows) kodiShowsUpdate = utilities.compareEpisodes(updateKodiTraktShows, updateKodiKodiShows, kodiUtilities.getSettingAsBool( "scrobble_fallback"), restrict=True, playback=True) if len(kodiShowsUpdate['shows']) == 0: self.sync.UpdateProgress(toPercent, line1=kodiUtilities.getString( 1441), line2=kodiUtilities.getString(32129)) logger.debug( "[Episodes Sync] Kodi episode progress is up to date.") return logger.debug("[Episodes Sync] %i show(s) shows are missing progress in Kodi" % len( kodiShowsUpdate['shows'])) for s in ["%s" % self.__getShowAsString(s, short=True) for s in kodiShowsUpdate['shows']]: logger.debug("[Episodes Sync] Episodes updated: %s" % s) episodes = [] for show in kodiShowsUpdate['shows']: for season in show['seasons']: for episode in season['episodes']: # If library item doesn't have a runtime set get it from # Trakt to avoid later using 0 in runtime * progress_pct. if not episode['runtime']: episode['runtime'] = self.sync.traktapi.getEpisodeSummary( show['ids']['trakt'], season['number'], episode['number'], extended='full').runtime episodes.append( {'episodeid': episode['ids']['episodeid'], 'progress': episode['progress'], 'runtime': episode['runtime']}) # need to calculate the progress in int from progress in percent from Trakt # split episode list into chunks of 50 chunksize = 50 chunked_episodes = utilities.chunks([{"jsonrpc": "2.0", "id": i, "method": "VideoLibrary.SetEpisodeDetails", "params": {"episodeid": episode['episodeid'], "resume": { "position": episode['runtime'] / 100.0 * episode['progress'], "total": episode['runtime']}}} for episode in episodes if episode['runtime'] > 0], chunksize) i = 0 x = float(len(episodes)) for chunk in chunked_episodes: if self.sync.IsCanceled(): return i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line2=kodiUtilities.getString( 32130) % ((i) * chunksize if (i) * chunksize < x else x, x)) kodiUtilities.kodiJsonRequest(chunk) self.sync.UpdateProgress( toPercent, line2=kodiUtilities.getString(32131) % len(episodes))
def __kodiLoadMovies(self): self.sync.UpdateProgress(1, line2=kodiUtilities.getString(32079)) logger.debug("[Movies Sync] Getting movie data from Kodi") data = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'id': 0, 'method': 'VideoLibrary.GetMovies', 'params': {'properties': [ 'title', 'imdbnumber', 'uniqueid', 'year', 'playcount', 'lastplayed', 'file', 'dateadded', 'runtime', 'userrating']}}) if data['limits']['total'] == 0: logger.debug("[Movies Sync] Kodi JSON request was empty.") return kodi_movies = kodiUtilities.kodiRpcToTraktMediaObjects(data) self.sync.UpdateProgress(10, line2=kodiUtilities.getString(32080)) return kodi_movies
def __addEpisodesToKodiWatched(self, traktShows, kodiShows, kodiShowsCollected, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('kodi_episode_playcount') and not self.sync.IsCanceled(): updateKodiTraktShows = copy.deepcopy(traktShows) updateKodiKodiShows = copy.deepcopy(kodiShows) kodiShowsUpdate = utilities.compareEpisodes(updateKodiTraktShows, updateKodiKodiShows, kodiUtilities.getSettingAsBool( "scrobble_fallback"), watched=True, restrict=True, collected=kodiShowsCollected) if len(kodiShowsUpdate['shows']) == 0: self.sync.UpdateProgress(toPercent, line1=kodiUtilities.getString( 32074), line2=kodiUtilities.getString(32107)) logger.debug( "[Episodes Sync] Kodi episode playcounts are up to date.") return logger.debug("[Episodes Sync] %i show(s) shows are missing playcounts on Kodi" % len( kodiShowsUpdate['shows'])) for s in ["%s" % self.__getShowAsString(s, short=True) for s in kodiShowsUpdate['shows']]: logger.debug("[Episodes Sync] Episodes updated: %s" % s) # logger.debug("kodiShowsUpdate: %s" % kodiShowsUpdate) episodes = [] for show in kodiShowsUpdate['shows']: for season in show['seasons']: for episode in season['episodes']: episodes.append({'episodeid': episode['ids']['episodeid'], 'playcount': episode['plays'], "lastplayed": utilities.convertUtcToDateTime(episode['last_watched_at'])}) # split episode list into chunks of 50 chunksize = 50 chunked_episodes = utilities.chunks( [{"jsonrpc": "2.0", "method": "VideoLibrary.SetEpisodeDetails", "params": episodes[i], "id": i} for i in range(len(episodes))], chunksize) i = 0 x = float(len(episodes)) for chunk in chunked_episodes: if self.sync.IsCanceled(): return i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line2=kodiUtilities.getString( 32108) % ((i) * chunksize if (i) * chunksize < x else x, x)) logger.debug("[Episodes Sync] chunk %s" % str(chunk)) result = kodiUtilities.kodiJsonRequest(chunk) logger.debug("[Episodes Sync] result %s" % str(result)) self.sync.UpdateProgress( toPercent, line2=kodiUtilities.getString(32109) % len(episodes))
def __scrobbleNotification(self, info): if not self.curVideoInfo: return if kodiUtilities.getSettingAsBool("scrobble_notification"): s = utilities.getFormattedItemName(self.curVideo['type'], info[self.curVideo['type']]) kodiUtilities.notification(kodiUtilities.getString(32015), s)
def __syncShowsRatings(self, traktShows, kodiShows, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_sync_ratings') and traktShows and not self.sync.IsCanceled(): updateKodiTraktShows = copy.deepcopy(traktShows) updateKodiKodiShows = copy.deepcopy(kodiShows) traktShowsToUpdate = self.__compareShows(updateKodiKodiShows, updateKodiTraktShows, rating=True) if len(traktShowsToUpdate['shows']) == 0: self.sync.UpdateProgress(toPercent, line1='', line2=kodiUtilities.getString(32181)) logger.debug("[Episodes Sync] Trakt show ratings are up to date.") else: logger.debug("[Episodes Sync] %i show(s) will have show ratings added on Trakt" % len(traktShowsToUpdate['shows'])) self.sync.UpdateProgress(fromPercent, line1='', line2=kodiUtilities.getString(32182) % len(traktShowsToUpdate['shows'])) self.sync.traktapi.addRating(traktShowsToUpdate) # needs to be restricted, because we can't add a rating to an episode which is not in our Kodi collection kodiShowsUpdate = self.__compareShows(updateKodiTraktShows, updateKodiKodiShows, rating=True, restrict = True) if len(kodiShowsUpdate['shows']) == 0: self.sync.UpdateProgress(toPercent, line1='', line2=kodiUtilities.getString(32176)) logger.debug("[Episodes Sync] Kodi show ratings are up to date.") else: logger.debug("[Episodes Sync] %i show(s) will have show ratings added in Kodi" % len(kodiShowsUpdate['shows'])) shows = [] for show in kodiShowsUpdate['shows']: shows.append({'tvshowid': show['tvshowid'], 'rating': show['rating']}) # split episode list into chunks of 50 chunksize = 50 chunked_episodes = utilities.chunks([{"jsonrpc": "2.0", "id": i, "method": "VideoLibrary.SetTVShowDetails", "params": {"tvshowid": shows[i]['tvshowid'], "userrating": shows[i]['rating']}} for i in range(len(shows))], chunksize) i = 0 x = float(len(shows)) for chunk in chunked_episodes: if self.sync.IsCanceled(): return i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line1='', line2=kodiUtilities.getString(32177) % ((i) * chunksize if (i) * chunksize < x else x, x)) kodiUtilities.kodiJsonRequest(chunk) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32178) % len(shows))
def __rateOnTrakt(rating, media_type, media, unrate=False): logger.debug("Sending rating (%s) to Trakt.tv" % rating) params = media if utilities.isMovie(media_type): key = 'movies' params['rating'] = rating if 'movieid' in media: kodiUtilities.kodiJsonRequest({"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.SetMovieDetails", "params": { "movieid": media['movieid'], "userrating": rating}}) elif utilities.isShow(media_type): key = 'shows' # we need to remove this key or trakt will be confused del(params["seasons"]) params['rating'] = rating if 'tvshowid' in media: kodiUtilities.kodiJsonRequest({"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.SetTVShowDetails", "params": { "tvshowid": media['tvshowid'], "userrating": rating}}) elif utilities.isSeason(media_type): key = 'shows' params['seasons'] = [{'rating': rating, 'number': media['season']}] elif utilities.isEpisode(media_type): key = 'episodes' params['rating'] = rating if 'episodeid' in media: kodiUtilities.kodiJsonRequest({"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.SetEpisodeDetails", "params": { "episodeid": media['episodeid'], "userrating": rating}}) else: return root = {key: [params]} if not unrate: data = globals.traktapi.addRating(root) else: data = globals.traktapi.removeRating(root) if data: s = utilities.getFormattedItemName(media_type, media) if 'not_found' in data and not data['not_found']['movies'] and not data['not_found']['episodes'] and not data['not_found']['shows']: if not unrate: kodiUtilities.notification(kodiUtilities.getString(32040), s) else: kodiUtilities.notification(kodiUtilities.getString(32042), s) else: kodiUtilities.notification(kodiUtilities.getString(32044), s)
def __addEpisodesToTraktCollection(self, kodiShows, traktShows, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('add_episodes_to_trakt') and not self.sync.IsCanceled(): addTraktShows = copy.deepcopy(traktShows) addKodiShows = copy.deepcopy(kodiShows) tmpTraktShowsAdd = utilities.compareEpisodes( addKodiShows, addTraktShows, kodiUtilities.getSettingAsBool("scrobble_fallback")) traktShowsAdd = copy.deepcopy(tmpTraktShowsAdd) utilities.sanitizeShows(traktShowsAdd) # logger.debug("traktShowsAdd %s" % traktShowsAdd) if len(traktShowsAdd['shows']) == 0: self.sync.UpdateProgress(toPercent, line1=kodiUtilities.getString(32068), line2=kodiUtilities.getString(32104)) logger.debug("[Episodes Sync] Trakt.tv episode collection is up to date.") return logger.debug("[Episodes Sync] %i show(s) have episodes (%d) to be added to your Trakt.tv collection." % (len(traktShowsAdd['shows']), utilities.countEpisodes(traktShowsAdd))) for show in traktShowsAdd['shows']: logger.debug("[Episodes Sync] Episodes added: %s" % self.__getShowAsString(show, short=True)) self.sync.UpdateProgress(fromPercent, line1=kodiUtilities.getString(32068), line2=kodiUtilities.getString(32067) % (len(traktShowsAdd['shows']))) # split episode list into chunks of 50 chunksize = 1 chunked_episodes = utilities.chunks(traktShowsAdd['shows'], chunksize) errorcount = 0 i = 0 x = float(len(traktShowsAdd['shows'])) for chunk in chunked_episodes: if self.sync.IsCanceled(): return i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line2=kodiUtilities.getString(32069) % ((i) * chunksize if (i) * chunksize < x else x, x)) request = {'shows': chunk} logger.debug("[traktAddEpisodes] Shows to add %s" % request) try: self.sync.traktapi.addToCollection(request) except Exception as ex: message = utilities.createError(ex) logging.fatal(message) errorcount += 1 logger.debug("[traktAddEpisodes] Finished with %d error(s)" % errorcount) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32105) % utilities.countEpisodes(traktShowsAdd))
def __deleteMoviesFromTraktCollection(self, traktMovies, kodiMovies, fromPercent, toPercent): if kodiUtilities.getSettingAsBool( 'clean_trakt_movies') and not self.sync.IsCanceled(): removeTraktMovies = copy.deepcopy(traktMovies) removeKodiMovies = copy.deepcopy(kodiMovies) logger.debug("[Movies Sync] Starting to remove.") traktMoviesToRemove = utilities.compareMovies( removeTraktMovies, removeKodiMovies, kodiUtilities.getSettingAsBool("scrobble_fallback")) utilities.sanitizeMovies(traktMoviesToRemove) logger.debug("[Movies Sync] Compared movies, found %s to remove." % len(traktMoviesToRemove)) if len(traktMoviesToRemove) == 0: self.sync.UpdateProgress(toPercent, line2=kodiUtilities.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.sync.UpdateProgress(fromPercent, line2=kodiUtilities.getString(32076) % len(traktMoviesToRemove)) moviesToRemove = {'movies': traktMoviesToRemove} try: self.sync.traktapi.removeFromCollection(moviesToRemove) except Exception as ex: message = utilities.createError(ex) logging.fatal(message) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32092) % len(traktMoviesToRemove))
def __addEpisodesToTraktWatched(self, kodiShows, traktShows, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_episode_playcount') and not self.sync.IsCanceled(): updateTraktTraktShows = copy.deepcopy(traktShows) updateTraktKodiShows = copy.deepcopy(kodiShows) traktShowsUpdate = utilities.compareEpisodes( updateTraktKodiShows, updateTraktTraktShows, kodiUtilities.getSettingAsBool("scrobble_fallback"), watched=True) utilities.sanitizeShows(traktShowsUpdate) # logger.debug("traktShowsUpdate %s" % traktShowsUpdate) if len(traktShowsUpdate['shows']) == 0: self.sync.UpdateProgress(toPercent, line1=kodiUtilities.getString(32071), line2=kodiUtilities.getString(32106)) logger.debug("[Episodes Sync] Trakt.tv episode playcounts are up to date.") return logger.debug("[Episodes Sync] %i show(s) are missing playcounts on Trakt.tv" % len(traktShowsUpdate['shows'])) for show in traktShowsUpdate['shows']: logger.debug("[Episodes Sync] Episodes updated: %s" % self.__getShowAsString(show, short=True)) self.sync.UpdateProgress(fromPercent, line1=kodiUtilities.getString(32071), line2=kodiUtilities.getString(32070) % (len(traktShowsUpdate['shows']))) errorcount = 0 i = 0 x = float(len(traktShowsUpdate['shows'])) for show in traktShowsUpdate['shows']: if self.sync.IsCanceled(): return epCount = utilities.countEpisodes([show]) title = show['title'].encode('utf-8', 'ignore') i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line2=title, line3=kodiUtilities.getString(32073) % epCount) s = {'shows': [show]} logger.debug("[traktUpdateEpisodes] Shows to update %s" % s) try: self.sync.traktapi.addToHistory(s) except Exception as ex: message = utilities.createError(ex) logging.fatal(message) errorcount += 1 logger.debug("[traktUpdateEpisodes] Finished with %d error(s)" % errorcount) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32072) % (len(traktShowsUpdate['shows'])), line3=" ")
def __addEpisodesToTraktWatched(self, kodiShows, traktShows, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_episode_playcount') and not self.sync.IsCanceled(): updateTraktTraktShows = copy.deepcopy(traktShows) updateTraktKodiShows = copy.deepcopy(kodiShows) traktShowsUpdate = utilities.compareEpisodes( updateTraktKodiShows, updateTraktTraktShows, kodiUtilities.getSettingAsBool("scrobble_fallback"), watched=True) utilities.sanitizeShows(traktShowsUpdate) # logger.debug("traktShowsUpdate %s" % traktShowsUpdate) if len(traktShowsUpdate['shows']) == 0: self.sync.UpdateProgress(toPercent, line1=kodiUtilities.getString(32071), line2=kodiUtilities.getString(32106)) logger.debug("[Episodes Sync] Trakt.tv episode playcounts are up to date.") return logger.debug("[Episodes Sync] %i show(s) are missing playcounts on Trakt.tv" % len(traktShowsUpdate['shows'])) for show in traktShowsUpdate['shows']: logger.debug("[Episodes Sync] Episodes updated: %s" % self.__getShowAsString(show, short=True)) self.sync.UpdateProgress(fromPercent, line1=kodiUtilities.getString(32071), line2=kodiUtilities.getString(32070) % (len(traktShowsUpdate['shows']))) errorcount = 0 i = 0 x = float(len(traktShowsUpdate['shows'])) for show in traktShowsUpdate['shows']: if self.sync.IsCanceled(): return epCount = utilities.countEpisodes([show]) title = show['title'] i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line2=title, line3=kodiUtilities.getString(32073) % epCount) s = {'shows': [show]} logger.debug("[traktUpdateEpisodes] Shows to update %s" % s) try: self.sync.traktapi.addToHistory(s) except Exception as ex: message = utilities.createError(ex) logging.fatal(message) errorcount += 1 logger.debug("[traktUpdateEpisodes] Finished with %d error(s)" % errorcount) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32072) % (len(traktShowsUpdate['shows'])), line3=" ")
def __addMoviesToKodiWatched(self, traktMovies, kodiMovies, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('kodi_movie_playcount') and not self.sync.IsCanceled(): updateKodiTraktMovies = copy.deepcopy(traktMovies) updateKodiKodiMovies = copy.deepcopy(kodiMovies) kodiMoviesToUpdate = utilities.compareMovies(updateKodiTraktMovies, updateKodiKodiMovies, kodiUtilities.getSettingAsBool( "scrobble_fallback"), watched=True, restrict=True) if len(kodiMoviesToUpdate) == 0: self.sync.UpdateProgress( toPercent, line2=kodiUtilities.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.sync.UpdateProgress(fromPercent, line2=kodiUtilities.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.sync.IsCanceled(): return i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line2=kodiUtilities.getString( 32089) % ((i) * chunksize if (i) * chunksize < x else x, x)) kodiUtilities.kodiJsonRequest(chunk) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString( 32090) % len(kodiMoviesToUpdate))
def _service_authenticate(self, user=None, pw=None): """authenticate if necessary into betaseries.com Args: user ([str], optional): username. Defaults to None. pw ([str], optional): password. Defaults to None. """ if user: self.user = user if pw: self.pw = pw # don't proceed if timeout timer has not expired if self.timerexpiretime > int(time.time()): return if self.__auth(): logger.info("successfully authenticated") else: notification(getString(32010), getString(32003)) logger.error("failed to connect for authentication")
def __checkerrors(self, error, auth=False, infos=""): """treatment about error returned by betaseries API Args: error (dict): error returned by API auth (bool, optional): error occured during authentication process. Defaults to False. infos (str, optional): text to add to message. Defaults to "". Returns: True on real error False on non real error (informations returned by API with 0 code) """ if auth is False and error["code"] == 0: return False if error["code"] < 2000: # API error notification(getString(32010), getString(32002)) logger.warning( f"bad API usage : [{error['code']}] - {error['text']}") # disable the service, the monitor class will pick up the changes # setSetting("betaactive", "false") elif error["code"] > 4001: # login error notification(getString(32010), getString(32004)) logger.warning("login or password incorrect") self.auth_fail = True elif error["code"] == 2001: # drop our session key self.token = "" logger.info("bad token") return True elif error["code"] == 2003: logger.info(f"already following show {infos}") # everything else elif auth is True: self.__service_fail(True) notification(getString(32010), getString(32001)) logger.error("server error while authenticating") notification(getString(32010), getString(32009)) else: notification(getString(32010), getString(32005, infos)) logger.info(f"failed to follow show {infos}") return True
def __init__(self, sync, progress): self.sync = sync if not self.sync.show_progress and self.sync.sync_on_update and self.sync.notify and self.sync.notify_during_playback: kodiUtilities.notification('%s %s' % (kodiUtilities.getString(32045), kodiUtilities.getString(32050)), kodiUtilities.getString(32061)) # Sync started if self.sync.show_progress and not self.sync.run_silent: progress.create("%s %s" % (kodiUtilities.getString(32045), kodiUtilities.getString(32050)), line1=" ", line2=" ", line3=" ") kodiShowsCollected, kodiShowsWatched = self.__kodiLoadShows() if not isinstance(kodiShowsCollected, list) and not kodiShowsCollected: logger.debug("[Episodes Sync] Kodi collected show list is empty, aborting tv show Sync.") if self.sync.show_progress and not self.sync.run_silent: progress.close() return if not isinstance(kodiShowsWatched, list) and not kodiShowsWatched: logger.debug("[Episodes Sync] Kodi watched show list is empty, aborting tv show Sync.") if self.sync.show_progress and not self.sync.run_silent: progress.close() return traktShowsCollected, traktShowsWatched, traktShowsRated, traktEpisodesRated = self.__traktLoadShows() if not traktShowsCollected: logger.debug("[Episodes Sync] Error getting Trakt.tv collected show list, aborting tv show sync.") if self.sync.show_progress and not self.sync.run_silent: progress.close() return if not traktShowsWatched: logger.debug("[Episodes Sync] Error getting Trakt.tv watched show list, aborting tv show sync.") if self.sync.show_progress and not self.sync.run_silent: progress.close() return traktShowsProgress = self.__traktLoadShowsPlaybackProgress(25, 36) self.__addEpisodesToTraktCollection(kodiShowsCollected, traktShowsCollected, 37, 47) self.__deleteEpisodesFromTraktCollection(traktShowsCollected, kodiShowsCollected, 48, 58) self.__addEpisodesToTraktWatched(kodiShowsWatched, traktShowsWatched, 59, 69) self.__addEpisodesToKodiWatched(traktShowsWatched, kodiShowsWatched, kodiShowsCollected, 70, 80) self.__addEpisodeProgressToKodi(traktShowsProgress, kodiShowsCollected, 81, 91) self.__syncShowsRatings(traktShowsRated, kodiShowsCollected, 92, 95) self.__syncEpisodeRatings(traktEpisodesRated, kodiShowsCollected, 96, 99) if not self.sync.show_progress and self.sync.sync_on_update and self.sync.notify and self.sync.notify_during_playback: kodiUtilities.notification('%s %s' % (kodiUtilities.getString(32045), kodiUtilities.getString(32050)), kodiUtilities.getString(32062)) # Sync complete if self.sync.show_progress and not self.sync.run_silent: self.sync.UpdateProgress(100, line1=" ", line2=kodiUtilities.getString(32075), line3=" ") progress.close() logger.debug("[Episodes Sync] Shows on Trakt.tv (%d), shows in Kodi (%d)." % (len(traktShowsCollected['shows']), len(kodiShowsCollected['shows']))) logger.debug("[Episodes Sync] Episodes on Trakt.tv (%d), episodes in Kodi (%d)." % (utilities.countEpisodes(traktShowsCollected), utilities.countEpisodes(kodiShowsCollected))) logger.debug("[Episodes Sync] Complete.")
def __addMoviesToTraktWatched(self, kodiMovies, traktMovies, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_movie_playcount') and not self.sync.IsCanceled(): updateTraktTraktMovies = copy.deepcopy(traktMovies) updateTraktKodiMovies = copy.deepcopy(kodiMovies) traktMoviesToUpdate = utilities.compareMovies(updateTraktKodiMovies, updateTraktTraktMovies, kodiUtilities.getSettingAsBool("scrobble_fallback"), watched=True) utilities.sanitizeMovies(traktMoviesToUpdate) if len(traktMoviesToUpdate) == 0: self.sync.UpdateProgress(toPercent, line2=kodiUtilities.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=kodiUtilities.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=kodiUtilities.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=kodiUtilities.getString(32087) % len(traktMoviesToUpdate))
def __addMoviesToTraktCollection(self, kodiMovies, traktMovies, fromPercent, toPercent): if kodiUtilities.getSettingAsBool( 'add_movies_to_trakt') and not self.sync.IsCanceled(): addTraktMovies = copy.deepcopy(traktMovies) addKodiMovies = copy.deepcopy(kodiMovies) traktMoviesToAdd = utilities.compareMovies( addKodiMovies, addTraktMovies, kodiUtilities.getSettingAsBool("scrobble_fallback")) utilities.sanitizeMovies(traktMoviesToAdd) logger.debug("[Movies Sync] Compared movies, found %s to add." % len(traktMoviesToAdd)) if len(traktMoviesToAdd) == 0: self.sync.UpdateProgress(toPercent, line2=kodiUtilities.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.sync.UpdateProgress(fromPercent, line2=kodiUtilities.getString(32063) % len(traktMoviesToAdd)) moviesToAdd = {'movies': traktMoviesToAdd} # logger.debug("Movies to add: %s" % moviesToAdd) try: self.sync.traktapi.addToCollection(moviesToAdd) except Exception as ex: message = utilities.createError(ex) logging.fatal(message) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32085) % len(traktMoviesToAdd))
def __auth(self): """low level Authenticate into betaseries.com Returns: True or None """ # create a pass hash md5pass = hashlib.md5() md5pass.update(self.pw.encode("utf8")) url = self.apiurl + "/members/auth" urldata = { "v": self.apiver, "key": self.apikey, "login": self.user, "password": md5pass.hexdigest(), } try: # authentication request response = utilities.get_urldata(url, urldata, "POST") # authentication response data = json.loads(response) logger.info("successfully authenticated") except Exception: logger.error("failed to connect for authentication") return None # parse results if "token" in data: # get token self.token = str(data["token"]) # reset failure count self.failurecount = 0 # reset timer self.timercounter = 0 self.timerexpiretime = 0 if data["errors"]: self.__checkerrors(data["errors"][0], auth=True) return None else: logger.debug("token find:" + self.token) notification(getString(32010), getString(32008)) return True
def __init__(self, sync, progress): self.sync = sync if not self.sync.show_progress and self.sync.sync_on_update and self.sync.notify and self.sync.notify_during_playback: kodiUtilities.notification('%s %s' % (kodiUtilities.getString(32045), kodiUtilities.getString(32050)), kodiUtilities.getString(32061)) # Sync started if self.sync.show_progress and not self.sync.run_silent: progress.create("%s %s" % (kodiUtilities.getString(32045), kodiUtilities.getString(32050)), line1=" ", line2=" ", line3=" ") kodiShowsCollected, kodiShowsWatched = self.__kodiLoadShows() if not isinstance(kodiShowsCollected, list) and not kodiShowsCollected: logger.debug("[Episodes Sync] Kodi collected show list is empty, aborting tv show Sync.") if self.sync.show_progress and not self.sync.run_silent: progress.close() return if not isinstance(kodiShowsWatched, list) and not kodiShowsWatched: logger.debug("[Episodes Sync] Kodi watched show list is empty, aborting tv show Sync.") if self.sync.show_progress and not self.sync.run_silent: progress.close() return traktShowsCollected, traktShowsWatched, traktShowsRated, traktEpisodesRated = self.__traktLoadShows() if not traktShowsCollected: logger.debug("[Episodes Sync] Error getting Trakt.tv collected show list, aborting tv show sync.") if self.sync.show_progress and not self.sync.run_silent: progress.close() return if not traktShowsWatched: logger.debug("[Episodes Sync] Error getting Trakt.tv watched show list, aborting tv show sync.") if self.sync.show_progress and not self.sync.run_silent: progress.close() return traktShowsProgress = self.__traktLoadShowsPlaybackProgress(25, 36) self.__addEpisodesToTraktCollection(kodiShowsCollected, traktShowsCollected, 37, 47) self.__deleteEpisodesFromTraktCollection(traktShowsCollected, kodiShowsCollected, 48, 58) self.__addEpisodesToTraktWatched(kodiShowsWatched, traktShowsWatched, 59, 69) self.__addEpisodesToKodiWatched(traktShowsWatched, kodiShowsWatched, kodiShowsCollected, 70, 80) self.__addEpisodeProgressToKodi(traktShowsProgress, kodiShowsCollected, 81, 91) self.__syncShowsRatings(traktShowsRated, kodiShowsCollected, 92, 95) self.__syncEpisodeRatings(traktEpisodesRated, kodiShowsCollected, 96, 99) if not self.sync.show_progress and self.sync.sync_on_update and self.sync.notify and self.sync.notify_during_playback: kodiUtilities.notification('%s %s' % (kodiUtilities.getString(32045), kodiUtilities.getString(32050)), kodiUtilities.getString(32062)) # Sync complete if self.sync.show_progress and not self.sync.run_silent: self.sync.UpdateProgress(100, line1=" ", line2=kodiUtilities.getString(32075), line3=" ") progress.close() logger.debug("[Episodes Sync] Shows on Trakt.tv (%d), shows in Kodi (%d)." % (len(traktShowsCollected['shows']), len(kodiShowsCollected['shows']))) logger.debug("[Episodes Sync] Episodes on Trakt.tv (%d), episodes in Kodi (%d)." % (self.__countEpisodes(traktShowsCollected), self.__countEpisodes(kodiShowsCollected))) logger.debug("[Episodes Sync] Complete.")
def onFocus(self, controlID): if controlID in self.focus_labels: s = kodiUtilities.getString(self.focus_labels[controlID]) if self.rerate: if self.media['user']['ratings'] and self.media['user']['ratings']['rating'] == self.buttons[controlID]: if utilities.isMovie(self.media_type): s = kodiUtilities.getString(32037) elif utilities.isShow(self.media_type): s = kodiUtilities.getString(32038) elif utilities.isEpisode(self.media_type): s = kodiUtilities.getString(32039) elif utilities.isSeason(self.media_type): s = kodiUtilities.getString(32132) else: pass self.getControl(10013).setLabel(s) else: self.getControl(10013).setLabel('')
def __rateOnTrakt(rating, media_type, media, unrate=False): logger.debug("Sending rating (%s) to Trakt.tv" % rating) params = media if utilities.isMovie(media_type): key = 'movies' params['rating'] = rating if 'movieid' in media: kodiUtilities.kodiJsonRequest({"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.SetMovieDetails", "params": {"movieid": media['movieid'], "userrating": rating}}) elif utilities.isShow(media_type): key = 'shows' params['rating'] = rating if 'tvshowid' in media: kodiUtilities.kodiJsonRequest({"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.SetTVShowDetails", "params": {"tvshowid": media['tvshowid'], "userrating": rating}}) elif utilities.isSeason(media_type): key = 'shows' params['seasons'] = [{'rating': rating, 'number': media['season']}] elif utilities.isEpisode(media_type): key = 'episodes' params['rating'] = rating if 'episodeid' in media: kodiUtilities.kodiJsonRequest({"jsonrpc": "2.0", "id": 1, "method": "VideoLibrary.SetEpisodeDetails", "params": {"episodeid": media['episodeid'], "userrating": rating}}) else: return root = {key: [params]} if not unrate: data = globals.traktapi.addRating(root) else: data = globals.traktapi.removeRating(root) if data: s = utilities.getFormattedItemName(media_type, media) if 'not_found' in data and not data['not_found']['movies'] and not data['not_found']['episodes'] and not data['not_found']['shows']: if not unrate: kodiUtilities.notification(kodiUtilities.getString(32040), s) else: kodiUtilities.notification(kodiUtilities.getString(32042), s) else: kodiUtilities.notification(kodiUtilities.getString(32044), s)
def __traktLoadMovies(self): self.sync.UpdateProgress(10, line1=kodiUtilities.getString(32079), line2=kodiUtilities.getString(32081)) logger.debug("[Movies Sync] Getting movie collection from Trakt.tv") traktMovies = {} traktMovies = self.sync.traktapi.getMoviesCollected(traktMovies) self.sync.UpdateProgress(17, line2=kodiUtilities.getString(32082)) traktMovies = self.sync.traktapi.getMoviesWatched(traktMovies) traktMovies = self.sync.traktapi.getMoviesRated(traktMovies) traktMovies = list(traktMovies.items()) self.sync.UpdateProgress(24, line2=kodiUtilities.getString(32083)) movies = [] for _, movie in traktMovies: movie = movie.to_dict() movies.append(movie) return movies
def doAddToWatchlist(self, data): media_type = data['media_type'] if utilities.isMovie(media_type): summaryInfo = globals.traktapi.getMovieSummary(data['id']).to_dict() if summaryInfo: s = utilities.getFormattedItemName(media_type, summaryInfo) logger.debug("doAddToWatchlist(): '%s' trying to add to users watchlist." % s) params = {'movies': [summaryInfo]} logger.debug("doAddToWatchlist(): %s" % str(params)) result = globals.traktapi.addToWatchlist(params) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s) elif utilities.isEpisode(media_type): summaryInfo = {'shows': [{'ids': utilities.parseIdToTraktIds(data['id'], media_type)[0], 'seasons': [{'number': data['season'], 'episodes': [{'number':data['number']}]}]}]} logger.debug("doAddToWatchlist(): %s" % str(summaryInfo)) s = utilities.getFormattedItemName(media_type, data) result = globals.traktapi.addToWatchlist(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s) elif utilities.isSeason(media_type): summaryInfo = {'shows': [{'ids': utilities.parseIdToTraktIds(data['id'], media_type)[0], 'seasons': [{'number': data['season']}]}]} s = utilities.getFormattedItemName(media_type, data) logger.debug("doAddToWatchlist(): '%s - Season %d' trying to add to users watchlist." % (data['id'], data['season'])) result = globals.traktapi.addToWatchlist(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s) elif utilities.isShow(media_type): summaryInfo = {'shows': [{'ids': utilities.parseIdToTraktIds(data['id'], media_type)[0]}]} s = utilities.getFormattedItemName(media_type, data) logger.debug("doAddToWatchlist(): %s" % str(summaryInfo)) result = globals.traktapi.addToWatchlist(summaryInfo) if result: kodiUtilities.notification(kodiUtilities.getString(32165), s) else: kodiUtilities.notification(kodiUtilities.getString(32166), s)
def __addEpisodesToKodiWatched(self, traktShows, kodiShows, kodiShowsCollected, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('kodi_episode_playcount') and not self.sync.IsCanceled(): updateKodiTraktShows = copy.deepcopy(traktShows) updateKodiKodiShows = copy.deepcopy(kodiShows) kodiShowsUpdate = self.__compareEpisodes(updateKodiTraktShows, updateKodiKodiShows, watched=True, restrict=True, collected=kodiShowsCollected) if len(kodiShowsUpdate['shows']) == 0: self.sync.UpdateProgress(toPercent, line1=kodiUtilities.getString(32074), line2=kodiUtilities.getString(32107)) logger.debug("[Episodes Sync] Kodi episode playcounts are up to date.") return logger.debug("[Episodes Sync] %i show(s) shows are missing playcounts on Kodi" % len(kodiShowsUpdate['shows'])) for s in ["%s" % self.__getShowAsString(s, short=True) for s in kodiShowsUpdate['shows']]: logger.debug("[Episodes Sync] Episodes updated: %s" % s) # logger.debug("kodiShowsUpdate: %s" % kodiShowsUpdate) episodes = [] for show in kodiShowsUpdate['shows']: for season in show['seasons']: for episode in season['episodes']: episodes.append({'episodeid': episode['ids']['episodeid'], 'playcount': episode['plays'], "lastplayed": utilities.convertUtcToDateTime(episode['last_watched_at'])}) # split episode list into chunks of 50 chunksize = 50 chunked_episodes = utilities.chunks([{"jsonrpc": "2.0", "method": "VideoLibrary.SetEpisodeDetails", "params": episodes[i], "id": i} for i in range(len(episodes))], chunksize) i = 0 x = float(len(episodes)) for chunk in chunked_episodes: if self.sync.IsCanceled(): return i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line2=kodiUtilities.getString(32108) % ((i) * chunksize if (i) * chunksize < x else x, x)) logger.debug("[Episodes Sync] chunk %s" % str(chunk)) result = kodiUtilities.kodiJsonRequest(chunk) logger.debug("[Episodes Sync] result %s" % str(result)) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32109) % len(episodes))
def __addEpisodeProgressToKodi(self, traktShows, kodiShows, fromPercent, toPercent): if kodiUtilities.getSettingAsBool('trakt_episode_playback') and traktShows and not self.sync.IsCanceled(): updateKodiTraktShows = copy.deepcopy(traktShows) updateKodiKodiShows = copy.deepcopy(kodiShows) kodiShowsUpdate = utilities.compareEpisodes(updateKodiTraktShows, updateKodiKodiShows, kodiUtilities.getSettingAsBool( "scrobble_fallback"), restrict=True, playback=True) if len(kodiShowsUpdate['shows']) == 0: self.sync.UpdateProgress(toPercent, line1=kodiUtilities.getString(1441), line2=kodiUtilities.getString(32129)) logger.debug("[Episodes Sync] Kodi episode playbacks are up to date.") return logger.debug("[Episodes Sync] %i show(s) shows are missing playbacks on Kodi" % len(kodiShowsUpdate['shows'])) for s in ["%s" % self.__getShowAsString(s, short=True) for s in kodiShowsUpdate['shows']]: logger.debug("[Episodes Sync] Episodes updated: %s" % s) episodes = [] for show in kodiShowsUpdate['shows']: for season in show['seasons']: for episode in season['episodes']: episodes.append({'episodeid': episode['ids']['episodeid'], 'progress': episode['progress'], 'runtime': episode['runtime']}) # need to calculate the progress in int from progress in percent from Trakt # split episode list into chunks of 50 chunksize = 50 chunked_episodes = utilities.chunks([{"jsonrpc": "2.0", "id": i, "method": "VideoLibrary.SetEpisodeDetails", "params": {"episodeid":episodes[i]['episodeid'], "resume": {"position": episodes[i]['runtime'] / 100.0 * episodes[i]['progress'], "total": episodes[i]['runtime']}}} for i in range(len(episodes))], chunksize) i = 0 x = float(len(episodes)) for chunk in chunked_episodes: if self.sync.IsCanceled(): return i += 1 y = ((i / x) * (toPercent-fromPercent)) + fromPercent self.sync.UpdateProgress(int(y), line2=kodiUtilities.getString(32130) % ((i) * chunksize if (i) * chunksize < x else x, x)) kodiUtilities.kodiJsonRequest(chunk) self.sync.UpdateProgress(toPercent, line2=kodiUtilities.getString(32131) % len(episodes))
def onInit(self): mange_string = getString(32133) if isMovie(self.media_type) else getString(32134) rate_string = getString(32137) if isShow(self.media_type): rate_string = getString(32138) elif isSeason(self.media_type): rate_string = getString(32149) elif isEpisode(self.media_type): rate_string = getString(32139) actions = [mange_string, getString(32135), getString(32136), rate_string, getString(32140), getString(32141), getString(32142), getString(32143)] keys = ["itemlists", "removefromlist", "addtowatchlist", "rate", "togglewatched", "managelists", "updatetags", "sync"] l = self.getControl(ACTION_LIST) for i in range(len(actions)): if keys[i] in self.buttons: l.addItem(self.newListItem(actions[i], id=keys[i])) self.setFocus(l)
def __init__(self, sync, progress): self.sync = sync if not self.sync.show_progress and sync.sync_on_update and sync.notify and self.sync.notify_during_playback: kodiUtilities.notification('%s %s' % (kodiUtilities.getString(32045), kodiUtilities.getString(32046)), kodiUtilities.getString(32061)) # Sync started if sync.show_progress and not sync.run_silent: progress.create("%s %s" % (kodiUtilities.getString(32045), kodiUtilities.getString(32046)), line1=" ", line2=" ", line3=" ") kodiMovies = self.__kodiLoadMovies() if not isinstance(kodiMovies, list) and not kodiMovies: logger.debug("[Movies Sync] Kodi movie list is empty, aborting movie Sync.") if sync.show_progress and not sync.run_silent: progress.close() return try: traktMovies = self.__traktLoadMovies() except Exception: logger.debug("[Movies Sync] Error getting Trakt.tv movie list, aborting movie Sync.") if sync.show_progress and not sync.run_silent: progress.close() return traktMoviesProgress = self.__traktLoadMoviesPlaybackProgress(25, 36) self.__addMoviesToTraktCollection(kodiMovies, traktMovies, 37, 47) self.__deleteMoviesFromTraktCollection(traktMovies, kodiMovies, 48, 58) self.__addMoviesToTraktWatched(kodiMovies, traktMovies, 59, 69) self.__addMoviesToKodiWatched(traktMovies, kodiMovies, 70, 80) self.__addMovieProgressToKodi(traktMoviesProgress, kodiMovies, 81, 91) self.__syncMovieRatings(traktMovies, kodiMovies, 92, 99) if sync.show_progress and not sync.run_silent: self.sync.UpdateProgress(100, line1=kodiUtilities.getString(32066), line2=" ", line3=" ") progress.close() if not sync.show_progress and sync.sync_on_update and sync.notify and sync.notify_during_playback: kodiUtilities.notification('%s %s' % (kodiUtilities.getString(32045), kodiUtilities.getString(32046)), kodiUtilities.getString(32062)) # Sync complete logger.debug("[Movies Sync] Movies on Trakt.tv (%d), movies in Kodi (%d)." % (len(traktMovies), len(kodiMovies))) logger.debug("[Movies Sync] Complete.")