def isPlayingZone(self): if WindowShowing.isTvTunesOverrideContinuePlaying(): return True if WindowShowing.isRecentEpisodesAdded(): return False if WindowShowing.isPluginPath(): return False if WindowShowing.isMovieInformation() and Settings.isPlayVideoInformation(): return True if WindowShowing.isSeasons() and Settings.isPlayTvShowSeasons(): return True if WindowShowing.isEpisodes() and Settings.isPlayTvShowEpisodes(): return True # Only valid if wanting theme on movie list if WindowShowing.isMovies() and Settings.isPlayMovieList(): return True # Only valid if wanting theme on TV list if WindowShowing.isTvShowTitles() and Settings.isPlayTvShowList(): return True # Only valid if wanting theme on Music Video list if WindowShowing.isMusicVideoTitles() and Settings.isPlayMusicVideoList(): return True if WindowShowing.isMusicSection(): return True # Any other area is deemed to be a non play area return False
def endPlaying(self, fastFade=False, slowFade=False): if self.isPlayingAudio() and Settings.isFadeOut(): cur_vol = self._getVolume() # Calculate how fast to fade the theme, this determines # the number of step to drop the volume in numSteps = 10 if fastFade: numSteps = numSteps / 2 elif slowFade: numSteps = numSteps * 4 vol_step = cur_vol / numSteps # do not mute completely else the mute icon shows up for step in range(0, (numSteps - 1)): # If the system is going to be shut down then we need to reset # everything as quickly as possible if WindowShowing.isShutdownMenu() or xbmc.abortRequested: log("ThemePlayer: Shutdown menu detected, cancelling fade out") break vol = cur_vol - vol_step log("ThemePlayer: fadeOut_vol: %s" % str(vol)) self._setVolume(vol) cur_vol = vol xbmc.sleep(200) # The final stop and reset of the settings will be done # outside of this "if" # Need to always stop by the end of this self.stop()
def _checkListPlayingDelay(self, themes): # Check if we are playing themes on the list view, in which case we will want to delay them if (Settings.isPlayMovieList() and WindowShowing.isMovies()) or ( Settings.isPlayTvShowList() and WindowShowing.isTvShowTitles() ) or (Settings.isPlayMusicVideoList() and WindowShowing.isMusicVideoTitles()): log("DelayedStartTheme: Movie List playing delay detected, anchorTime = %s" % str(self.anchorTime)) if themes != self.themesToStart: # Theme selection has changed self.themesToStart = themes # Reset the current time as we need the delay from here self.anchorTime = 2 # for movie list delay, it is just a counter else: # reduce the anchor by one self.anchorTime = self.anchorTime - 1 if self.anchorTime < 1: self.clear() return True return False # Default is to allow playing return True
def _checkListPlayingDelay(self, themes): # Check if we are playing themes on the list view, in which case we will want to delay them if (Settings.isPlayMovieList() and WindowShowing.isMovies()) or (Settings.isPlayTvShowList() and WindowShowing.isTvShowTitles()) or (Settings.isPlayMusicVideoList() and WindowShowing.isMusicVideoTitles()): log("DelayedStartTheme: Movie List playing delay detected, anchorTime = %s" % str(self.anchorTime)) if themes != self.themesToStart: # Theme selection has changed self.themesToStart = themes # Reset the current time as we need the delay from here self.anchorTime = 2 # for movie list delay, it is just a counter else: # reduce the anchor by one self.anchorTime = self.anchorTime - 1 if self.anchorTime < 1: self.clear() return True return False # Default is to allow playing return True
def _getMovieSetFileList(self): # Create a map for Program name to video file movieSetMap = dict() # Check if the selection is a Movie Set if WindowShowing.isMovieSet(): # Get Movie Set Data Base ID dbid = xbmc.getInfoLabel("ListItem.DBID") # Get movies from Movie Set json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovieSetDetails", "params": {"setid": %s, "properties": [ "thumbnail" ], "movies": { "properties": [ "file", "title"], "sort": { "order": "ascending", "method": "title" }} },"id": 1 }' % dbid) json_query = unicode(json_query, 'utf-8', errors='ignore') json_query = simplejson.loads(json_query) if ("result" in json_query) and ('setdetails' in json_query['result']): # Get the list of movies paths from the movie set items = json_query['result']['setdetails']['movies'] for item in items: log("TunesBackend: Movie Set file (%s): %s" % (item['title'], item['file'])) movieSetMap[item['title']] = item['file'] return movieSetMap
def endPlaying(self, fastFade=False, slowFade=False): # If we are stopping audio and we do not have a value for the original volume # then it means we are stopping something that we did not start, this means that # before we do anything like fade the volume out we should get the current # volume and store it as the base level if self.original_volume < 0: self.original_volume = self._getVolume() if self.isPlayingAudio() and Settings.isFadeOut(): cur_vol = self._getVolume() # Calculate how fast to fade the theme, this determines # the number of step to drop the volume in numSteps = 10 if fastFade: numSteps = numSteps / 2 elif slowFade: numSteps = numSteps * 4 vol_step = cur_vol / numSteps # do not mute completely else the mute icon shows up for step in range(0, (numSteps - 1)): # If the system is going to be shut down then we need to reset # everything as quickly as possible if WindowShowing.isShutdownMenu() or xbmc.abortRequested: log("ThemePlayer: Shutdown menu detected, cancelling fade out" ) break vol = cur_vol - vol_step log("ThemePlayer: fadeOut_vol: %s" % str(vol)) self._setVolume(vol) cur_vol = vol xbmc.sleep(200) # The final stop and reset of the settings will be done # outside of this "if" # Need to always stop by the end of this self.stop()
def getThemes(self): themePath = "" # Only need the theme path for videos if not WindowShowing.isMusicSection(): # Check if the files are stored in a custom path if Settings.isCustomPathEnabled(): if not WindowShowing.isMovies(): videotitle = xbmc.getInfoLabel("ListItem.TVShowTitle") else: videotitle = xbmc.getInfoLabel("ListItem.Title") videotitle = normalize_string(videotitle) themePath = os_path_join(Settings.getCustomPath(), videotitle) # Looking at the TV Show information page elif WindowShowing.isMovieInformation() and (WindowShowing.isTvShowTitles() or WindowShowing.isTvShows()): themePath = xbmc.getInfoLabel("ListItem.FilenameAndPath") else: themePath = xbmc.getInfoLabel("ListItem.Path") # To try and reduce the amount of "noise" in the logging, where the # same check is logged again and again, we record if it has been # logged for this video, and then do not do it again until the # video changes and what we would print wound be different debug_logging_enabled = False # Only log if something is different from the last time we logged if self.lastLoggedThemePath != themePath: debug_logging_enabled = True self.lastLoggedThemePath = themePath log("TunesBackend: themePath = %s" % themePath, debug_logging_enabled) # Check if the selection is a Movie Set if WindowShowing.isMovieSet(): movieSetMap = self._getMovieSetFileList() if Settings.isCustomPathEnabled(): # Need to make the values part (the path) point to the custom path # rather than the video file for aKey in movieSetMap.keys(): videotitle = normalize_string(aKey) movieSetMap[aKey] = os_path_join(Settings.getCustomPath(), videotitle) if len(movieSetMap) < 1: themefile = ThemeFiles("", debug_logging_enabled=debug_logging_enabled) else: themefile = ThemeFiles(themePath, movieSetMap.values(), debug_logging_enabled=debug_logging_enabled) # When the reference is into the database and not the file system # then don't return it elif themePath.startswith("videodb:"): # If in either the Tv Show List or the Movie list then # need to stop the theme is selecting the back button if WindowShowing.isMovies() or WindowShowing.isTvShowTitles(): themefile = ThemeFiles("", debug_logging_enabled=debug_logging_enabled) else: # Load the previous theme themefile = self.newThemeFiles else: if WindowShowing.isMusicSection(): themefile = MusicThemeFiles(debug_logging_enabled) else: themefile = ThemeFiles(themePath, debug_logging_enabled=debug_logging_enabled) return themefile
def runAsAService(self): logVideoLibraryNotShowing = True while not xbmc.abortRequested: # Wait a little before starting the check each time xbmc.sleep(200) # Check the forced TV Tunes status at the start of the loop, if this is True # then we don't want to stop themes until the next iteration, this stops the case # where some checks are done and the value changes part was through a single # loop iteration isForcedTvTunesContinue = WindowShowing.isTvTunesOverrideContinuePlaying() # Stop the theme if the shutdown menu appears - it normally means # we are about to shut the system down, so get ahead of the game if WindowShowing.isShutdownMenu(): self.stop(fastFade=True) continue # NOTE: The screensaver kicking in will only be picked up if the option # "Use Visualization if Playing Audio" is disabled if WindowShowing.isScreensaver(): if self.isAlive: log("TunesBackend: Screensaver active") self.stop(fastFade=True) # It may be possible that we stopped for the screen-saver about to kick in # If we are using Gotham or higher, it is possible for us to re-kick off the # screen-saver, otherwise the action of us stopping the theme will reset the # timeout and the user will have to wait longer log("TunesBackend: Restarting screensaver that TvTunes stopped") xbmc.executebuiltin("ActivateScreensaver", True) continue # Check if TvTunes is blocked from playing any themes if xbmcgui.Window(10025).getProperty('TvTunesBlocked') not in [None, ""]: self.stop(fastFade=True) continue if (not WindowShowing.isVideoLibrary()) and (not WindowShowing.isMusicSection()): log("TunesBackend: Video Library no longer visible", logVideoLibraryNotShowing) logVideoLibraryNotShowing = False # End playing cleanly (including any fade out) and then stop everything self.stop() continue else: logVideoLibraryNotShowing = True # There is a valid page selected and there is currently nothing playing if self.isPlayingZone() and not WindowShowing.isTvTunesOverrideContinuePrevious(): newThemes = self.getThemes() if self.newThemeFiles != newThemes: self.newThemeFiles = newThemes # Check if the file path has changed, if so there is a new file to play if self.newThemeFiles != self.oldThemeFiles and self.newThemeFiles.hasThemes(): log("TunesBackend: old path: %s" % self.oldThemeFiles.getPath()) log("TunesBackend: new path: %s" % self.newThemeFiles.getPath()) if self.start_playing(): # Now that playing has started, update the current themes that are being used self.oldThemeFiles = self.newThemeFiles # Check the operations where we are currently running and we need to stop # playing the current theme if self.isAlive: if self.themePlayer.isPlayingTheme(): # There is no theme at this location, so make sure we are stopped if not self.newThemeFiles.hasThemes(): log("TunesBackend: No themes to play for current item") self.themePlayer.endPlaying() self.oldThemeFiles.clear() self.prevThemeFiles.clear() self.delayedStart.clear() self.isAlive = False else: # This will occur when a theme has stopped playing, maybe is is not set to loop # There can be a delay when playing between playlist items, so give it a little # time to start playing the next one themeIsStillPlaying = False maxLoop = 500 while (maxLoop > 0) and (not themeIsStillPlaying): maxLoop = maxLoop - 1 xbmc.sleep(1) if self.themePlayer.isPlayingTheme(): themeIsStillPlaying = True break if not themeIsStillPlaying: log("TunesBackend: playing ended, restoring settings") self.themePlayer.restoreSettings() self.isAlive = False # This is the case where the user has moved from within an area where the themes # to an area where the theme is no longer played, so it will trigger a stop and # reset everything to highlight that nothing is playing if (not self.isPlayingZone()) and (not isForcedTvTunesContinue): self.stop() else: # Check for the case where we are playing the trailer as a theme # video, if so we want to stop the trailer playing when the video # information screen is displayed. If we don't, when the trailer is # started then TvTunes will automatically stop it if Settings.useTrailers() and WindowShowing.isMovieInformation() and self.themePlayer.isPlayingTrailerTheme(): self.stop() # Check to see if the setting to restrict the theme duration is enabled # and if it is we need to stop the current theme playing self.themePlayer.checkEnding() # We have finished running, just make one last check to ensure # we do not need to stop any audio self.stop(True) del self.themePlayer
def play(self, item=None, listitem=None, windowed=True, fastFade=False): self.tvtunesPlayerStarted = True # if something is already playing, then we do not want # to replace it with the theme if not self.isPlaying(): self.updateVideoRefreshRate(item) # Save the volume from before any alterations self.original_volume = self._getVolume() # Perform and lowering of the sound for theme playing self._lowerVolume() if Settings.isFadeIn(): # Get the current volume - this is our target volume targetVol = self._getVolume() cur_vol_perc = 1 # Calculate how fast to fade the theme, this determines # the number of step to drop the volume in numSteps = 10 if fastFade: numSteps = numSteps / 2 vol_step = targetVol / numSteps # Reduce the volume before starting # do not mute completely else the mute icon shows up self._setVolume(1) # Now start playing before we start increasing the volume xbmc.Player.play(self, item=item, listitem=listitem, windowed=windowed) # Wait until playing has started maxLoop = 100 while (not self.isPlaying()) and ( not xbmc.abortRequested) and (maxLoop > 0): maxLoop = maxLoop - 1 xbmc.sleep(30) for step in range(0, (numSteps - 1)): # If the system is going to be shut down then we need to reset # everything as quickly as possible if WindowShowing.isShutdownMenu() or xbmc.abortRequested: log("ThemePlayer: Shutdown menu detected, cancelling fade in" ) break vol = cur_vol_perc + vol_step log("ThemePlayer: fadeIn_vol: %s" % str(vol)) self._setVolume(vol) cur_vol_perc = vol xbmc.sleep(200) # Make sure we end on the correct volume self._setVolume(targetVol) else: xbmc.Player.play(self, item=item, listitem=listitem, windowed=windowed) if Settings.isLoop(): xbmc.executebuiltin("PlayerControl(RepeatAll)") # We no longer use the JSON method to repeat as it does not work with videos # xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "method": "Player.SetRepeat", "params": {"playerid": 0, "repeat": "all" }, "id": 1 }') # If we had a random start and we are looping then we need to make sure # when it comes to play the theme for a second time it starts at the beginning # and not from the same mid-point if Settings.isRandomStart(): item[0].setProperty('StartOffset', "0") else: xbmc.executebuiltin("PlayerControl(RepeatOff)") # We no longer use the JSON method to repeat as it does not work with videos # xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "method": "Player.SetRepeat", "params": {"playerid": 0, "repeat": "off" }, "id": 1 }') # Record the time that playing was started self.startTime = int(time.time()) # Clear the current playlist, as we will re-populate it self.playListItems = [] # Save off the number of items in the playlist if item is not None: self.playlistSize = item.size() log("ThemePlayer: Playlist size = %d" % self.playlistSize) # Store a list of all the tracks in the playlist try: i = 0 while i < self.playlistSize: self.playListItems.append(item[i].getfilename()) i = i + 1 except: log("ThemePlayer: Failed to save off playlist") # Check if we are limiting each track in the list if not Settings.isLoop(): # Already started playing the first, so the remaining number of # tracks is one less than the total self.remainingTracks = self.playlistSize - 1 self._setNextSkipTrackTime(self.startTime) else: self.playlistSize = 1
def runAsAService(self): logVideoLibraryNotShowing = True while not xbmc.abortRequested: # Wait a little before starting the check each time xbmc.sleep(200) # Check the forced TV Tunes status at the start of the loop, if this is True # then we don't want to stop themes until the next iteration, this stops the case # where some checks are done and the value changes part was through a single # loop iteration isForcedTvTunesContinue = WindowShowing.isTvTunesOverrideContinuePlaying() # Stop the theme if the shutdown menu appears - it normally means # we are about to shut the system down, so get ahead of the game if WindowShowing.isShutdownMenu(): self.stop(fastFade=True) continue # NOTE: The screensaver kicking in will only be picked up if the option # "Use Visualization if Playing Audio" is disabled if WindowShowing.isScreensaver(): if self.isAlive: log("TunesBackend: Screensaver active") self.stop(fastFade=True) # It may be possible that we stopped for the screen-saver about to kick in # If we are using Gotham or higher, it is possible for us to re-kick off the # screen-saver, otherwise the action of us stopping the theme will reset the # timeout and the user will have to wait longer log("TunesBackend: Restarting screensaver that TvTunes stopped") xbmc.executebuiltin("ActivateScreensaver", True) continue # Check if TvTunes is blocked from playing any themes if xbmcgui.Window(10025).getProperty('TvTunesBlocked') not in [None, ""]: self.stop(fastFade=True) continue if (not WindowShowing.isVideoLibrary()) and (not WindowShowing.isMusicSection()): log("TunesBackend: Video Library no longer visible", logVideoLibraryNotShowing) logVideoLibraryNotShowing = False # End playing cleanly (including any fade out) and then stop everything self.stop() continue else: logVideoLibraryNotShowing = True # There is a valid page selected and there is currently nothing playing if self.isPlayingZone() and not WindowShowing.isTvTunesOverrideContinuePrevious(): newThemes = self.getThemes() if self.newThemeFiles != newThemes: self.newThemeFiles = newThemes # Check if the file path has changed, if so there is a new file to play if self.newThemeFiles != self.oldThemeFiles and self.newThemeFiles.hasThemes(): log("TunesBackend: old path: %s" % self.oldThemeFiles.getPath()) log("TunesBackend: new path: %s" % self.newThemeFiles.getPath()) if self.start_playing(): # Now that playing has started, update the current themes that are being used self.oldThemeFiles = self.newThemeFiles # Check the operations where wee are currently running and we need to stop # playing the current theme if self.isAlive: if self.themePlayer.isPlayingTheme(): # There is no theme at this location, so make sure we are stopped if not self.newThemeFiles.hasThemes(): log("TunesBackend: No themes to play for current item") self.themePlayer.endPlaying() self.oldThemeFiles.clear() self.prevThemeFiles.clear() self.delayedStart.clear() self.isAlive = False else: # This will occur when a theme has stopped playing, maybe is is not set to loop # There can be a delay when playing between playlist items, so give it a little # time to start playing the next one themeIsStillPlaying = False maxLoop = 500 while (maxLoop > 0) and (not themeIsStillPlaying): maxLoop = maxLoop - 1 xbmc.sleep(1) if self.themePlayer.isPlayingTheme(): themeIsStillPlaying = True break if not themeIsStillPlaying: log("TunesBackend: playing ended, restoring settings") self.themePlayer.restoreSettings() self.isAlive = False # This is the case where the user has moved from within an area where the themes # to an area where the theme is no longer played, so it will trigger a stop and # reset everything to highlight that nothing is playing if (not self.isPlayingZone()) and (not isForcedTvTunesContinue): self.stop() # Check to see if the setting to restrict the theme duration is enabled # and if it is we need to stop the current theme playing self.themePlayer.checkEnding() # We have finished running, just make one last check to ensure # we do not need to stop any audio self.stop(True) del self.themePlayer
def play(self, item=None, listitem=None, windowed=True, fastFade=False): self.tvtunesPlayerStarted = True # if something is already playing, then we do not want # to replace it with the theme if not self.isPlaying(): self.updateVideoRefreshRate(item) # Save the volume from before any alterations self.original_volume = self._getVolume() # Perform and lowering of the sound for theme playing self._lowerVolume() if Settings.isFadeIn(): # Get the current volume - this is our target volume targetVol = self._getVolume() cur_vol_perc = 1 # Calculate how fast to fade the theme, this determines # the number of step to drop the volume in numSteps = 10 if fastFade: numSteps = numSteps / 2 vol_step = targetVol / numSteps # Reduce the volume before starting # do not mute completely else the mute icon shows up self._setVolume(1) # Now start playing before we start increasing the volume xbmc.Player.play(self, item=item, listitem=listitem, windowed=windowed) # Wait until playing has started maxLoop = 100 while (not self.isPlaying()) and (not xbmc.abortRequested) and (maxLoop > 0): maxLoop = maxLoop - 1 xbmc.sleep(30) for step in range(0, (numSteps - 1)): # If the system is going to be shut down then we need to reset # everything as quickly as possible if WindowShowing.isShutdownMenu() or xbmc.abortRequested: log("ThemePlayer: Shutdown menu detected, cancelling fade in") break vol = cur_vol_perc + vol_step log("ThemePlayer: fadeIn_vol: %s" % str(vol)) self._setVolume(vol) cur_vol_perc = vol xbmc.sleep(200) # Make sure we end on the correct volume self._setVolume(targetVol) else: xbmc.Player.play(self, item=item, listitem=listitem, windowed=windowed) if Settings.isLoop(): xbmc.executebuiltin("PlayerControl(RepeatAll)") # We no longer use the JSON method to repeat as it does not work with videos # xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "method": "Player.SetRepeat", "params": {"playerid": 0, "repeat": "all" }, "id": 1 }') # If we had a random start and we are looping then we need to make sure # when it comes to play the theme for a second time it starts at the beginning # and not from the same mid-point if Settings.isRandomStart(): item[0].setProperty('StartOffset', "0") else: xbmc.executebuiltin("PlayerControl(RepeatOff)") # We no longer use the JSON method to repeat as it does not work with videos # xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "method": "Player.SetRepeat", "params": {"playerid": 0, "repeat": "off" }, "id": 1 }') # Record the time that playing was started self.startTime = int(time.time()) # Clear the current playlist, as we will re-populate it self.playListItems = [] # Save off the number of items in the playlist if item is not None: self.playlistSize = item.size() log("ThemePlayer: Playlist size = %d" % self.playlistSize) # Store a list of all the tracks in the playlist try: i = 0 while i < self.playlistSize: self.playListItems.append(item[i].getfilename()) i = i + 1 except: log("ThemePlayer: Failed to save off playlist") # Check if we are limiting each track in the list if not Settings.isLoop(): # Already started playing the first, so the remaining number of # tracks is one less than the total self.remainingTracks = self.playlistSize - 1 self._setNextSkipTrackTime(self.startTime) else: self.playlistSize = 1
# Make sure we have recorded this machines Id Settings.setTvTunesId() # Check if the settings mean we want to reset the volume on startup startupVol = Settings.getStartupVolume() if startupVol < 0: log("TvTunesService: No Volume Change Required") else: log("TvTunesService: Setting volume to %s" % startupVol) xbmc.executebuiltin('SetVolume(%d)' % startupVol, True) # Check if the video info button should be hidden, we do this here as this will be # called when the system is loaded, it can then be read by the skin # when it comes to draw the button WindowShowing.updateHideVideoInfoButton() WindowShowing.updateShowOnContextMenu() # Make sure the user wants to play themes if Settings.isThemePlayingEnabled(): log("TvTunesService: Theme playing enabled") if Settings.isUploadEnabled(): log("TvTunesService: Launching uploader") xbmc.executebuiltin('RunScript(%s)' % os.path.join(__lib__, "upload.py"), False) else: log("TvTunesService: Uploader not enabled") # Create a monitor so we can reload the settings if they change systemMonitor = TvTunesMonitor()
def getThemes(self): themePath = "" # Only need the theme path for videos if not WindowShowing.isMusicSection(): # Check if the files are stored in a custom path if Settings.isCustomPathEnabled(): if not WindowShowing.isMovies(): videotitle = xbmc.getInfoLabel("ListItem.TVShowTitle") else: videotitle = xbmc.getInfoLabel("ListItem.Title") videotitle = normalize_string(videotitle) themePath = os_path_join(Settings.getCustomPath(), videotitle) # Looking at the TV Show information page elif WindowShowing.isMovieInformation() and ( WindowShowing.isTvShowTitles() or WindowShowing.isTvShows()): themePath = xbmc.getInfoLabel("ListItem.FilenameAndPath") else: themePath = xbmc.getInfoLabel("ListItem.Path") # To try and reduce the amount of "noise" in the logging, where the # same check is logged again and again, we record if it has been # logged for this video, and then do not do it again until the # video changes and what we would print wound be different debug_logging_enabled = False # Only log if something is different from the last time we logged if self.lastLoggedThemePath != themePath: debug_logging_enabled = True self.lastLoggedThemePath = themePath log("TunesBackend: themePath = %s" % themePath, debug_logging_enabled) # Check if the selection is a Movie Set if WindowShowing.isMovieSet(): movieSetMap = self._getMovieSetFileList() if Settings.isCustomPathEnabled(): # Need to make the values part (the path) point to the custom path # rather than the video file for aKey in movieSetMap.keys(): videotitle = normalize_string(aKey) movieSetMap[aKey] = os_path_join(Settings.getCustomPath(), videotitle) if len(movieSetMap) < 1: themefile = ThemeFiles( "", debug_logging_enabled=debug_logging_enabled) else: themefile = ThemeFiles( themePath, movieSetMap.values(), debug_logging_enabled=debug_logging_enabled) # When the reference is into the database and not the file system # then don't return it elif themePath.startswith("videodb:"): # If in either the Tv Show List or the Movie list then # need to stop the theme is selecting the back button if WindowShowing.isMovies() or WindowShowing.isTvShowTitles(): themefile = ThemeFiles( "", debug_logging_enabled=debug_logging_enabled) else: # Load the previous theme themefile = self.newThemeFiles else: if WindowShowing.isMusicSection(): themefile = MusicThemeFiles(debug_logging_enabled) else: themefile = ThemeFiles( themePath, debug_logging_enabled=debug_logging_enabled) # Check if no themes were found for this item, there is a case if it is a # TV Show and it is nested Show-Name/Series-X/Episode-Directory/Episode.ext # Then this will not pick up themes in the root of the TV Show directory if (not themefile.hasThemes()) and ( not Settings.isCustomPathEnabled() ) and WindowShowing.isEpisodes(): tvshowTitle = xbmc.getInfoLabel("ListItem.TVShowTitle") if tvshowTitle not in [None, ""]: try: # Make a call to the database to find out the root path of this TV Show filterStr = '{"operator": "is", "field": "title", "value": "%s"}' % tvshowTitle cmd = '{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties": ["file"], "filter": %s},"id": 1 }' % filterStr json_query = xbmc.executeJSONRPC(cmd) json_query = simplejson.loads(json_query) if ("result" in json_query) and ( 'tvshows' in json_query['result']): # Get the path to the TV Show and compare it to where we were previously # looking tvshowList = json_query['result']['tvshows'] if len(tvshowList) == 1: tvshowPath = json_query['result'][ 'tvshows'][0]['file'] # Make sure we have not already checked this path # We will already have checked the parent path as well if (tvshowPath != themePath) and ( tvshowPath != os_path_split(themePath)[0]): # So we know that we haven't checked the root of this TV Show yet log( "TunesBackend: Checking root TV Show Path = %s" % tvshowPath, debug_logging_enabled) themefile = ThemeFiles( tvshowPath, debug_logging_enabled= debug_logging_enabled) except: log( "TunesBackend: Failed to check root TV Show %s" % traceback.format_exc(), debug_logging_enabled) return themefile