def __preFetchUserRatings(self, result): if result: if utilities.isMovie( self.curVideo['type']) and kodiUtilities.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 kodiUtilities.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 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 __scrobble(self, status): if not self.curVideoInfo: return logger.debug("scrobble()") scrobbleMovieOption = kodiUtilities.getSettingAsBool('scrobble_movie') scrobbleEpisodeOption = kodiUtilities.getSettingAsBool('scrobble_episode') watchedPercent = self.__calculateWatchedPercent() if utilities.isMovie(self.curVideo['type']) and scrobbleMovieOption: response = self.traktapi.scrobbleMovie(self.curVideoInfo, watchedPercent, status) if response is not None: self.__scrobbleNotification(response) logger.debug("Scrobble response: %s" % str(response)) return response else: logger.debug("Failed to scrobble movie: %s | %s | %s" % (self.curVideoInfo, watchedPercent, status)) 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 logger.debug("scrobble sending show object: %s" % str(self.traktShowSummary)) logger.debug("scrobble sending episode object: %s" % str(self.curVideoInfo)) response = self.traktapi.scrobbleEpisode(self.traktShowSummary, self.curVideoInfo, watchedPercent, status) if (kodiUtilities.getSettingAsBool('scrobble_secondary_title')): logger.debug('[traktPlayer] Setting is enabled to try secondary show title, if necessary.') # If there is an empty response, the reason might be that the title we have isn't the actual show title, # but rather an alternative title. To handle this case, call the Trakt search function. if response is None: logger.debug("Searching for show title: %s" % self.traktShowSummary['title']) # This text query API is basically the same as searching on the website. Works with alternative # titles, unlike the scrobble function. newResp = self.traktapi.getTextQuery(self.traktShowSummary['title'], "show", None) if not newResp: logger.debug("Empty Response from getTextQuery, giving up") else: logger.debug("Got Response from getTextQuery: %s" % str(newResp)) # We got something back. Have to assume the first show found is the right one; if there's more than # one, there's no way to know which to use. Pull the primary title from the response (and the year, # just because it's there). showObj = {'title': newResp[0].title, 'year': newResp[0].year} logger.debug("scrobble sending getTextQuery first show object: %s" % str(showObj)) # Now we can attempt the scrobble again, using the primary title this time. response = self.traktapi.scrobbleEpisode(showObj, self.curVideoInfo, watchedPercent, status) if response is not None: self.__scrobbleNotification(response) logger.debug("Scrobble response: %s" % str(response)) return response else: logger.debug("Failed to scrobble episode: %s | %s | %s | %s" % (self.traktShowSummary, self.curVideoInfo, watchedPercent, status))
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 __preFetchUserRatings(self, result): if result: if utilities.isMovie(self.curVideo['type']) and kodiUtilities.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 kodiUtilities.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 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 __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 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 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 __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 __scrobble(self, status): if not self.curVideoInfo: return logger.debug("scrobble()") scrobbleMovieOption = kodiUtilities.getSettingAsBool('scrobble_movie') scrobbleEpisodeOption = kodiUtilities.getSettingAsBool( 'scrobble_episode') watchedPercent = self.__calculateWatchedPercent() if utilities.isMovie(self.curVideo['type']) and scrobbleMovieOption: response = self.traktapi.scrobbleMovie(self.curVideoInfo, watchedPercent, status) if response is not None: self.__scrobbleNotification(response) logger.debug("Scrobble response: %s" % str(response)) return response else: logger.debug("Failed to scrobble movie: %s | %s | %s" % (self.curVideoInfo, watchedPercent, status)) 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 logger.debug("scrobble sending show object: %s" % str(self.traktShowSummary)) logger.debug("scrobble sending episode object: %s" % str(self.curVideoInfo)) response = self.traktapi.scrobbleEpisode(self.traktShowSummary, self.curVideoInfo, watchedPercent, status) if (kodiUtilities.getSettingAsBool('scrobble_secondary_title')): logger.debug( '[traktPlayer] Setting is enabled to try secondary show title, if necessary.' ) # If there is an empty response, the reason might be that the title we have isn't the actual show title, # but rather an alternative title. To handle this case, call the Trakt search function. if response is None: logger.debug("Searching for show title: %s" % self.traktShowSummary['title']) # This text query API is basically the same as searching on the website. Works with alternative # titles, unlike the scrobble function. newResp = self.traktapi.getTextQuery( self.traktShowSummary['title'], "show", None) if not newResp: logger.debug( "Empty Response from getTextQuery, giving up") else: logger.debug("Got Response from getTextQuery: %s" % str(newResp)) # We got something back. Have to assume the first show found is the right one; if there's more than # one, there's no way to know which to use. Pull the primary title from the response (and the year, # just because it's there). showObj = { 'title': newResp[0].title, 'year': newResp[0].year } logger.debug( "scrobble sending getTextQuery first show object: %s" % str(showObj)) # Now we can attempt the scrobble again, using the primary title this time. response = self.traktapi.scrobbleEpisode( showObj, self.curVideoInfo, watchedPercent, status) if response is not None: self.__scrobbleNotification(response) logger.debug("Scrobble response: %s" % str(response)) return response else: logger.debug("Failed to scrobble episode: %s | %s | %s | %s" % (self.traktShowSummary, self.curVideoInfo, watchedPercent, status))
def test_isEpisode(): assert utilities.isEpisode('episode')
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 doManualRating(self, data): action = data['action'] media_type = data['media_type'] summaryInfo = None if not utilities.isValidMediaType(media_type): logger.debug( "doManualRating(): Invalid media type '%s' passed for manual %s." % (media_type, action)) return if not data['action'] in ['rate', 'unrate']: logger.debug("doManualRating(): Unknown action passed.") return logger.debug( "Getting data for manual %s of %s: video_id: |%s| dbid: |%s|" % (action, media_type, data.get('video_id'), data.get('dbid'))) id_type = utilities.parseIdToTraktIds(str(data['video_id']), media_type)[1] if not id_type: logger.debug("doManualRating(): Unrecognized id_type: |%s|-|%s|." % (media_type, data['video_id'])) return ids = globals.traktapi.getIdLookup(data['video_id'], id_type) if not ids: logger.debug("doManualRating(): No Results for: |%s|-|%s|." % (media_type, data['video_id'])) return trakt_id = dict(ids[0].keys)['trakt'] if utilities.isEpisode(media_type): summaryInfo = globals.traktapi.getEpisodeSummary( trakt_id, data['season'], data['episode']) userInfo = globals.traktapi.getEpisodeRatingForUser( trakt_id, data['season'], data['episode'], 'trakt') elif utilities.isSeason(media_type): summaryInfo = globals.traktapi.getShowSummary(trakt_id) userInfo = globals.traktapi.getSeasonRatingForUser( trakt_id, data['season'], 'trakt') elif utilities.isShow(media_type): summaryInfo = globals.traktapi.getShowSummary(trakt_id) userInfo = globals.traktapi.getShowRatingForUser(trakt_id, 'trakt') elif utilities.isMovie(media_type): summaryInfo = globals.traktapi.getMovieSummary(trakt_id) userInfo = globals.traktapi.getMovieRatingForUser( trakt_id, 'trakt') if summaryInfo is not None: summaryInfo = summaryInfo.to_dict() summaryInfo['user'] = {'ratings': userInfo} if utilities.isEpisode(media_type): summaryInfo['season'] = data['season'] summaryInfo['number'] = data['episode'] summaryInfo['episodeid'] = data.get('dbid') elif utilities.isSeason(media_type): summaryInfo['season'] = data['season'] elif utilities.isMovie(media_type): summaryInfo['movieid'] = data.get('dbid') elif utilities.isShow(media_type): summaryInfo['tvshowid'] = data.get('dbid') if action == 'rate': if not 'rating' in data: rateMedia(media_type, [summaryInfo]) else: rateMedia(media_type, [summaryInfo], rating=data['rating']) elif action == 'unrate': rateMedia(media_type, [summaryInfo], unrate=True) else: logger.debug( "doManualRating(): Summary info was empty, possible problem retrieving data from Trakt.tv" )
def run(): args = __getArguments() data = {} if args['action'] == 'auth_info': data['action'] = 'auth_info' if args['action'] == 'contextmenu': buttons = [] media_type = kodiUtilities.getMediaType() if media_type in ['movie', 'show', 'season', 'episode']: buttons.append("rate") buttons.append("togglewatched") buttons.append("addtowatchlist") buttons.append("sync") contextMenu = traktContextMenu(media_type=media_type, buttons=buttons) contextMenu.doModal() _action = contextMenu.action del contextMenu if _action is None: return logger.debug("'%s' selected from trakt.tv action menu" % _action) args['action'] = _action if args['action'] == 'sync': data = {'action': 'manualSync', 'silent': False} if 'silent' in args: data['silent'] = (args['silent'].lower() == 'true') data['library'] = "all" if 'library' in args and args['library'] in ['episodes', 'movies']: data['library'] = args['library'] elif args['action'] in ['rate', 'unrate']: data = {'action': args['action']} media_type = None if 'media_type' in args and 'dbid' in args: media_type = args['media_type'] try: data['dbid'] = int(args['dbid']) except ValueError: logger.debug( "Manual %s triggered for library item, but DBID is invalid." % args['action']) return elif 'media_type' in args and 'remoteid' in args: media_type = args['media_type'] data['remoteid'] = args['remoteid'] try: data['season'] = int(args['season']) data['episode'] = int(args['episode']) except ValueError: logger.debug("Error parsing season or episode for manual %s" % args['action']) return except KeyError: pass else: media_type = kodiUtilities.getMediaType() if not utilities.isValidMediaType(media_type): logger.debug("Error, not in video library.") return data['dbid'] = int(xbmc.getInfoLabel('ListItem.DBID')) if media_type is None: logger.debug( "Manual %s triggered on an unsupported content container." % args['action']) elif utilities.isValidMediaType(media_type): data['media_type'] = media_type if 'dbid' in data: logger.debug("Manual %s of library '%s' with an ID of '%s'." % (args['action'], media_type, data['dbid'])) if utilities.isMovie(media_type): result = kodiUtilities.getMovieDetailsFromKodi( data['dbid'], ['imdbnumber', 'title', 'year']) if not result: logger.debug( "No data was returned from Kodi, aborting manual %s." % args['action']) return elif utilities.isShow(media_type): tvshow_id = data['dbid'] elif utilities.isSeason(media_type): result = kodiUtilities.getSeasonDetailsFromKodi( data['dbid'], ['tvshowid', 'season']) if not result: logger.debug( "No data was returned from Kodi, aborting manual %s." % args['action']) return tvshow_id = result['tvshowid'] data['season'] = result['season'] elif utilities.isEpisode(media_type): result = kodiUtilities.getEpisodeDetailsFromKodi( data['dbid'], ['season', 'episode', 'tvshowid']) if not result: logger.debug( "No data was returned from Kodi, aborting manual %s." % args['action']) return tvshow_id = result['tvshowid'] data['season'] = result['season'] data['episode'] = result['episode'] if utilities.isShow(media_type) or utilities.isSeason( media_type) or utilities.isEpisode(media_type): result = kodiUtilities.getShowDetailsFromKodi( tvshow_id, ['imdbnumber']) if not result: logger.debug( "No data was returned from Kodi, aborting manual %s." % args['action']) return data['video_id'] = result['imdbnumber'] else: data['video_id'] = data['remoteid'] if 'season' in data and 'episode' in data: logger.debug( "Manual %s of non-library '%s' S%02dE%02d, with an ID of '%s'." % (args['action'], media_type, data['season'], data['episode'], data['remoteid'])) elif 'season' in data: logger.debug( "Manual %s of non-library '%s' S%02d, with an ID of '%s'." % (args['action'], media_type, data['season'], data['remoteid'])) else: logger.debug( "Manual %s of non-library '%s' with an ID of '%s'." % (args['action'], media_type, data['remoteid'])) if args['action'] == 'rate' and 'rating' in args: if args['rating'] in [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10' ]: data['rating'] = int(args['rating']) data = {'action': 'manualRating', 'ratingData': data} else: logger.debug("Manual %s of '%s' is unsupported." % (args['action'], media_type)) elif args['action'] == 'togglewatched': media_type = kodiUtilities.getMediaType() if media_type in ['movie', 'show', 'season', 'episode']: data = {'media_type': media_type} if utilities.isMovie(media_type): dbid = int(xbmc.getInfoLabel('ListItem.DBID')) result = kodiUtilities.getMovieDetailsFromKodi( dbid, ['imdbnumber', 'title', 'year', 'playcount']) if result: if result['playcount'] == 0: data['id'] = result['imdbnumber'] else: logger.debug("Movie alread marked as watched in Kodi.") else: logger.debug("Error getting movie details from Kodi.") return elif utilities.isEpisode(media_type): dbid = int(xbmc.getInfoLabel('ListItem.DBID')) result = kodiUtilities.getEpisodeDetailsFromKodi( dbid, [ 'showtitle', 'season', 'episode', 'tvshowid', 'playcount' ]) if result: if result['playcount'] == 0: data['id'] = result['imdbnumber'] data['season'] = result['season'] data['number'] = result['episode'] data['title'] = result['showtitle'] else: logger.debug( "Episode already marked as watched in Kodi.") else: logger.debug("Error getting episode details from Kodi.") return elif utilities.isSeason(media_type): showID = None showTitle = xbmc.getInfoLabel('ListItem.TVShowTitle') result = kodiUtilities.kodiJsonRequest({ 'jsonrpc': '2.0', 'method': 'VideoLibrary.GetTVShows', 'params': { 'properties': ['title', 'imdbnumber', 'year'] }, 'id': 0 }) if result and 'tvshows' in result: for show in result['tvshows']: if show['title'] == showTitle: showID = show['tvshowid'] data['id'] = show['imdbnumber'] data['title'] = show['title'] break else: logger.debug("Error getting TV shows from Kodi.") return season = xbmc.getInfoLabel('ListItem.Season') if season == "": season = 0 else: season = int(season) result = kodiUtilities.kodiJsonRequest({ 'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': { 'tvshowid': showID, 'season': season, 'properties': ['season', 'episode', 'playcount'] }, 'id': 0 }) if result and 'episodes' in result: episodes = [] for episode in result['episodes']: if episode['playcount'] == 0: episodes.append(episode['episode']) if len(episodes) == 0: logger.debug( "'%s - Season %d' is already marked as watched." % (showTitle, season)) return data['season'] = season data['episodes'] = episodes else: logger.debug( "Error getting episodes from '%s' for Season %d" % (showTitle, season)) return elif utilities.isShow(media_type): dbid = int(xbmc.getInfoLabel('ListItem.DBID')) result = kodiUtilities.getShowDetailsFromKodi( dbid, ['year', 'imdbnumber']) if not result: logger.debug("Error getting show details from Kodi.") return showTitle = result['label'] data['id'] = result['imdbnumber'] result = kodiUtilities.kodiJsonRequest({ 'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': { 'tvshowid': dbid, 'properties': ['season', 'episode', 'playcount', 'showtitle'] }, 'id': 0 }) if result and 'episodes' in result: i = 0 s = {} for e in result['episodes']: data['title'] = e['showtitle'] season = str(e['season']) if not season in s: s[season] = [] if e['playcount'] == 0: s[season].append(e['episode']) i += 1 if i == 0: logger.debug("'%s' is already marked as watched." % showTitle) return data['seasons'] = dict( (k, v) for k, v in s.iteritems() if v) else: logger.debug( "Error getting episode details for '%s' from Kodi." % showTitle) return if len(data) > 1: logger.debug( "Marking '%s' with the following data '%s' as watched on Trakt.tv" % (media_type, str(data))) data['action'] = 'markWatched' # execute toggle watched action xbmc.executebuiltin("Action(ToggleWatched)") elif args['action'] == 'addtowatchlist': media_type = kodiUtilities.getMediaType() if media_type in ['movie', 'show', 'season', 'episode']: data = {'media_type': media_type} if utilities.isMovie(media_type): dbid = int(xbmc.getInfoLabel('ListItem.DBID')) result = kodiUtilities.getMovieDetailsFromKodi( dbid, ['imdbnumber', 'title', 'year', 'playcount']) if result: data['id'] = result['imdbnumber'] else: logger.debug("Error getting movie details from Kodi.") return elif utilities.isEpisode(media_type): dbid = int(xbmc.getInfoLabel('ListItem.DBID')) result = kodiUtilities.getEpisodeDetailsFromKodi( dbid, [ 'showtitle', 'season', 'episode', 'tvshowid', 'playcount' ]) if result: data['id'] = result['imdbnumber'] data['season'] = result['season'] data['number'] = result['episode'] data['title'] = result['showtitle'] else: logger.debug("Error getting episode details from Kodi.") return elif utilities.isSeason(media_type): showID = None showTitle = xbmc.getInfoLabel('ListItem.TVShowTitle') result = kodiUtilities.kodiJsonRequest({ 'jsonrpc': '2.0', 'method': 'VideoLibrary.GetTVShows', 'params': { 'properties': ['title', 'imdbnumber', 'year'] }, 'id': 0 }) if result and 'tvshows' in result: for show in result['tvshows']: if show['title'] == showTitle: showID = show['tvshowid'] data['id'] = show['imdbnumber'] data['title'] = show['title'] break else: logger.debug("Error getting TV shows from Kodi.") return season = xbmc.getInfoLabel('ListItem.Season') if season == "": season = 0 else: season = int(season) result = kodiUtilities.kodiJsonRequest({ 'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': { 'tvshowid': showID, 'season': season, 'properties': ['season', 'episode', 'playcount'] }, 'id': 0 }) if result and 'episodes' in result: episodes = [] for episode in result['episodes']: if episode['playcount'] == 0: episodes.append(episode['episode']) data['season'] = season data['episodes'] = episodes else: logger.debug( "Error getting episodes from '%s' for Season %d" % (showTitle, season)) return elif utilities.isShow(media_type): dbid = int(xbmc.getInfoLabel('ListItem.DBID')) result = kodiUtilities.getShowDetailsFromKodi( dbid, ['year', 'imdbnumber']) if not result: logger.debug("Error getting show details from Kodi.") return showTitle = result['label'] data['id'] = result['imdbnumber'] result = kodiUtilities.kodiJsonRequest({ 'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': { 'tvshowid': dbid, 'properties': ['season', 'episode', 'playcount', 'showtitle'] }, 'id': 0 }) if result and 'episodes' in result: s = {} for e in result['episodes']: data['title'] = e['showtitle'] season = str(e['season']) if not season in s: s[season] = [] if e['playcount'] == 0: s[season].append(e['episode']) data['seasons'] = dict( (k, v) for k, v in s.iteritems() if v) else: logger.debug( "Error getting episode details for '%s' from Kodi." % showTitle) return if len(data) > 1: logger.debug( "Adding '%s' with the following data '%s' to users watchlist on Trakt.tv" % (media_type, str(data))) data['action'] = 'addtowatchlist' q = sqlitequeue.SqliteQueue() if 'action' in data: logger.debug("Queuing for dispatch: %s" % data) q.append(data)
def playbackStarted(self, data): logger.debug("playbackStarted(data: %s)" % data) if not data: return self.curVideo = data self.curVideoInfo = None self.videosToRate = [] if not kodiUtilities.getSettingAsBool( 'scrobble_fallback' ) and 'id' not in self.curVideo and 'video_ids' not in self.curVideo: logger.debug('Aborting scrobble to avoid fallback: %s' % (self.curVideo)) return if 'type' in self.curVideo: logger.debug("Watching: %s" % self.curVideo['type']) if not xbmc.Player().isPlayingVideo(): logger.debug("Suddenly stopped watching item") return xbmc.sleep( 1000) # Wait for possible silent seek (caused by resuming) try: self.watchedTime = xbmc.Player().getTime() self.videoDuration = xbmc.Player().getTotalTime() except Exception as e: logger.debug("Suddenly stopped watching item: %s" % e.message) self.curVideo = None return if self.videoDuration == 0: if utilities.isMovie(self.curVideo['type']): self.videoDuration = 90 elif utilities.isEpisode(self.curVideo['type']): self.videoDuration = 30 else: self.videoDuration = 1 self.playlistIndex = xbmc.PlayList( xbmc.PLAYLIST_VIDEO).getposition() self.isMultiPartEpisode = False if utilities.isMovie(self.curVideo['type']): if 'id' in self.curVideo: self.curVideoInfo = kodiUtilities.kodiRpcToTraktMediaObject( 'movie', kodiUtilities.getMovieDetailsFromKodi( self.curVideo['id'], [ 'uniqueid', 'title', 'year', 'file', 'lastplayed', 'playcount' ])) elif 'video_ids' in self.curVideo: self.curVideoInfo = {'ids': self.curVideo['video_ids']} elif 'title' in self.curVideo and 'year' in self.curVideo: self.curVideoInfo = { 'title': self.curVideo['title'], 'year': self.curVideo['year'] } else: logger.debug("Couldn't set curVideoInfo for movie type") logger.debug("Movie type, curVideoInfo: %s" % self.curVideoInfo) elif utilities.isEpisode(self.curVideo['type']): if 'id' in self.curVideo: episodeDetailsKodi = kodiUtilities.getEpisodeDetailsFromKodi( self.curVideo['id'], [ 'showtitle', 'season', 'episode', 'tvshowid', 'uniqueid', 'file', 'playcount' ]) title, year = utilities.regex_year( episodeDetailsKodi['showtitle']) if not year: self.traktShowSummary = { 'title': episodeDetailsKodi['showtitle'], 'year': episodeDetailsKodi['year'] } else: self.traktShowSummary = {'title': title, 'year': year} if 'show_ids' in episodeDetailsKodi: self.traktShowSummary['ids'] = episodeDetailsKodi[ 'show_ids'] self.curVideoInfo = kodiUtilities.kodiRpcToTraktMediaObject( 'episode', episodeDetailsKodi) if not self.curVideoInfo: # getEpisodeDetailsFromKodi was empty logger.debug( "Episode details from Kodi was empty, ID (%d) seems invalid, aborting further scrobbling of this episode." % self.curVideo['id']) self.curVideo = None self.isPlaying = False self.watchedTime = 0 return elif 'video_ids' in self.curVideo and 'season' in self.curVideo and 'episode' in self.curVideo: self.curVideoInfo = { 'season': self.curVideo['season'], 'number': self.curVideo['episode'] } self.traktShowSummary = {'ids': self.curVideo['video_ids']} elif 'title' in self.curVideo and 'season' in self.curVideo and 'episode' in self.curVideo: self.curVideoInfo = { 'title': self.curVideo['title'], 'season': self.curVideo['season'], 'number': self.curVideo['episode'] } title, year = utilities.regex_year( self.curVideo['showtitle']) if not year: self.traktShowSummary = { 'title': self.curVideo['showtitle'] } else: self.traktShowSummary = {'title': title, 'year': year} if 'year' in self.curVideo: self.traktShowSummary['year'] = self.curVideo['year'] else: logger.debug( "Couldn't set curVideoInfo/traktShowSummary for episode type" ) if 'multi_episode_count' in self.curVideo and self.curVideo[ 'multi_episode_count'] > 1: self.isMultiPartEpisode = True logger.debug("Episode type, curVideoInfo: %s" % self.curVideoInfo) logger.debug("Episode type, traktShowSummary: %s" % self.traktShowSummary) self.isPlaying = True self.isPaused = False result = {} if kodiUtilities.getSettingAsBool( 'scrobble_movie') or kodiUtilities.getSettingAsBool( 'scrobble_episode'): result = self.__scrobble('start') elif kodiUtilities.getSettingAsBool( 'rate_movie') and utilities.isMovie( self.curVideo['type']) and 'ids' in self.curVideoInfo: best_id = utilities.best_id(self.curVideoInfo['ids']) result = { 'movie': self.traktapi.getMovieSummary(best_id).to_dict() } elif kodiUtilities.getSettingAsBool( 'rate_episode') and utilities.isEpisode( self.curVideo['type'] ) and 'ids' in self.traktShowSummary: best_id = utilities.best_id(self.traktShowSummary['ids']) result = { 'show': self.traktapi.getShowSummary(best_id).to_dict(), 'episode': self.traktapi.getEpisodeSummary( best_id, self.curVideoInfo['season'], self.curVideoInfo['number']).to_dict() } result['episode']['season'] = self.curVideoInfo['season'] if 'id' in self.curVideo: if utilities.isMovie(self.curVideo['type']): result['movie']['movieid'] = self.curVideo['id'] elif utilities.isEpisode(self.curVideo['type']): result['episode']['episodeid'] = self.curVideo['id'] self.__preFetchUserRatings(result)
def playbackStarted(self, data): logger.debug("playbackStarted(data: %s)" % data) if not data: return self.curVideo = data self.curVideoInfo = None self.videosToRate = [] if not kodiUtilities.getSettingAsBool('scrobble_fallback') and 'id' not in self.curVideo and 'video_ids' not in self.curVideo: logger.debug('Aborting scrobble to avoid fallback: %s' % (self.curVideo)) return if 'type' in self.curVideo: logger.debug("Watching: %s" % self.curVideo['type']) if not xbmc.Player().isPlayingVideo(): logger.debug("Suddenly stopped watching item") return xbmc.sleep(1000) # Wait for possible silent seek (caused by resuming) try: self.watchedTime = xbmc.Player().getTime() self.videoDuration = xbmc.Player().getTotalTime() except Exception as e: logger.debug("Suddenly stopped watching item: %s" % e.message) self.curVideo = None return if self.videoDuration == 0: if utilities.isMovie(self.curVideo['type']): self.videoDuration = 90 elif utilities.isEpisode(self.curVideo['type']): self.videoDuration = 30 else: self.videoDuration = 1 self.playlistLength = len(xbmc.PlayList(xbmc.PLAYLIST_VIDEO)) self.playlistIndex = xbmc.PlayList(xbmc.PLAYLIST_VIDEO).getposition() if self.playlistLength == 0: logger.debug("Warning: Cant find playlist length, assuming that this item is by itself") self.playlistLength = 1 self.isMultiPartEpisode = False if utilities.isMovie(self.curVideo['type']): if 'id' in self.curVideo: self.curVideoInfo = kodiUtilities.kodiRpcToTraktMediaObject('movie', kodiUtilities.getMovieDetailsFromKodi(self.curVideo['id'], ['imdbnumber', 'title', 'year', 'file', 'lastplayed', 'playcount'])) elif 'video_ids' in self.curVideo: self.curVideoInfo = {'ids': self.curVideo['video_ids']} elif 'title' in self.curVideo and 'year' in self.curVideo: self.curVideoInfo = {'title': self.curVideo['title'], 'year': self.curVideo['year']} else: logger.debug("Couldn't set curVideoInfo for movie type") logger.debug("Movie type, curVideoInfo: %s" % self.curVideoInfo) elif utilities.isEpisode(self.curVideo['type']): if 'id' in self.curVideo: episodeDetailsKodi = kodiUtilities.getEpisodeDetailsFromKodi(self.curVideo['id'], ['showtitle', 'season', 'episode', 'tvshowid', 'uniqueid', 'file', 'playcount']) tvdb = episodeDetailsKodi['imdbnumber'] title, year = utilities.regex_year(episodeDetailsKodi['showtitle']) if not year: self.traktShowSummary = {'title': episodeDetailsKodi['showtitle'], 'year': episodeDetailsKodi['year']} else: self.traktShowSummary = {'title': title, 'year': year} if tvdb: self.traktShowSummary['ids'] = {'tvdb': tvdb} self.curVideoInfo = kodiUtilities.kodiRpcToTraktMediaObject('episode', episodeDetailsKodi) if not self.curVideoInfo: # getEpisodeDetailsFromKodi was empty logger.debug("Episode details from Kodi was empty, ID (%d) seems invalid, aborting further scrobbling of this episode." % self.curVideo['id']) self.curVideo = None self.isPlaying = False self.watchedTime = 0 return elif 'video_ids' in self.curVideo and 'season' in self.curVideo and 'episode' in self.curVideo: self.curVideoInfo = {'season': self.curVideo['season'], 'number': self.curVideo['episode']} self.traktShowSummary = {'ids': self.curVideo['video_ids']} elif 'title' in self.curVideo and 'season' in self.curVideo and 'episode' in self.curVideo: self.curVideoInfo = {'title': self.curVideo['title'], 'season': self.curVideo['season'], 'number': self.curVideo['episode']} title, year = utilities.regex_year(self.curVideo['showtitle']) if not year: self.traktShowSummary = {'title': self.curVideo['showtitle']} else: self.traktShowSummary = {'title': title, 'year': year} if 'year' in self.curVideo: self.traktShowSummary['year'] = self.curVideo['year'] else: logger.debug("Couldn't set curVideoInfo/traktShowSummary for episode type") if 'multi_episode_count' in self.curVideo and self.curVideo['multi_episode_count'] > 1: self.isMultiPartEpisode = True logger.debug("Episode type, curVideoInfo: %s" % self.curVideoInfo) logger.debug("Episode type, traktShowSummary: %s" % self.traktShowSummary) self.isPlaying = True self.isPaused = False result = {} if kodiUtilities.getSettingAsBool('scrobble_movie') or kodiUtilities.getSettingAsBool('scrobble_episode'): result = self.__scrobble('start') elif kodiUtilities.getSettingAsBool('rate_movie') and utilities.isMovie(self.curVideo['type']) and 'ids' in self.curVideoInfo: best_id = utilities.best_id(self.curVideoInfo['ids']) result = {'movie': self.traktapi.getMovieSummary(best_id).to_dict()} elif kodiUtilities.getSettingAsBool('rate_episode') and utilities.isEpisode(self.curVideo['type']) and 'ids' in self.traktShowSummary: best_id = utilities.best_id(self.traktShowSummary['ids']) result = {'show': self.traktapi.getShowSummary(best_id).to_dict(), 'episode': self.traktapi.getEpisodeSummary(best_id, self.curVideoInfo['season'], self.curVideoInfo['number']).to_dict()} result['episode']['season'] = self.curVideoInfo['season'] if 'id' in self.curVideo: if utilities.isMovie(self.curVideo['type']): result['movie']['movieid'] = self.curVideo['id'] elif utilities.isEpisode(self.curVideo['type']): result['episode']['episodeid'] = self.curVideo['id'] self.__preFetchUserRatings(result)
def run(): args = __getArguments() data = {} if args['action'] == 'auth_info': data['action'] = 'auth_info' if args['action'] == 'contextmenu': buttons = [] media_type = kodiUtilities.getMediaType() if media_type in ['movie', 'show', 'season', 'episode']: buttons.append("rate") buttons.append("togglewatched") buttons.append("addtowatchlist") buttons.append("sync") contextMenu = traktContextMenu(media_type=media_type, buttons=buttons) contextMenu.doModal() _action = contextMenu.action del contextMenu if _action is None: return logger.debug("'%s' selected from trakt.tv action menu" % _action) args['action'] = _action if args['action'] == 'sync': data = {'action': 'manualSync', 'silent': False} if 'silent' in args: data['silent'] = (args['silent'].lower() == 'true') data['library'] = "all" if 'library' in args and args['library'] in ['episodes', 'movies']: data['library'] = args['library'] elif args['action'] in ['rate', 'unrate']: data = {'action': args['action']} media_type = None if 'media_type' in args and 'dbid' in args: media_type = args['media_type'] try: data['dbid'] = int(args['dbid']) except ValueError: logger.debug("Manual %s triggered for library item, but DBID is invalid." % args['action']) return elif 'media_type' in args and 'remoteid' in args: media_type = args['media_type'] data['remoteid'] = args['remoteid'] try: data['season'] = int(args['season']) data['episode'] = int(args['episode']) except ValueError: logger.debug("Error parsing season or episode for manual %s" % args['action']) return except KeyError: pass else: media_type = kodiUtilities.getMediaType() if not utilities.isValidMediaType(media_type): logger.debug("Error, not in video library.") return data['dbid'] = int(xbmc.getInfoLabel('ListItem.DBID')) if media_type is None: logger.debug("Manual %s triggered on an unsupported content container." % args['action']) elif utilities.isValidMediaType(media_type): data['media_type'] = media_type if 'dbid' in data: logger.debug("Manual %s of library '%s' with an ID of '%s'." % (args['action'], media_type, data['dbid'])) if utilities.isMovie(media_type): result = kodiUtilities.getMovieDetailsFromKodi(data['dbid'], ['imdbnumber', 'uniqueid', 'title', 'year']) if not result: logger.debug("No data was returned from Kodi, aborting manual %s." % args['action']) return elif utilities.isShow(media_type): tvshow_id = data['dbid'] elif utilities.isSeason(media_type): result = kodiUtilities.getSeasonDetailsFromKodi(data['dbid'], ['tvshowid', 'season']) if not result: logger.debug("No data was returned from Kodi, aborting manual %s." % args['action']) return tvshow_id = result['tvshowid'] data['season'] = result['season'] elif utilities.isEpisode(media_type): result = kodiUtilities.getEpisodeDetailsFromKodi(data['dbid'], ['season', 'episode', 'tvshowid']) if not result: logger.debug("No data was returned from Kodi, aborting manual %s." % args['action']) return tvshow_id = result['tvshowid'] data['season'] = result['season'] data['episode'] = result['episode'] if utilities.isShow(media_type) or utilities.isSeason(media_type) or utilities.isEpisode(media_type): result = kodiUtilities.getShowDetailsFromKodi(tvshow_id, ['imdbnumber', 'uniqueid']) if not result: logger.debug("No data was returned from Kodi, aborting manual %s." % args['action']) return data['video_id'] = result['imdbnumber'] else: data['video_id'] = data['remoteid'] if 'season' in data and 'episode' in data: logger.debug("Manual %s of non-library '%s' S%02dE%02d, with an ID of '%s'." % (args['action'], media_type, data['season'], data['episode'], data['remoteid'])) elif 'season' in data: logger.debug("Manual %s of non-library '%s' S%02d, with an ID of '%s'." % (args['action'], media_type, data['season'], data['remoteid'])) else: logger.debug("Manual %s of non-library '%s' with an ID of '%s'." % (args['action'], media_type, data['remoteid'])) if args['action'] == 'rate' and 'rating' in args: if args['rating'] in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']: data['rating'] = int(args['rating']) data = {'action': 'manualRating', 'ratingData': data} else: logger.debug("Manual %s of '%s' is unsupported." % (args['action'], media_type)) elif args['action'] == 'togglewatched': media_type = kodiUtilities.getMediaType() if media_type in ['movie', 'show', 'season', 'episode']: data = {'media_type': media_type} if utilities.isMovie(media_type): dbid = int(xbmc.getInfoLabel('ListItem.DBID')) result = kodiUtilities.getMovieDetailsFromKodi(dbid, ['imdbnumber', 'title', 'year', 'playcount']) if result: if result['playcount'] == 0: data['id'] = result['imdbnumber'] else: logger.debug("Movie alread marked as watched in Kodi.") else: logger.debug("Error getting movie details from Kodi.") return elif utilities.isEpisode(media_type): dbid = int(xbmc.getInfoLabel('ListItem.DBID')) result = kodiUtilities.getEpisodeDetailsFromKodi(dbid, ['showtitle', 'season', 'episode', 'tvshowid', 'playcount']) if result: if result['playcount'] == 0: data['id'] = result['imdbnumber'] data['season'] = result['season'] data['number'] = result['episode'] data['title'] = result['showtitle'] else: logger.debug("Episode already marked as watched in Kodi.") else: logger.debug("Error getting episode details from Kodi.") return elif utilities.isSeason(media_type): showID = None showTitle = xbmc.getInfoLabel('ListItem.TVShowTitle') result = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetTVShows', 'params': {'properties': ['title', 'imdbnumber', 'year']}, 'id': 0}) if result and 'tvshows' in result: for show in result['tvshows']: if show['title'] == showTitle: showID = show['tvshowid'] data['id'] = show['imdbnumber'] data['title'] = show['title'] break else: logger.debug("Error getting TV shows from Kodi.") return season = xbmc.getInfoLabel('ListItem.Season') if season == "": season = 0 else: season = int(season) result = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': {'tvshowid': showID, 'season': season, 'properties': ['season', 'episode', 'playcount']}, 'id': 0}) if result and 'episodes' in result: episodes = [] for episode in result['episodes']: if episode['playcount'] == 0: episodes.append(episode['episode']) if len(episodes) == 0: logger.debug("'%s - Season %d' is already marked as watched." % (showTitle, season)) return data['season'] = season data['episodes'] = episodes else: logger.debug("Error getting episodes from '%s' for Season %d" % (showTitle, season)) return elif utilities.isShow(media_type): dbid = int(xbmc.getInfoLabel('ListItem.DBID')) result = kodiUtilities.getShowDetailsFromKodi(dbid, ['year', 'imdbnumber', 'uniqueid']) if not result: logger.debug("Error getting show details from Kodi.") return showTitle = result['label'] data['id'] = result['imdbnumber'] result = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': {'tvshowid': dbid, 'properties': ['season', 'episode', 'playcount', 'showtitle']}, 'id': 0}) if result and 'episodes' in result: i = 0 s = {} for e in result['episodes']: data['title'] = e['showtitle'] season = str(e['season']) if not season in s: s[season] = [] if e['playcount'] == 0: s[season].append(e['episode']) i += 1 if i == 0: logger.debug("'%s' is already marked as watched." % showTitle) return data['seasons'] = dict((k, v) for k, v in list(s.items()) if v) else: logger.debug("Error getting episode details for '%s' from Kodi." % showTitle) return if len(data) > 1: logger.debug("Marking '%s' with the following data '%s' as watched on Trakt.tv" % (media_type, str(data))) data['action'] = 'markWatched' # execute toggle watched action xbmc.executebuiltin("Action(ToggleWatched)") elif args['action'] == 'addtowatchlist': media_type = kodiUtilities.getMediaType() if media_type in ['movie', 'show', 'season', 'episode']: data = {'media_type': media_type} if utilities.isMovie(media_type): dbid = int(xbmc.getInfoLabel('ListItem.DBID')) result = kodiUtilities.getMovieDetailsFromKodi(dbid, ['imdbnumber', 'title', 'year', 'playcount']) if result: data['id'] = result['imdbnumber'] else: logger.debug("Error getting movie details from Kodi.") return elif utilities.isEpisode(media_type): dbid = int(xbmc.getInfoLabel('ListItem.DBID')) result = kodiUtilities.getEpisodeDetailsFromKodi(dbid, ['showtitle', 'season', 'episode', 'tvshowid', 'playcount']) if result: data['id'] = result['imdbnumber'] data['season'] = result['season'] data['number'] = result['episode'] data['title'] = result['showtitle'] else: logger.debug("Error getting episode details from Kodi.") return elif utilities.isSeason(media_type): showID = None showTitle = xbmc.getInfoLabel('ListItem.TVShowTitle') result = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetTVShows', 'params': {'properties': ['title', 'imdbnumber', 'year']}, 'id': 0}) if result and 'tvshows' in result: for show in result['tvshows']: if show['title'] == showTitle: showID = show['tvshowid'] data['id'] = show['imdbnumber'] data['title'] = show['title'] break else: logger.debug("Error getting TV shows from Kodi.") return season = xbmc.getInfoLabel('ListItem.Season') if season == "": season = 0 else: season = int(season) result = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': {'tvshowid': showID, 'season': season, 'properties': ['season', 'episode', 'playcount']}, 'id': 0}) if result and 'episodes' in result: episodes = [] for episode in result['episodes']: if episode['playcount'] == 0: episodes.append(episode['episode']) data['season'] = season data['episodes'] = episodes else: logger.debug("Error getting episodes from '%s' for Season %d" % (showTitle, season)) return elif utilities.isShow(media_type): dbid = int(xbmc.getInfoLabel('ListItem.DBID')) result = kodiUtilities.getShowDetailsFromKodi(dbid, ['year', 'imdbnumber', 'uniqueid']) if not result: logger.debug("Error getting show details from Kodi.") return showTitle = result['label'] data['id'] = result['imdbnumber'] result = kodiUtilities.kodiJsonRequest({'jsonrpc': '2.0', 'method': 'VideoLibrary.GetEpisodes', 'params': {'tvshowid': dbid, 'properties': ['season', 'episode', 'playcount', 'showtitle']}, 'id': 0}) if result and 'episodes' in result: s = {} for e in result['episodes']: data['title'] = e['showtitle'] season = str(e['season']) if not season in s: s[season] = [] if e['playcount'] == 0: s[season].append(e['episode']) data['seasons'] = dict((k, v) for k, v in list(s.items()) if v) else: logger.debug("Error getting episode details for '%s' from Kodi." % showTitle) return if len(data) > 1: logger.debug("Adding '%s' with the following data '%s' to users watchlist on Trakt.tv" % (media_type, str(data))) data['action'] = 'addtowatchlist' q = sqlitequeue.SqliteQueue() if 'action' in data: logger.debug("Queuing for dispatch: %s" % data) q.append(data)
def transitionCheck(self, isSeek=False): if not xbmc.Player().isPlayingVideo(): return if self.isPlaying: t = xbmc.Player().getTime() l = xbmc.PlayList(xbmc.PLAYLIST_VIDEO).getposition() if self.isPVR: if self.stopScrobbler: self.stopScrobbler = False self.lastMPCheck = time.time( ) + 600 #10min transition sleep self.__scrobble('stop') return self.watchedTime = (utilities._to_sec( xbmc.getInfoLabel('PVR.EpgEventElapsedTime(hh:mm:ss)'))) self.videoDuration = int( utilities._to_sec( xbmc.getInfoLabel('PVR.EpgEventDuration(hh:mm:ss)'))) elif self.playlistIndex == l: self.watchedTime = t else: logger.debug( "Current playlist item changed! Not updating time! (%d -> %d)" % (self.playlistIndex, l)) # do transition check every minute if (time.time() > (self.lastMPCheck + 60)) or isSeek: self.lastMPCheck = time.time() watchedPercent = self.__calculateWatchedPercent() if 'id' in self.curVideo and self.isMultiPartEpisode: epIndex = self._currentEpisode( watchedPercent, self.curVideo['multi_episode_count']) if self.curMPEpisode != epIndex: response = self.__scrobble('stop') if response is not None: logger.debug("Scrobble response: %s" % str(response)) self.videosToRate.append(self.curVideoInfo) # update current information self.curMPEpisode = epIndex self.curVideoInfo = kodiUtilities.kodiRpcToTraktMediaObject( 'episode', kodiUtilities.getEpisodeDetailsFromKodi( self.curVideo['multi_episode_data'][ self.curMPEpisode], [ 'showtitle', 'season', 'episode', 'tvshowid', 'uniqueid', 'file', 'playcount' ])) logger.debug( "Multi episode transition - call start for next episode" ) response = self.__scrobble('start') self.__preFetchUserRatings(response) elif self.isPVR: activePlayers = kodiUtilities.kodiJsonRequest({ "jsonrpc": "2.0", "method": "Player.GetActivePlayers", "id": 1 }) logger.debug("Scrobble - activePlayers: %s" % activePlayers) playerId = int(activePlayers[0]['playerid']) logger.debug( "Scrobble - Doing Player.GetItem kodiJsonRequest") result = kodiUtilities.kodiJsonRequest({ 'jsonrpc': '2.0', 'method': 'Player.GetItem', 'params': { 'playerid': playerId }, 'id': 1 }) if result: logger.debug("Scrobble - %s" % result) type, curVideo = kodiUtilities.getInfoLabelDetails( result) if curVideo != self.curVideo: response = self.__scrobble('stop') if response is not None: logger.debug("Scrobble response: %s" % str(response)) logger.debug("Scrobble PVR transition") # update current information self.curVideo = curVideo if utilities.isMovie(self.curVideo['type']): if 'title' in self.curVideo and 'year' in self.curVideo: self.curVideoInfo = { 'title': self.curVideo['title'], 'year': self.curVideo['year'] } else: logger.debug( "Scrobble Couldn't set curVideoInfo for movie type" ) logger.debug( "Scrobble Movie type, curVideoInfo: %s" % self.curVideoInfo) elif utilities.isEpisode( self.curVideo['type']): if 'title' in self.curVideo and 'season' in self.curVideo and 'episode' in self.curVideo: self.curVideoInfo = { 'title': self.curVideo['title'], 'season': self.curVideo['season'], 'number': self.curVideo['episode'] } title, year = utilities.regex_year( self.curVideo['showtitle']) if not year: self.traktShowSummary = { 'title': self.curVideo['showtitle'] } else: self.traktShowSummary = { 'title': title, 'year': year } if 'year' in self.curVideo: self.traktShowSummary[ 'year'] = self.curVideo['year'] else: logger.debug( "Scrobble Couldn't set curVideoInfo/traktShowSummary for episode type" ) logger.debug( "Scrobble Episode type, curVideoInfo: %s" % self.curVideoInfo) logger.debug( "Scrobble Episode type, traktShowSummary: %s" % self.traktShowSummary) response = self.__scrobble('start') elif isSeek: self.__scrobble('start')
def onNotification(self, sender, method, data): if sender == "xbmc": if method == "VideoLibrary.OnScanFinished": if self.service.update: self.ScanBSMarkedEpisode() elif method == "Player.OnPlay": result = json.loads(data) logger.debug("OnPlay: " + str(result)) if "item" in result: if utilities.isEpisode( result["item"]["type"]) or utilities.isMovie( result["item"]["type"]): # in case Player.OnPlay comes to fast after Player.OnStop xbmc.sleep(1000) self.Play = True elif method == "Player.OnStop": result = json.loads(data) logger.debug("OnStop: " + str(result)) # if viewing in file mode and playback stopped at the end if "item" in result and result["end"]: item = result["item"] if utilities.isEpisode(item["type"]): episode = False if "id" in item: episode = Media( item["id"], 1, self.Play).get_media_info("episode") elif ("episode" in item and "season" in item and "showtitle" in item): logstr = "" tvdbid = globals.betaseriesapi.tvdbidFromTitle( item["showtitle"], logstr) if tvdbid: tvdbepid = globals.betaseriesapi.tvdbepidFromtvdbid( tvdbid, item["showtitle"], item["season"], item["episode"], logstr, ) if tvdbepid: episode = Media( int(tvdbepid), 1, True).get_media_info("episode") if not episode and "title" in item: episode = Media(item["title"], 1, True).get_media_info("episode") # mark episode as watched if episode: logger.debug(episode) self.action(episode, self.service) elif utilities.isMovie(item["type"]): movie = False if "id" in item: movie = Media(item["id"], 1, self.Play).get_media_info("movie") elif "title" in item: movie = Media(item["title"], 1, self.Play).get_media_info("movie") # mark movie as watched if movie: self.action(movie, self.service) else: # wait 1s to avoid setting Play=False before marking episode xbmc.sleep(1000) self.Play = False elif method == "VideoLibrary.OnUpdate": result = json.loads(data) logger.debug("OnUpdate: " + str(result)) if "playcount" in result: if "item" in result: item = result["item"] if utilities.isEpisode(item["type"]): logger.debug( "episode status changed for library id = %s, playcount = %s" % (item["id"], result["playcount"])) episode = Media( item["id"], result["playcount"], self.Play).get_media_info("episode") logger.debug(episode) if episode: if result["playcount"] == 0 and not episode[ "seen"]: # mark as downloaded episode["playcount"] = -1 self.action(episode, self.service) self.action(episode, self.service) self.Play = False elif utilities.isMovie(item["type"]): logger.debug( "movie status changed for library id = %s, playcount = %s" % (item["id"], result["playcount"])) movie = Media(item["id"], result["playcount"], self.Play).get_media_info("movie") logger.debug(movie) if movie: # mark as watched or not, depending on playcount self.action(movie, self.service) self.Play = False
def doManualRating(self, data): action = data['action'] media_type = data['media_type'] summaryInfo = None if not utilities.isValidMediaType(media_type): logger.debug("doManualRating(): Invalid media type '%s' passed for manual %s." % (media_type, action)) return if not data['action'] in ['rate', 'unrate']: logger.debug("doManualRating(): Unknown action passed.") return logger.debug("Getting data for manual %s of %s: video_id: |%s| dbid: |%s|" % (action, media_type, data.get('video_id'), data.get('dbid'))) id_type = utilities.parseIdToTraktIds(str(data['video_id']), media_type)[1] if not id_type: logger.debug("doManualRating(): Unrecognized id_type: |%s|-|%s|." % (media_type, data['video_id'])) return ids = globals.traktapi.getIdLookup(data['video_id'], id_type) if not ids: logger.debug("doManualRating(): No Results for: |%s|-|%s|." % (media_type, data['video_id'])) return trakt_id = dict(ids[0].keys)['trakt'] if utilities.isEpisode(media_type): summaryInfo = globals.traktapi.getEpisodeSummary(trakt_id, data['season'], data['episode']) userInfo = globals.traktapi.getEpisodeRatingForUser(trakt_id, data['season'], data['episode'], 'trakt') elif utilities.isSeason(media_type): summaryInfo = globals.traktapi.getShowSummary(trakt_id) userInfo = globals.traktapi.getSeasonRatingForUser(trakt_id, data['season'], 'trakt') elif utilities.isShow(media_type): summaryInfo = globals.traktapi.getShowSummary(trakt_id) userInfo = globals.traktapi.getShowRatingForUser(trakt_id, 'trakt') elif utilities.isMovie(media_type): summaryInfo = globals.traktapi.getMovieSummary(trakt_id) userInfo = globals.traktapi.getMovieRatingForUser(trakt_id, 'trakt') if summaryInfo is not None: summaryInfo = summaryInfo.to_dict() summaryInfo['user'] = {'ratings': userInfo} if utilities.isEpisode(media_type): summaryInfo['season'] = data['season'] summaryInfo['number'] = data['episode'] summaryInfo['episodeid'] = data.get('dbid') elif utilities.isSeason(media_type): summaryInfo['season'] = data['season'] elif utilities.isMovie(media_type): summaryInfo['movieid'] = data.get('dbid') elif utilities.isShow(media_type): summaryInfo['tvshowid'] = data.get('dbid') if action == 'rate': if not 'rating' in data: rateMedia(media_type, [summaryInfo]) else: rateMedia(media_type, [summaryInfo], rating=data['rating']) elif action == 'unrate': rateMedia(media_type, [summaryInfo], unrate=True) else: logger.debug("doManualRating(): Summary info was empty, possible problem retrieving data from Trakt.tv")
def _service_mark(self, episode, service): # abort if betamark = false and playcount > 0 and play = false if not service.mark and episode["playcount"] > 0 and not episode[ "playstatus"]: logger.info(f"abort marking, as play = {episode['playstatus']}") return # abort if betaunmark = false and playcount = 0 and play = false elif (not service.unMark and episode["playcount"] == 0 and not episode["playstatus"]): logger.info(f"abort unmarking, as play = {episode['playstatus']}") return if utilities.isEpisode(episode["type"]): # follow show if BetaFollow = true # if service.follow and episode["playcount"] != -1: if service.follow and not episode["followed"]: url = self.apiurl + "/shows/show" urldata = { "v": self.apiver, "key": self.apikey, "token": self.token, "thetvdb_id": episode["int_id"], } try: # marking request response = utilities.get_urldata(url, urldata, "POST") # marking response data = json.loads(response) except Exception: self.__service_fail(False) logger.info( f"failed to follow TV show {episode['showtitle']}") # parse results if data["errors"]: if self.__checkerrors(data["errors"][0], infos=episode["showtitle"]): return None if service.notify: notification(getString(32010), getString(30013, episode["showtitle"])) logger.info(f"now following show {episode['showtitle']}") if utilities.isMovie(episode["type"]): # mark movie as watched url = self.apiurl + "/movies/movie" urldata = { "v": self.apiver, "key": self.apikey, "token": self.token, "id": episode["int_id"], "state": episode["playcount"], } method = "POST" if episode["playcount"] == 0: act = "not watched" actlang = 30017 else: act = "watched" actlang = 30016 elif utilities.isEpisode(episode["type"]): # mark episode as watched, unwatched or downloaded urldata = { "v": self.apiver, "key": self.apikey, "token": self.token, "thetvdb_id": episode["remote_id"], } if service.bulk: urldata.update({"bulk": 1}) if episode["playcount"] == 0: url = self.apiurl + "/episodes/watched" method = "DELETE" act = "not watched" actlang = 30015 elif episode["playcount"] == -1: url = self.apiurl + "/episodes/downloaded" method = "POST" act = "downloaded" actlang = 30101 else: url = self.apiurl + "/episodes/watched" method = "POST" act = "watched" actlang = 30014 try: # marking request response = utilities.get_urldata(url, urldata, method) # marking response data = json.loads(response) except Exception: self.__service_fail(False) logger.warning(f"failed to mark as {act}") return # parse results if data["errors"]: if self.__checkerrors(data["errors"][0], infos=episode["type"] + episode["title"]): return None if service.notify: notification(getString(32010), getString(actlang)) logger.info( f"{episode['showtitle']} {episode['title']} marked as {act}") return None