def _moveToThemeFolder(self, directory): log("moveToThemeFolder: path = %s" % directory) # Handle the case where we have a disk image if (os_path_split(directory)[1] == 'VIDEO_TS') or (os_path_split(directory)[1] == 'BDMV'): directory = os_path_split(directory)[0] dirs, files = list_dir(directory) for aFile in files: m = re.search(Settings.getThemeFileRegEx(directory), aFile, re.IGNORECASE) if m: srcpath = os_path_join(directory, aFile) log("fetchAllMissingThemes: Found match: %s" % srcpath) targetpath = os_path_join(directory, Settings.getThemeDirectory()) # Make sure the theme directory exists if not dir_exists(targetpath): try: xbmcvfs.mkdir(targetpath) except: log( "fetchAllMissingThemes: Failed to create directory: %s" % targetpath, True, LOGERROR) break else: log("moveToThemeFolder: directory already exists %s" % targetpath) # Add the filename to the path targetpath = os_path_join(targetpath, aFile) if not xbmcvfs.rename(srcpath, targetpath): log("moveToThemeFolder: Failed to move file from %s to %s" % (srcpath, targetpath))
def _moveToThemeFolder(self, directory): log("moveToThemeFolder: path = %s" % directory) # Handle the case where we have a disk image if (os_path_split(directory)[1] == 'VIDEO_TS') or (os_path_split(directory)[1] == 'BDMV'): directory = os_path_split(directory)[0] dirs, files = list_dir(directory) for aFile in files: m = re.search(Settings.getThemeFileRegEx(directory), aFile, re.IGNORECASE) if m: srcpath = os_path_join(directory, aFile) log("fetchAllMissingThemes: Found match: %s" % srcpath) targetpath = os_path_join(directory, Settings.getThemeDirectory()) # Make sure the theme directory exists if not dir_exists(targetpath): try: xbmcvfs.mkdir(targetpath) except: log("fetchAllMissingThemes: Failed to create directory: %s" % targetpath, True, xbmc.LOGERROR) break else: log("moveToThemeFolder: directory already exists %s" % targetpath) # Add the filename to the path targetpath = os_path_join(targetpath, aFile) if not xbmcvfs.rename(srcpath, targetpath): log("moveToThemeFolder: Failed to move file from %s to %s" % (srcpath, targetpath))
def _generateThemeFilelist(self, rawPath): # Get the full path with any network alterations workingPath = self._getUsablePath(rawPath) themeList = self._getThemeFiles(workingPath) # If no themes have been found if len(themeList) < 1: # TV shows stored as ripped disc folders if ('VIDEO_TS' in workingPath) or ('BDMV' in workingPath): log("ThemeFiles: Found VIDEO_TS or BDMV in path: Correcting the path for DVDR tv shows", self.debug_logging_enabled) workingPath = os_path_split(workingPath)[0] themeList = self._getThemeFiles(workingPath) if len(themeList) < 1: workingPath = os_path_split(workingPath)[0] themeList = self._getThemeFiles(workingPath) else: # If no theme files were found in this path, look at the parent directory workingPath = os_path_split(workingPath)[0] # Check for the case where there is the theme forlder settings, we want to # check the parent folders themes directory if Settings.isThemeDirEnabled(): themeDir = os_path_join(workingPath, Settings.getThemeDirectory()) themeList = self._getThemeFiles(themeDir) # If there are still no themes, just check the parent directory if len(themeList) < 1: themeList = self._getThemeFiles(workingPath) log("ThemeFiles: Playlist size = %d" % len(themeList), self.debug_logging_enabled) log("ThemeFiles: Working Path = %s" % workingPath, self.debug_logging_enabled) return themeList
def _doesThemeExist(self, directory, checkParent=False, incAudioThemes=True, incVideoThemes=True): log("doesThemeExist: Checking directory: %s" % directory) # Check for custom theme directory if Settings.isThemeDirEnabled(): themeDir = os_path_join(directory, Settings.getThemeDirectory()) # Check if this directory exists if not dir_exists(themeDir): workingPath = directory # If the path currently ends in the directory separator # then we need to clear an extra one if (workingPath[-1] == os.sep) or (workingPath[-1] == os.altsep): workingPath = workingPath[:-1] # If not check to see if we have a DVD VOB if (os_path_split(workingPath)[1] == 'VIDEO_TS') or (os_path_split(workingPath)[1] == 'BDMV'): # Check the parent of the DVD Dir themeDir = os_path_split(workingPath)[0] themeDir = os_path_join(themeDir, Settings.getThemeDirectory()) directory = themeDir # Check to see if we need to check the parent directory if checkParent: directory = os_path_split(directory)[0] # check if the directory exists before searching if dir_exists(directory): # Generate the regex audioOnly = False videoOnly = False if not incAudioThemes: videoOnly = True if not incVideoThemes: audioOnly = True themeFileRegEx = Settings.getThemeFileRegEx(audioOnly=audioOnly, videoOnly=videoOnly) dirs, files = list_dir(directory) for aFile in files: m = re.search(themeFileRegEx, aFile, re.IGNORECASE) if m: log("doesThemeExist: Found match: " + aFile) return True # Check if an NFO file exists nfoFileName = os_path_join(directory, "tvtunes.nfo") if xbmcvfs.exists(nfoFileName): log("doesThemeExist: Found match: " + nfoFileName) return True return False
def _doesThemeExist(self, directory, checkParent=False, incAudioThemes=True, incVideoThemes=True): log("doesThemeExist: Checking directory: %s" % directory) # Check for custom theme directory if Settings.isThemeDirEnabled(): themeDir = os_path_join(directory, Settings.getThemeDirectory()) # Check if this directory exists if not dir_exists(themeDir): workingPath = directory # If the path currently ends in the directory separator # then we need to clear an extra one if (workingPath[-1] == os.sep) or (workingPath[-1] == os.altsep): workingPath = workingPath[:-1] # If not check to see if we have a DVD VOB if (os_path_split(workingPath)[1] == 'VIDEO_TS') or (os_path_split(workingPath)[1] == 'BDMV'): # Check the parent of the DVD Dir themeDir = os_path_split(workingPath)[0] themeDir = os_path_join(themeDir, Settings.getThemeDirectory()) directory = themeDir # Check to see if we need to check the parent directory if checkParent: directory = os_path_split(directory)[0] # check if the directory exists before searching if dir_exists(directory): # Generate the regex audioOnly = False videoOnly = False if not incAudioThemes: videoOnly = True if not incVideoThemes: audioOnly = True themeFileRegEx = Settings.getThemeFileRegEx(audioOnly=audioOnly, videoOnly=videoOnly) dirs, files = list_dir(directory) for aFile in files: m = re.search(themeFileRegEx, aFile, re.IGNORECASE) if m: log("doesThemeExist: Found match: " + aFile) return True # Check if an NFO file exists nfoFileName = os_path_join(directory, "tvtunes.nfo") if xbmcvfs.exists(nfoFileName): log("doesThemeExist: Found match: " + nfoFileName) return True return False
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 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 _generateThemeFilelistWithDirs(self, rawPath): themeFiles = [] # Check the theme directory if it is set up if Settings.isThemeDirEnabled(): themeDir = self._getUsablePath(rawPath) themeDir = os_path_join(themeDir, Settings.getThemeDirectory()) themeFiles = self._generateThemeFilelist(themeDir) # Check for the case where there is a DVD directory and the themes # directory is above it if len(themeFiles) < 1: if ('VIDEO_TS' in rawPath) or ('BDMV' in rawPath): log("ThemeFiles: Found VIDEO_TS in path: Correcting the path for DVDR tv shows", self.debug_logging_enabled) themeDir = self._getUsablePath(rawPath) themeDir = os_path_split(themeDir)[0] themeDir = os_path_join(themeDir, Settings.getThemeDirectory()) themeFiles = self._generateThemeFilelist(themeDir) # If no themes were found in the directory then search the normal location if len(themeFiles) < 1: themeFiles = self._generateThemeFilelist(rawPath) return themeFiles
def _getUsablePath(self, rawPath): workingPath = rawPath # Start by removing the stack details if workingPath.startswith("stack://"): workingPath = workingPath.replace("stack://", "").split(" , ", 1)[0] if Settings.isSmbEnabled() and not ('@' in workingPath): if workingPath.startswith("smb://"): log("### Try authentication share") workingPath = workingPath.replace("smb://", "smb://%s:%s@" % (Settings.getSmbUser(), Settings.getSmbPassword())) log("### %s" % workingPath) # Also handle the apple format elif workingPath.startswith("afp://"): log("### Try authentication share") workingPath = workingPath.replace("afp://", "afp://%s:%s@" % (Settings.getSmbUser(), Settings.getSmbPassword())) log("### %s" % workingPath) # handle episodes stored as rar files if workingPath.startswith("rar://"): workingPath = workingPath.replace("rar://", "") fileExt = None if os_path_isfile(workingPath): fileExt = os.path.splitext(workingPath)[1] # If this is a file, then get it's parent directory # Also limit file extensions to a maximum of 4 characters if fileExt is not None and fileExt != "" and len(fileExt) < 5: workingPath = os_path_split(workingPath)[0] # If the path currently ends in the directory separator # then we need to clear an extra one if (workingPath[-1] == os.sep) or (workingPath[-1] == os.altsep): workingPath = workingPath[:-1] return workingPath
def _loadFromFile(self): # Get the videos schedule that is stored in the file scheduleFileName = Settings.getScheduleFile() if scheduleFileName in [None, ""]: log("Schedule: No schedule file set") return log("Schedule: Searching for schedule file: %s" % scheduleFileName) # Return False if file does not exist if not xbmcvfs.exists(scheduleFileName): log("Schedule: No schedule file found: %s" % scheduleFileName) return # Save off the time this file was modified statFile = xbmcvfs.Stat(scheduleFileName) self.lastScheduleModified = statFile.st_mtime() log("Schedule: Reading in schedule file with modify time: %s" % str(self.lastScheduleModified)) # The file exists, so start loading it try: # Need to first load the contents of the file into # a string, this is because the XML File Parse option will # not handle formats like smb:// scheduleFile = xbmcvfs.File(scheduleFileName, 'r') scheduleFileStr = scheduleFile.read() scheduleFile.close() # Create an XML parser scheduleXml = ET.ElementTree(ET.fromstring(scheduleFileStr)) rootElement = scheduleXml.getroot() log("Schedule: Root element is = %s" % rootElement.tag) # Check which format if being used if rootElement.tag == "schedule": log("Schedule: Schedule format file detected") # <schedule> # <rule start="14:24" end="14:37" video="video3.mkv" overlay="WindowFrame1.png" /> # </schedule> # Get the directory that the schedule file is in as this might be needed # if we have local paths in the XML file directory = os_path_split(scheduleFileName)[0] # There could be multiple rule entries, so loop through all of them itemNum = self.idOffset + 1 for ruleElem in scheduleXml.findall('rule'): if ruleElem is not None: videoFile = ruleElem.get('video', None) overlayFile = ruleElem.get('overlay', None) startTime = self._convertTimeToMinutes(ruleElem.get('start', "00:00")) endTime = self._convertTimeToMinutes(ruleElem.get('end', "00:00")) day = self._convertDayFormat(ruleElem.get('day', None)) if (videoFile not in [None, ""]) and (startTime not in [None, ""]) and (endTime not in [None, ""]): # Make it a full path if it is not already if videoFile.startswith('..') or (("/" not in videoFile) and ("\\" not in videoFile)): videoFile = os_path_join(directory, videoFile) if overlayFile not in [None, ""]: if overlayFile.startswith('..') or (("/" not in overlayFile) and ("\\" not in overlayFile)): overlayFile = os_path_join(directory, overlayFile) log("Schedule File: Item %d (Start:%d, End:%d) contains video %s" % (itemNum, startTime, endTime, videoFile)) # Check if the video file exists if os_path_isfile(videoFile): details = {'id': itemNum, 'start': startTime, 'end': endTime, 'day': day, 'video': videoFile, 'overlay': overlayFile} self.scheduleDetails.append(details) else: log("Schedule: File does not exist: %s" % videoFile) itemNum = itemNum + 1 else: log("Schedule: Unknown schedule file format") del scheduleXml except: log("Schedule: Failed to process schedule file: %s" % scheduleFileName, xbmc.LOGERROR) log("Schedule: %s" % traceback.format_exc(), xbmc.LOGERROR)
def _getPlaylist(self): playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) # Note: The playlist clear option seems to impact all playlist settings, # so will remove the repeat settings on a playlist that is currently playing, # not just this instance - a bit nasty, but not much we can do about it playlist.clear() # Check to see if we should be using a video from the schedule scheduleEntry = self.scheduler.getScheduleEntry() if scheduleEntry != -1: # There is an item scheduled, so check to see if the item has actually changed if scheduleEntry == self.currentScheduleItem: return None # Set the entry we are about to play self.currentScheduleItem = scheduleEntry # Get the actual video file that should be played scheduledVideo = self.scheduler.getScheduleVideo(scheduleEntry) # Do a quick check to see if the video exists if xbmcvfs.exists(scheduledVideo): log("Screensaver video for scheduled item %d is: %s" % (scheduleEntry, scheduledVideo)) playlist.add(scheduledVideo) # Check if we are showing all the videos in a given folder elif Settings.isFolderSelection(): videosFolder = Settings.getScreensaverFolder() # Check if we are dealing with a Folder of videos if videosFolder not in [None, ""]: if dir_exists(videosFolder): self.currentScheduleItem = -1 files = self._getAllFilesInDirectory(videosFolder) # Check if we are limiting to a single folder per session if Settings.isLimitSessionToSingleCollection(): # Select just one file at random singleVideo = random.choice(files) # Check if this file is part of a collection justFilename = (os_path_split(singleVideo))[-1] collectionCtrl = CollectSets() collectionVideos = collectionCtrl.getFilesInSameCollection(justFilename) del collectionCtrl # If it is part of a collection, then limit to only files in # this collection if len(collectionVideos) > 0: log("Screensaver restricting to collection containing %s" % singleVideo) # Check each of the videos to see which are in the collection collectionFileList = [] for aFile in files: # Get just the filename aFilename = (os_path_split(aFile))[-1] if aFilename in collectionVideos: log("Screensaver including collection video %s" % aFile) collectionFileList.append(aFile) else: log("Screensaver excluding non collection video %s" % aFile) else: log("Screensaver restricting to directory containing %s" % singleVideo) # Not in a collection, so just gather the files in the same directory # Get the directory that file was part of parentPath = (os_path_split(singleVideo))[0] # Now only select videos from that directory files = self._getAllFilesInDirectory(parentPath, False) # Now shuffle the playlist to ensure that if there are more # than one video a different one starts each time random.shuffle(files) for vidFile in files: log("Screensaver video in directory is: %s" % vidFile) playlist.add(vidFile) else: # Must be dealing with a single file videoFile = Settings.getScreensaverVideo() # Check to make sure the screensaver video file exists if videoFile not in [None, ""]: if xbmcvfs.exists(videoFile): self.currentScheduleItem = -1 log("Screensaver video is: %s" % videoFile) playlist.add(videoFile) # If there are no videos in the playlist yet, then display an error if playlist.size() < 1: errorLocation = Settings.getScreensaverVideo() if Settings.isFolderSelection(): errorLocation = Settings.getScreensaverFolder() log("No Screensaver file set or not valid %s" % errorLocation) cmd = 'Notification("{0}", "{1}", 3000, "{2}")'.format(ADDON.getLocalizedString(32300).encode('utf-8'), errorLocation, ADDON.getAddonInfo('icon')) xbmc.executebuiltin(cmd) return None return playlist
def _loadFromFile(self): # Get the videos schedule that is stored in the file scheduleFileName = Settings.getScheduleFile() if scheduleFileName in [None, ""]: log("Schedule: No schedule file set") return log("Schedule: Searching for schedule file: %s" % scheduleFileName) # Return False if file does not exist if not xbmcvfs.exists(scheduleFileName): log("Schedule: No schedule file found: %s" % scheduleFileName) return # Save off the time this file was modified statFile = xbmcvfs.Stat(scheduleFileName) self.lastScheduleModified = statFile.st_mtime() log("Schedule: Reading in schedule file with modify time: %s" % str(self.lastScheduleModified)) # The file exists, so start loading it try: # Need to first load the contents of the file into # a string, this is because the XML File Parse option will # not handle formats like smb:// scheduleFile = xbmcvfs.File(scheduleFileName, 'r') scheduleFileStr = scheduleFile.read() scheduleFile.close() # Create an XML parser scheduleXml = ET.ElementTree(ET.fromstring(scheduleFileStr)) rootElement = scheduleXml.getroot() log("Schedule: Root element is = %s" % rootElement.tag) # Check which format if being used if rootElement.tag == "schedule": log("Schedule: Schedule format file detected") # <schedule> # <rule start="14:24" end="14:37" video="video3.mkv" overlay="WindowFrame1.png" /> # </schedule> # Get the directory that the schedule file is in as this might be needed # if we have local paths in the XML file directory = os_path_split(scheduleFileName)[0] # There could be multiple rule entries, so loop through all of them itemNum = self.idOffset + 1 for ruleElem in scheduleXml.findall('rule'): if ruleElem is not None: videoFile = ruleElem.get('video', None) overlayFile = ruleElem.get('overlay', None) startTime = self._convertTimeToMinutes( ruleElem.get('start', "00:00")) endTime = self._convertTimeToMinutes( ruleElem.get('end', "00:00")) day = self._convertDayFormat(ruleElem.get('day', None)) if (videoFile not in [None, ""]) and (startTime not in [ None, "" ]) and (endTime not in [None, ""]): # Make it a full path if it is not already if videoFile.startswith('..') or ( ("/" not in videoFile) and ("\\" not in videoFile)): videoFile = os_path_join(directory, videoFile) if overlayFile not in [None, ""]: if overlayFile.startswith('..') or ( ("/" not in overlayFile) and ("\\" not in overlayFile)): overlayFile = os_path_join( directory, overlayFile) log("Schedule File: Item %d (Start:%d, End:%d) contains video %s" % (itemNum, startTime, endTime, videoFile)) # Check if the video file exists if os_path_isfile(videoFile): details = { 'id': itemNum, 'start': startTime, 'end': endTime, 'day': day, 'video': videoFile, 'overlay': overlayFile } self.scheduleDetails.append(details) else: log("Schedule: File does not exist: %s" % videoFile) itemNum = itemNum + 1 else: log("Schedule: Unknown schedule file format") del scheduleXml except: log( "Schedule: Failed to process schedule file: %s" % scheduleFileName, xbmc.LOGERROR) log("Schedule: %s" % traceback.format_exc(), xbmc.LOGERROR)
def _getPlaylist(self): playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) # Note: The playlist clear option seems to impact all playlist settings, # so will remove the repeat settings on a playlist that is currently playing, # not just this instance - a bit nasty, but not much we can do about it playlist.clear() # Check to see if we should be using a video from the schedule scheduleEntry = self.scheduler.getScheduleEntry() if scheduleEntry != -1: # There is an item scheduled, so check to see if the item has actually changed if scheduleEntry == self.currentScheduleItem: return None # Set the entry we are about to play self.currentScheduleItem = scheduleEntry # Get the actual video file that should be played scheduledVideo = self.scheduler.getScheduleVideo(scheduleEntry) # Do a quick check to see if the video exists if xbmcvfs.exists(scheduledVideo): log("Screensaver video for scheduled item %d is: %s" % (scheduleEntry, scheduledVideo)) playlist.add(scheduledVideo) # Check if we are showing all the videos in a given folder elif Settings.isFolderSelection(): videosFolder = Settings.getScreensaverFolder() # Check if we are dealing with a Folder of videos if videosFolder not in [None, ""]: if dir_exists(videosFolder): self.currentScheduleItem = -1 files = self._getAllFilesInDirectory(videosFolder) # Check if we are limiting to a single folder per session if Settings.isLimitSessionToSingleCollection(): # Select just one file at random singleVideo = random.choice(files) # Check if this file is part of a collection justFilename = (os_path_split(singleVideo))[-1] collectionCtrl = CollectSets() collectionVideos = collectionCtrl.getFilesInSameCollection( justFilename) del collectionCtrl # If it is part of a collection, then limit to only files in # this collection if len(collectionVideos) > 0: log("Screensaver restricting to collection containing %s" % singleVideo) # Check each of the videos to see which are in the collection collectionFileList = [] for aFile in files: # Get just the filename aFilename = (os_path_split(aFile))[-1] if aFilename in collectionVideos: log("Screensaver including collection video %s" % aFile) collectionFileList.append(aFile) else: log("Screensaver excluding non collection video %s" % aFile) else: log("Screensaver restricting to directory containing %s" % singleVideo) # Not in a collection, so just gather the files in the same directory # Get the directory that file was part of parentPath = (os_path_split(singleVideo))[0] # Now only select videos from that directory files = self._getAllFilesInDirectory( parentPath, False) # Now shuffle the playlist to ensure that if there are more # than one video a different one starts each time random.shuffle(files) for vidFile in files: log("Screensaver video in directory is: %s" % vidFile) playlist.add(vidFile) else: # Must be dealing with a single file videoFile = Settings.getScreensaverVideo() # Check to make sure the screensaver video file exists if videoFile not in [None, ""]: if xbmcvfs.exists(videoFile): self.currentScheduleItem = -1 log("Screensaver video is: %s" % videoFile) playlist.add(videoFile) # If there are no videos in the playlist yet, then display an error if playlist.size() < 1: errorLocation = Settings.getScreensaverVideo() if Settings.isFolderSelection(): errorLocation = Settings.getScreensaverFolder() log("No Screensaver file set or not valid %s" % errorLocation) cmd = 'Notification("{0}", "{1}", 3000, "{2}")'.format( ADDON.getLocalizedString(32300).encode('utf-8'), errorLocation, ADDON.getAddonInfo('icon')) xbmc.executebuiltin(cmd) return None return playlist
def addCustomCollection(self, customXmlFile): log("CollectSets: Checking custom xml file: %s" % customXmlFile) # Try and load the collection file to ensure all the data is correct collectionDetails = self.loadCollection(customXmlFile, False) if collectionDetails in [None, ""]: log("CollectSets: No collection details returned for %s" % customXmlFile) # TODO: Show error return False collectionName = collectionDetails['name'] if collectionName.lower() in [ 'aquarium', 'beach', 'clock', 'fireplace', 'miscellaneous', 'snow', 'space', 'waterfall', 'apple tv' ]: log("CollectSets: Collection name clashes %s" % collectionName) # We return True here, as we have already displayed an error msg = "%s: %s" % (ADDON.getLocalizedString(32084), collectionName) xbmcgui.Dialog().notification(ADDON.getLocalizedString(32005), msg, ICON, 5000, False) return True # check the number of videos if len(collectionDetails['videos']) < 1: log("CollectSets: Collection contains no videos %s" % customXmlFile) # TODO: Show error return False # Check each of the settings for a video, must have name, filename and primary for videoItem in collectionDetails['videos']: if videoItem['name'] in [None, ""]: log("CollectSets: Video without a name in collection %s" % customXmlFile) # TODO: Show error return False if videoItem['filename'] in [None, ""]: log("CollectSets: Video without a filename in collection %s" % customXmlFile) # TODO: Show error return False if videoItem['primary'] in [None, ""]: log("CollectSets: Video without a primary in collection %s" % customXmlFile) # TODO: Show error return False customCollections = self.getCustomCollectionSets() # Add check to see if it clashes with a different custom collection if collectionName in customCollections.keys(): log("CollectSets: Custom collection name clashes %s" % collectionName) # We return True here, as we have already displayed an error msg = "%s: %s" % (ADDON.getLocalizedString(32084), collectionName) xbmcgui.Dialog().notification(ADDON.getLocalizedString(32005), msg, ICON, 5000, False) return True # If we have reached here then we are OK to add the custom set, so take a copy of # it to the addon settings directory finalCustomXmlFile = os_path_join(Settings.getCustomFolder(), os_path_split(customXmlFile)[-1]) log("CollectSets: Copy from %s to %s" % (customXmlFile, finalCustomXmlFile)) copy = xbmcvfs.copy(customXmlFile, finalCustomXmlFile) if copy: # Now get the details that are required for the collection customCollections[collectionName] = { 'name': collectionName, 'filename': finalCustomXmlFile, 'image': collectionDetails['image'], 'default': False } # save the new set of custom collections self.saveCustomCollections(customCollections) return True
# are, on windows we should already have them defaultFFmpegSetting = Settings.FFMPEG_NONE # First location to check is the location defined in the settings libLocation = None # First check the player directory playerDir = xbmc.translatePath('special://xbmc/system/players/dvdplayer/').decode("utf-8") libLocation = FFMpegLib.getPlatformLibFiles(playerDir) if libLocation is None: # Then check the root directory, sometimes they are there rootDir = xbmc.translatePath('special://xbmc/').decode("utf-8") libLocation = FFMpegLib.getPlatformLibFiles(rootDir) if libLocation is not None: libPath = os_path_split(libLocation['avutil'])[0] log("AudioBookService: Detected library path as %s" % libPath) Settings.setFFmpegLibraryLocation(libPath) # If the libraries are there, enable them as the default defaultFFmpegSetting = Settings.FFMPEG_LIB # Now check to see if we have one of the FFmpeg bundles installed if xbmc.getCondVisibility('System.HasAddon(script.module.ffmpeg)') != 1: log("AudioBookService: No script.module.ffmpeg bundle detected") else: log("AudioBookService: script.module.ffmpeg bundle detected") ffmpegModule = xbmcaddon.Addon(id='script.module.ffmpeg') modulePath = ffmpegModule.getAddonInfo('path') log("AudioBookService: FFmpeg addon path is: %s" % modulePath) # Make sure the addon path exists
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 = 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