def createExtrasCache(self, jsonGet, target, dbid): log("VideoExtrasService: Creating cache for %s" % target) json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.%s", "params": { "properties": ["title", "file"] }, "id": 1}' % jsonGet) json_query = unicode(json_query, 'utf-8', errors='ignore') json_query = simplejson.loads(json_query) extrasCacheString = "" if ("result" in json_query) and (target in json_query['result']): # Get the list of movies paths from the movie list returned items = json_query['result'][target] for item in items: # Check to see if exit has been called, if so stop if xbmc.abortRequested or xbmc.getCondVisibility("Window.IsVisible(shutdownmenu)"): return log("VideoExtrasService: %s detected: %s = %s" % (target, item['title'], item['file'])) videoExtras = VideoExtrasBase(item['file'], target, item['title']) # Only checking for the existence of extras - no need for DB or default Fanart firstExtraFile = videoExtras.findExtras(True) del videoExtras # Check if any extras exist for this movie if firstExtraFile: log("VideoExtrasService: Extras found for (%d) %s" % (item[dbid], item['title'])) extrasCacheString = ("%s[%d]%s" % (extrasCacheString, item[dbid], os.linesep)) # Add the overlay image for this item self._createOverlayFile(target, item[dbid], self.skinExtrasOverlay) self._createOverlayFile(target, item[dbid], self.skinExtrasOverlayList, VideoExtrasService.LIST_TAG) else: # No extras so remove the file if it exists self._removeOverlayFile(target, item[dbid]) self._removeOverlayFile(target, item[dbid], VideoExtrasService.LIST_TAG)
def editPlot(self, target, path, filename): # Create the extras class that will be used to process the extras videoExtras = VideoExtrasBase(path, target) # Perform the search command # We are only updating the NFO for an entry already shown, no need for fanart files = videoExtras.findExtras() del videoExtras for anExtra in files: if anExtra.isFilenameMatch(filename): log("MenuNavigator: Found = %s" % filename) # Prompt the user for the new name keyboard = xbmc.Keyboard() keyboard.setDefault(anExtra.getPlot()) keyboard.doModal() if keyboard.isConfirmed(): try: newplot = keyboard.getText().decode("utf-8") except: newplot = keyboard.getText() # Only set the title if it has changed if (newplot != anExtra.getPlot()) and ((len(newplot) > 0) or (anExtra.getPlot() is not None)): isTv = (target == MenuNavigator.TVSHOWS) result = anExtra.setPlot(newplot, isTV=isTv) if not result: xbmcgui.Dialog().ok(ADDON.getLocalizedString(32102), ADDON.getLocalizedString(32115)) else: # Update the display xbmc.executebuiltin("Container.Refresh")
def hasVideoExtras(self, target, dbid, file, title=None): # If the service is on, then we can just check to see if the overlay image exists if Settings.isServiceEnabled(): # Get the path where the file exists rootPath = os_path_join(PROFILE_DIR, target) if not dir_exists(rootPath): # Directory does not exist yet, so can't have extras return False # Generate the name of the file that the overlay will be copied to targetFile = os_path_join(rootPath, ("%d.png" % dbid)) if xbmcvfs.exists(targetFile): return True # Otherwise, need to do the lookup the old fashioned way of looking for the # extras files on the file system (This is much slower) else: videoExtras = VideoExtrasBase(file, target, title) # We are only checking for existence of extras, no need for fanart firstExtraFile = videoExtras.findExtras(True) del videoExtras if firstExtraFile: log("MenuNavigator: Extras found for (%d) %s" % (dbid, file)) return True return False
def playAllExtras(self, path, target, extrasParentTitle): # Check if the use database setting is enabled extrasDb = None if Settings.isDatabaseEnabled(): extrasDb = ExtrasDB() # Create the extras class that will be used to process the extras videoExtras = VideoExtrasBase(path, target, extrasParentTitle) # Perform the search command # No need for fanart default as only getting a list to play, not display files = videoExtras.findExtras(extrasDb=extrasDb) del videoExtras ExtrasPlayer.playAll(files, extrasParentTitle)
def findExtras(self, exitOnFirst=False, extrasDb=None, defaultFanArt=""): # Display the busy icon while searching for files xbmc.executebuiltin("ActivateWindow(busydialog)") files = VideoExtrasBase.findExtras(self, exitOnFirst, extrasDb, defaultFanArt) xbmc.executebuiltin("Dialog.Close(busydialog)") return files
def playExtra(self, path, target, filename, extrasParentTitle="", forceResume=False, fromStart=False): # Check if the use database setting is enabled extrasDb = None if Settings.isDatabaseEnabled(): extrasDb = ExtrasDB() # Create the extras class that will be used to process the extras videoExtras = VideoExtrasBase(path, target, extrasParentTitle) # Perform the search command # No need for fanart default as only getting a list to play, not display files = videoExtras.findExtras(extrasDb=extrasDb) del videoExtras for anExtra in files: if anExtra.isFilenameMatch(filename): log("MenuNavigator: Found = %s" % filename) # Check if we are forcing playback from the start if fromStart is not False: anExtra.setResumePoint(0) # If part way viewed prompt the user for resume or play from beginning if (anExtra.getResumePoint()) > 0 and (forceResume is not True): resumeWindow = VideoExtrasResumeWindow.createVideoExtrasResumeWindow( anExtra.getDisplayResumePoint()) resumeWindow.doModal() # Check the return value, if exit, then we play nothing if resumeWindow.isExit(): return # If requested to restart from beginning, reset the resume point before playing if resumeWindow.isRestart(): anExtra.setResumePoint(0) # Default is to actually resume ExtrasPlayer.performPlayAction(anExtra, extrasParentTitle)
def markAsUnwatched(self, path, target, filename): # If marking as watched we need to set the resume time so it doesn't # start in the middle the next time it starts if Settings.isDatabaseEnabled(): # Create the extras class that will be used to process the extras videoExtras = VideoExtrasBase(path, target) # Perform the search command extrasDb = ExtrasDB() # We are only updating the DB for an entry already shown, no need for fanart files = videoExtras.findExtras(extrasDb=extrasDb) del videoExtras del extrasDb for anExtra in files: if anExtra.isFilenameMatch(filename): log("MenuNavigator: Found = %s" % filename) anExtra.setResumePoint(0) anExtra.saveState() # Update the display xbmc.executebuiltin("Container.Refresh")
def playExtra(self, path, target, filename, extrasParentTitle="", forceResume=False, fromStart=False): # Check if the use database setting is enabled extrasDb = None if Settings.isDatabaseEnabled(): extrasDb = ExtrasDB() # Create the extras class that will be used to process the extras videoExtras = VideoExtrasBase(path, target, extrasParentTitle) # Perform the search command # No need for fanart default as only getting a list to play, not display files = videoExtras.findExtras(extrasDb=extrasDb) del videoExtras for anExtra in files: if anExtra.isFilenameMatch(filename): log("MenuNavigator: Found = %s" % filename) # Check if we are forcing playback from the start if fromStart is not False: anExtra.setResumePoint(0) # If part way viewed prompt the user for resume or play from beginning if (anExtra.getResumePoint()) > 0 and (forceResume is not True): resumeWindow = VideoExtrasResumeWindow.createVideoExtrasResumeWindow(anExtra.getDisplayResumePoint()) resumeWindow.doModal() # Check the return value, if exit, then we play nothing if resumeWindow.isExit(): return # If requested to restart from beginning, reset the resume point before playing if resumeWindow.isRestart(): anExtra.setResumePoint(0) # Default is to actually resume ExtrasPlayer.performPlayAction(anExtra, extrasParentTitle)
def editPlot(self, target, path, filename): # Create the extras class that will be used to process the extras videoExtras = VideoExtrasBase(path, target) # Perform the search command # We are only updating the NFO for an entry already shown, no need for fanart files = videoExtras.findExtras() del videoExtras for anExtra in files: if anExtra.isFilenameMatch(filename): log("MenuNavigator: Found = %s" % filename) # Prompt the user for the new name keyboard = xbmc.Keyboard() keyboard.setDefault(anExtra.getPlot()) keyboard.doModal() if keyboard.isConfirmed(): try: newplot = keyboard.getText().decode("utf-8") except: newplot = keyboard.getText() # Only set the title if it has changed if (newplot != anExtra.getPlot()) and ( (len(newplot) > 0) or (anExtra.getPlot() is not None)): isTv = (target == MenuNavigator.TVSHOWS) result = anExtra.setPlot(newplot, isTV=isTv) if not result: xbmcgui.Dialog().ok( ADDON.getLocalizedString(32102), ADDON.getLocalizedString(32115)) else: # Update the display xbmc.executebuiltin("Container.Refresh")
def checkIfVideoExtrasDisplay(self): # Check if the item that was played was a movie if xbmc.getInfoLabel("ListItem.dbtype") != 'movie': log("VideoExtrasPlayerMonitor: Was not a movie playing") return dbid = xbmc.getInfoLabel("ListItem.DBID") if dbid in [None, ""]: log("VideoExtrasPlayerMonitor: No DBID") return # Get the details for the extras title = xbmc.getInfoLabel("ListItem.Title") file = xbmc.getInfoLabel("ListItem.FilenameAndPath") if file in [None, ""]: file = xbmc.getInfoLabel("ListItem.Path") if file in [None, ""]: log("VideoExtrasPlayerMonitor: Unable to find playing file") return log("VideoExtrasPlayerMonitor: searching for: %s = %s" % (title, file)) videoExtras = VideoExtrasBase(file, Settings.MOVIES, title) # Only checking for the existence of extras - no need for DB or default Fanart firstExtraFile = videoExtras.findExtras(True) del videoExtras if not firstExtraFile: log("VideoExtrasPlayerMonitor: No extras for %s" % file) return # So there are extras, so now check to see if the movie was actually # completely viewed, we only want to display the extras for the movie # if the whole thing was viewed # It can take a little while for the database to be updated, so we need # to keep trying for a little while (3 seconds) playcount = None resumePosition = None lastResumeValue = None i = 30 while (i > 0) and (not xbmc.abortRequested): json_query = xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovieDetails", "params": {"movieid":%s, "properties": ["playcount", "resume"] }, "id": 1}' % str(dbid)) json_query = unicode(json_query, 'utf-8', errors='ignore') json_query = simplejson.loads(json_query) if ("result" in json_query) and ('moviedetails' in json_query['result']): # Get the movie details from the response movieDetails = json_query['result']['moviedetails'] if movieDetails in [None, ""]: return log("VideoExtrasPlayerMonitor: Database details: %s" % str(movieDetails)) # Get the playcount playcount = movieDetails['playcount'] if playcount not in [None, "", 0, "0"]: # As well as the playcount, we want to check if there is any resume data resumePosition = movieDetails['resume']['position'] # May take a little while for the resume to be updated, so we can wait for either # it changing or the timeout expires if lastResumeValue in [None, ""]: lastResumeValue = resumePosition elif lastResumeValue != resumePosition: if resumePosition not in ["0", 0]: playcount = None break i = i - 1 xbmc.sleep(100) if (playcount in [None, "", 0, "0"]) or (resumePosition not in [None, "0", 0]): log("VideoExtrasPlayerMonitor: Movie was not completed, no need to show extras") return # If we reach here, then we should show the extras log("VideoExtras: Showing extras for %s" % file) cmd = 'RunScript(script.videoextras,display,"%s")' % file xbmc.executebuiltin(cmd)
def showExtras(self, path, target, extrasParentTitle="", extrasDefaultFanArt="", extrasDefaultIconImage=""): # Check if the use database setting is enabled extrasDb = None if Settings.isDatabaseEnabled(): extrasDb = ExtrasDB() # Create the extras class that will be used to process the extras videoExtras = VideoExtrasBase(path, target, extrasParentTitle) # Perform the search command files = videoExtras.findExtras(extrasDb=extrasDb, defaultFanArt=extrasDefaultFanArt) del videoExtras tvShowTitle = "" if target == MenuNavigator.TVSHOWS: tvShowTitle = extrasParentTitle if len(files) > 0: # Start by adding an option to Play All anItem = xbmcgui.ListItem(ADDON.getLocalizedString(32101), path=path) # Get the first items fanart for the play all option anItem.setProperty("Fanart_Image", files[0].getFanArt()) if tvShowTitle != "": anItem.setInfo('video', {'TvShowTitle': tvShowTitle}) if extrasParentTitle != "": anItem.setInfo('video', {'Title': extrasParentTitle}) if extrasDefaultIconImage != "": anItem.setIconImage(extrasDefaultIconImage) anItem.addContextMenuItems([], replaceItems=True) url = self._build_url({ 'mode': 'playallextras', 'foldername': target, 'path': path, 'parentTitle': extrasParentTitle }) xbmcplugin.addDirectoryItem(handle=self.addon_handle, url=url, listitem=anItem, isFolder=False) # Check if we want to have YouTube Extra Support if Settings.isYouTubeSearchSupportEnabled(): self._getVideoPluginLink(extrasParentTitle, 'plugin.video.youtube', 32116, extrasDefaultIconImage, extrasDefaultFanArt) # Check if we want to have Vimeo Extra Support if Settings.isVimeoSearchSupportEnabled(): self._getVideoPluginLink(extrasParentTitle, 'plugin.video.vimeo', 32122, extrasDefaultIconImage, extrasDefaultFanArt) # Add each of the extras to the list to display for anExtra in files: # Create the list item li = anExtra.createListItem( parentTitle=extrasParentTitle, tvShowTitle=tvShowTitle, defaultIconImage=extrasDefaultIconImage) # Hack, if the "TotalTime" and "ResumeTime" are set on the list item # and it is partially watched, then Kodi will display the continue dialog # However we can not get what the user selects from this dialog, so it # will always continue. Found out that we can hack this by clearing # the "TotalTime" property # http://forum.xbmc.org/showthread.php?tid=192627 li.setProperty("TotalTime", "") li.addContextMenuItems([], replaceItems=True) li.addContextMenuItems(self._getContextMenu( anExtra, target, path, extrasParentTitle), replaceItems=True) url = self._build_url({ 'mode': 'playextra', 'foldername': target, 'path': path, 'filename': anExtra.getFilename().encode("utf-8"), 'parentTitle': extrasParentTitle }) xbmcplugin.addDirectoryItem(handle=self.addon_handle, url=url, listitem=li, isFolder=False) xbmcplugin.endOfDirectory(self.addon_handle)
def showExtras(self, path, target, extrasParentTitle="", extrasDefaultFanArt="", extrasDefaultIconImage=""): # Check if the use database setting is enabled extrasDb = None if Settings.isDatabaseEnabled(): extrasDb = ExtrasDB() # Create the extras class that will be used to process the extras videoExtras = VideoExtrasBase(path, target, extrasParentTitle) # Perform the search command files = videoExtras.findExtras(extrasDb=extrasDb, defaultFanArt=extrasDefaultFanArt) del videoExtras tvShowTitle = "" if target == MenuNavigator.TVSHOWS: tvShowTitle = extrasParentTitle if len(files) > 0: # Start by adding an option to Play All anItem = xbmcgui.ListItem(ADDON.getLocalizedString(32101), path=path) # Get the first items fanart for the play all option anItem.setProperty("Fanart_Image", files[0].getFanArt()) if tvShowTitle != "": anItem.setInfo('video', {'TvShowTitle': tvShowTitle}) if extrasParentTitle != "": anItem.setInfo('video', {'Title': extrasParentTitle}) if extrasDefaultIconImage != "": anItem.setIconImage(extrasDefaultIconImage) anItem.addContextMenuItems([], replaceItems=True) url = self._build_url({'mode': 'playallextras', 'foldername': target, 'path': path, 'parentTitle': extrasParentTitle}) xbmcplugin.addDirectoryItem(handle=self.addon_handle, url=url, listitem=anItem, isFolder=False) # Check if we want to have YouTube Extra Support if Settings.isYouTubeSearchSupportEnabled(): self._getVideoPluginLink(extrasParentTitle, 'plugin.video.youtube', 32116, extrasDefaultIconImage, extrasDefaultFanArt) # Check if we want to have Vimeo Extra Support if Settings.isVimeoSearchSupportEnabled(): self._getVideoPluginLink(extrasParentTitle, 'plugin.video.vimeo', 32122, extrasDefaultIconImage, extrasDefaultFanArt) # Add each of the extras to the list to display for anExtra in files: # Create the list item li = anExtra.createListItem(parentTitle=extrasParentTitle, tvShowTitle=tvShowTitle, defaultIconImage=extrasDefaultIconImage) # Hack, if the "TotalTime" and "ResumeTime" are set on the list item # and it is partially watched, then Kodi will display the continue dialog # However we can not get what the user selects from this dialog, so it # will always continue. Found out that we can hack this by clearing # the "TotalTime" property # http://forum.xbmc.org/showthread.php?tid=192627 li.setProperty("TotalTime", "") li.addContextMenuItems([], replaceItems=True) li.addContextMenuItems(self._getContextMenu(anExtra, target, path, extrasParentTitle), replaceItems=True) url = self._build_url({'mode': 'playextra', 'foldername': target, 'path': path, 'filename': anExtra.getFilename().encode("utf-8"), 'parentTitle': extrasParentTitle}) xbmcplugin.addDirectoryItem(handle=self.addon_handle, url=url, listitem=li, isFolder=False) xbmcplugin.endOfDirectory(self.addon_handle)