def fetchTheme(self, title, path, originaltitle=None, isTvShow=None, year=None, imdb=None): # If there is already a theme then start playing it self._startPlayingExistingTheme(path) if Settings.isThemeDirEnabled() and self._doesThemeExist(path, True): # Prompt user if we should move themes in the parent # directory into the theme directory moveExistingThemes = xbmcgui.Dialog().yesno(__addon__.getLocalizedString(32105), __addon__.getLocalizedString(32206), __addon__.getLocalizedString(32207)) # Check if we need to move a theme file if moveExistingThemes: log("fetchAllMissingThemes: Moving theme for %s" % title) self._moveToThemeFolder(path) # Stop playing any theme that started self._stopPlayingTheme() # Now reload the screen to reflect the change xbmc.executebuiltin("Container.Refresh") return if originaltitle is not None: originaltitle = normalize_string(originaltitle) # Perform the fetch videoList = [] normtitle = normalize_string(title) videoItem = {'title': normtitle, 'path': path, 'originalTitle': originaltitle, 'isTvShow': isTvShow, 'year': year, 'imdb': imdb} videoList.append(videoItem) TvTunesFetcher(videoList) # Stop playing any theme that started self._stopPlayingTheme() # Now reload the screen to reflect the change xbmc.executebuiltin("Container.Refresh")
def __init__(self, rawPath, pathList=None, videotitle=None, debug_logging_enabled=True, audioOnly=False): self.debug_logging_enabled = debug_logging_enabled self.forceShuffle = False self.doNotShuffle = False self.audioOnly = audioOnly self.rawPath = rawPath if rawPath in [None, ""]: self.clear() else: # Check for the case where there is a custom path set so we need to use # the custom location rather than the rawPath if Settings.isCustomPathEnabled() and (videotitle not in [None, ""]): customRoot = Settings.getCustomPath() # Make sure that the path passed in has not already been converted if customRoot not in self.rawPath: self.rawPath = os_path_join(customRoot, normalize_string(videotitle)) log("ThemeFiles: Setting custom path to %s" % self.rawPath, self.debug_logging_enabled) if (pathList is not None) and (len(pathList) > 0): self.themeFiles = [] for aPath in pathList: subThemeList = self._generateThemeFilelistWithDirs(aPath) # add these files to the existing list self.themeFiles = self._mergeThemeLists(self.themeFiles, subThemeList) # If we were given a list, then we should shuffle the themes # as we don't always want the first path playing first self.forceShuffle = True else: self.themeFiles = self._generateThemeFilelistWithDirs(self.rawPath) # Check if we need to handle the ordering for video themes if not audioOnly: self.doNotShuffle = self._filterForVideoThemesRule() self.forceShuffle = False
def fetchAllMissingThemes(self): tvShows = self.getVideos('GetTVShows', MenuNavigator.TVSHOWS) movies = self.getVideos('GetMovies', MenuNavigator.MOVIES) music = self.getVideos('GetMusicVideos', MenuNavigator.MUSICVIDEOS) videoList = [] moveExistingThemes = None for videoItem in (tvShows + movies + music): # Get the path where the theme should be stored path = self.getPathForVideoItem(videoItem) # Skip items that already have themes if self._doesThemeExist(path): continue if Settings.isThemeDirEnabled() and self._doesThemeExist(path, True): if moveExistingThemes is None: # Prompt user if we should move themes in the parent # directory into the theme directory moveExistingThemes = xbmcgui.Dialog().yesno(__addon__.getLocalizedString(32105), __addon__.getLocalizedString(32206), __addon__.getLocalizedString(32207)) # Check if we need to move a theme file if moveExistingThemes: log("fetchAllMissingThemes: Moving theme for %s" % videoItem['title']) self._moveToThemeFolder(path) continue normtitle = normalize_string(videoItem['title']).encode("utf-8") normOriginalTitle = None if videoItem['originaltitle'] is not None: normOriginalTitle = normalize_string(videoItem['originaltitle']).encode("utf-8") videoItem = {'title': normtitle, 'path': path.encode("utf-8"), 'originalTitle': normOriginalTitle, 'isTvShow': videoItem['isTvShow'], 'year': videoItem['year'], 'imdb': videoItem['imdb']} videoList.append(videoItem) if len(videoList) > 0: TvTunesFetcher(videoList)
def _getCustomPathDir(self, path): # Get the last element of the path pathLastDir = os_path_split(path)[1] # Create the path with this added custPath = Settings.getCustomPath(self.videoType) custPath = os_path_join(custPath, pathLastDir) log("VideoExtrasFinder: Checking existence of custom path %s" % custPath) # Check if this path exists if not dir_exists(custPath): # If it doesn't exist, check the path before that, this covers the # case where there is a TV Show with each season in it's own directory # Make sure we have enough elements to actually navigate back up the path if len(os_path_split((os_path_split(path)[0]))) < 2: log("VideoExtrasFinder: No parent directories to check %s" % path) else: path2ndLastDir = os_path_split((os_path_split(path)[0]))[1] custPath = Settings.getCustomPath(self.videoType) custPath = os_path_join(custPath, path2ndLastDir) custPath = os_path_join(custPath, pathLastDir) log("VideoExtrasFinder: Checking existence of custom path %s" % custPath) if not dir_exists(custPath): # If it still does not exist then check just the 2nd to last path custPath = Settings.getCustomPath(self.videoType) custPath = os_path_join(custPath, path2ndLastDir) log("VideoExtrasFinder: Checking existence of custom path %s" % custPath) if not dir_exists(custPath): # Some systems will store extras in the custom pass using the name # of the TV Show of Movie, so try that videoName = self.title if self.title in [None, ""]: if self.videoType == Settings.TVSHOWS: videoName = xbmc.getInfoLabel("ListItem.TVShowTitle") else: videoName = xbmc.getInfoLabel("ListItem.Title") videoName = normalize_string(videoName) # Now construct the path using the movie or TV show title custPath = Settings.getCustomPath(self.videoType) custPath = os_path_join(custPath, videoName) log("VideoExtrasFinder: Checking existence of custom path using title %s" % custPath) if not dir_exists(custPath): custPath = None return custPath
def getPathForVideoItem(self, videoItem): path = "" # Get the path where the theme should be stored if Settings.isCustomPathEnabled(): path = os_path_join(Settings.getCustomPath(), normalize_string(videoItem['title'])) else: path = videoItem['file'] # Handle stacked files that have a custom file name format if path.startswith("stack://"): path = path.replace("stack://", "").split(" , ", 1)[0] # Need to remove the filename from the end as we just want the directory fileExt = os.path.splitext(path)[1] # If this is a file, then get it's parent directory if fileExt is not None and fileExt != "": path = os_path_split(path)[0] return path
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 getSoloVideo(self): log("getSoloVideo: solo mode") # Used to pass the name and path via the command line # This caused problems with non ascii characters, so now # we just look at the screen details # The solo option is only available from the info screen # Looking at the TV Show information page isTvShow = self._isTv() if isTvShow: videoName = xbmc.getInfoLabel("ListItem.TVShowTitle") log("getSoloVideo: TV Show detected %s" % videoName) else: videoName = xbmc.getInfoLabel("ListItem.Title") log("getSoloVideo: Movie detected %s" % videoName) # Now get the video path videoPath = None if xbmc.getCondVisibility( "Window.IsVisible(movieinformation)") and isTvShow: videoPath = xbmc.getInfoLabel("ListItem.FilenameAndPath") if videoPath is None or videoPath == "": videoPath = xbmc.getInfoLabel("ListItem.Path") log("getSoloVideo: Video Path %s" % videoPath) # Check if there is an "Original Title Defines originalTitle = xbmc.getInfoLabel("ListItem.OriginalTitle") if (originalTitle is not None) and (originalTitle != ""): originalTitle = normalize_string(originalTitle) else: originalTitle = None normVideoName = normalize_string(videoName) log("getSoloVideo: videoName = %s" % normVideoName) # If the main title and the original title are the same # Then no need to use the original title if (originalTitle == normVideoName): originalTitle = None if Settings.isCustomPathEnabled(): videoPath = os_path_join(Settings.getCustomPath(), normVideoName) else: log("getSoloVideo: Solo dir = %s" % videoPath) # Need to clean the path if we are going to store the file there # Handle stacked files that have a custom file name format if videoPath.startswith("stack://"): videoPath = videoPath.replace("stack://", "").split(" , ", 1)[0] # Need to remove the filename from the end as we just want the directory # if not os.path.isdir(videoPath): fileExt = os.path.splitext(videoPath)[1] # If this is a file, then get it's parent directory if fileExt is not None and fileExt != "": videoPath = os.path.dirname(videoPath) log("getSoloVideo: videoPath = %s" % videoPath) # Now get the year and imdb number for the video year = xbmc.getInfoLabel("ListItem.Year") imdb = xbmc.getInfoLabel("ListItem.IMDBNumber") videoItem = { 'title': normVideoName, 'path': videoPath, 'originalTitle': originalTitle, 'isTvShow': isTvShow, 'year': year, 'imdb': imdb } return videoItem
def getSoloVideo(self): log("getSoloVideo: solo mode") # Used to pass the name and path via the command line # This caused problems with non ascii characters, so now # we just look at the screen details # The solo option is only available from the info screen # Looking at the TV Show information page isTvShow = self._isTv() if isTvShow: videoName = xbmc.getInfoLabel("ListItem.TVShowTitle") log("getSoloVideo: TV Show detected %s" % videoName) else: videoName = xbmc.getInfoLabel("ListItem.Title") log("getSoloVideo: Movie detected %s" % videoName) # Now get the video path videoPath = None if xbmc.getCondVisibility("Window.IsVisible(movieinformation)") and isTvShow: videoPath = xbmc.getInfoLabel("ListItem.FilenameAndPath") if videoPath is None or videoPath == "": videoPath = xbmc.getInfoLabel("ListItem.Path") log("getSoloVideo: Video Path %s" % videoPath) # Check if there is an "Original Title Defines originalTitle = xbmc.getInfoLabel("ListItem.OriginalTitle") if (originalTitle is not None) and (originalTitle != ""): originalTitle = normalize_string(originalTitle) else: originalTitle = None normVideoName = normalize_string(videoName) log("getSoloVideo: videoName = %s" % normVideoName) # If the main title and the original title are the same # Then no need to use the original title if (originalTitle == normVideoName): originalTitle = None if Settings.isCustomPathEnabled(): videoPath = os_path_join(Settings.getCustomPath(), normVideoName) else: log("getSoloVideo: Solo dir = %s" % videoPath) # Need to clean the path if we are going to store the file there # Handle stacked files that have a custom file name format if videoPath.startswith("stack://"): videoPath = videoPath.replace("stack://", "").split(" , ", 1)[0] # Need to remove the filename from the end as we just want the directory # if not os.path.isdir(videoPath): fileExt = os.path.splitext(videoPath)[1] # If this is a file, then get it's parent directory if fileExt is not None and fileExt != "": videoPath = os.path.dirname(videoPath) log("getSoloVideo: videoPath = %s" % videoPath) # Now get the year and imdb number for the video year = xbmc.getInfoLabel("ListItem.Year") imdb = xbmc.getInfoLabel("ListItem.IMDBNumber") videoItem = {'title': normVideoName, 'path': videoPath, 'originalTitle': originalTitle, 'isTvShow': isTvShow, 'year': year, 'imdb': imdb} return videoItem
def getSoloVideo(self): log("getSoloVideo: solo mode") # Used to pass the name and path via the command line # This caused problems with non ascii characters, so now # we just look at the screen details # The solo option is only available from the info screen # Looking at the TV Show information page if WindowShowing.isTv(): videoName = xbmc.getInfoLabel("ListItem.TVShowTitle") log("getSoloVideo: TV Show detected %s" % videoName) else: videoName = xbmc.getInfoLabel("ListItem.Title") log("getSoloVideo: Movie detected %s" % videoName) # Now get the video path videoPath = None if WindowShowing.isMovieInformation() and WindowShowing.isTv(): videoPath = xbmc.getInfoLabel("ListItem.FilenameAndPath") if videoPath is None or videoPath == "": videoPath = xbmc.getInfoLabel("ListItem.Path") log("getSoloVideo: Video Path %s" % videoPath) # Check if there is an "Original Title Defines originalTitle = xbmc.getInfoLabel("ListItem.OriginalTitle") if (originalTitle is not None) and (originalTitle != ""): originalTitle = normalize_string(originalTitle) else: originalTitle = None normVideoName = normalize_string(videoName) log("getSoloVideo: videoName = %s" % normVideoName) # If the main title and the original title are the same # Then no need to use the original title if (originalTitle == normVideoName): originalTitle = None if Settings.isCustomPathEnabled(): videoPath = os_path_join(Settings.getCustomPath(), normVideoName) else: log("getSoloVideo: Solo dir = %s" % videoPath) # Need to clean the path if we are going to store the file there # Handle stacked files that have a custom file name format if videoPath.startswith("stack://"): videoPath = videoPath.replace("stack://", "").split(" , ", 1)[0] # Need to remove the filename from the end as we just want the directory # if not os.path.isdir(videoPath): fileExt = os.path.splitext(videoPath)[1] # If this is a file, then get it's parent directory if fileExt is not None and fileExt != "": videoPath = os.path.dirname(videoPath) log("getSoloVideo: videoPath = %s" % videoPath) # try: # decodedPath = videoPath.decode("utf-8") # videoPath = decodedPath # except: # pass return [normVideoName, videoPath, originalTitle]
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