def getMusicVideos(self, itemList = []): result = [] doUtils = DownloadUtils() #only get basic info for our sync-compares sortstring = "&SortBy=SortName" url = "{server}/mediabrowser/Users/{UserId}/items?%s&Fields=CumulativeRunTimeTicks,Etag&Recursive=true&SortOrder=Descending&IncludeItemTypes=MusicVideo&CollapseBoxSetItems=false&format=json&ImageTypeLimit=1" % sortstring jsonData = doUtils.downloadUrl(url) if (jsonData == ""): return result if (jsonData[u'Items'] != ""): result = jsonData[u'Items'] # Work around to only return items from the given list if (result != None and len(result) > 0 and len(itemList) > 0): newResult = [] for item in result: if (item[u'Id'] in itemList): newResult.append(item) result = newResult return result
def getViewCollections(self, type): #Build a list of the user views doUtils = DownloadUtils() viewsUrl = "{server}/mediabrowser/Users/{UserId}/Views?format=json&ImageTypeLimit=1" jsonData = doUtils.downloadUrl(viewsUrl) collections=[] if (jsonData != ""): views = views[u'Items'] for view in views: if (view[u'Type'] == 'UserView'): # Need to grab the real main node newViewsUrl = "{server}/mediabrowser/Users/{UserId}/items?ParentId=%s&SortBy=SortName&SortOrder=Ascending&format=json&ImageTypeLimit=1" % view[u'Id'] jsonData = doUtils.downloadUrl(newViewsUrl) if (jsonData != ""): newViews = newViews[u'Items'] for newView in newViews: # There are multiple nodes in here like 'Latest', 'NextUp' - below we grab the full node. if newView[u'CollectionType'] == "MovieMovies" or newView[u'CollectionType'] == "TvShowSeries": view=newView if (view[u'ChildCount'] != 0): Name = view[u'Name'] total = str(view[u'ChildCount']) type = view[u'CollectionType'] if type == None: type = "None" # User may not have declared the type if type == type: collections.append( {'title' : Name, 'type' : type, 'id' : view[u'Id']}) return collections
def getMovies(self, id, fullinfo = False, fullSync = True, itemList = []): result = None doUtils = DownloadUtils() if fullSync: sortstring = "&SortBy=SortName" else: if(len(itemList) > 0): # if we want a certain list specify it #sortstring = "&Ids=" + ",".join(itemList) sortstring = "" # work around for now until ParetnId and Id work together else: # just get the last 20 created items sortstring = "&Limit=20&SortBy=DateCreated" if fullinfo: url = "{server}/mediabrowser/Users/{UserId}/items?ParentId=%s%s&Fields=Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&SortOrder=Descending&IncludeItemTypes=Movie&CollapseBoxSetItems=false&format=json&ImageTypeLimit=1" % (id, sortstring) else: url = "{server}/mediabrowser/Users/{UserId}/items?ParentId=%s%s&Fields=CumulativeRunTimeTicks&Recursive=true&SortOrder=Descending&IncludeItemTypes=Movie&CollapseBoxSetItems=false&format=json&ImageTypeLimit=1" % (id, sortstring) jsonData = doUtils.downloadUrl(url) if (jsonData == ""): return result if (jsonData[u'Items'] != ""): result = jsonData[u'Items'] # work around for now until ParetnId and Id work together if (result != None and len(result) > 0 and len(itemList) > 0): newResult = [] for item in result: if (item[u'Id'] in itemList): newResult.append(item) result = newResult return result
def getMusicAlbums(self, itemList = []): result = [] doUtils = DownloadUtils() #only get basic info for our sync-compares url = "{server}/mediabrowser/Users/{UserId}/Items?Fields=Name,CumulativeRunTimeTicks,Etag&Recursive=true&IncludeItemTypes=MusicAlbum&format=json" jsonData = doUtils.downloadUrl(url) if (jsonData == ""): return result if (jsonData[u'Items'] != ""): result = jsonData[u'Items'] #only return valid albums - which have artists tempresult = [] for item in result: if item["AlbumArtists"]: tempresult.append(item) result = tempresult # Work around to only return items from the given list if (result != None and len(result) > 0 and len(itemList) > 0): newResult = [] for item in result: if (item[u'Id'] in itemList): newResult.append(item) result = newResult return result
def getMusicVideos(self, fullinfo = False, fullSync = True): result = None addon = xbmcaddon.Addon(id='plugin.video.emby') port = addon.getSetting('port') host = addon.getSetting('ipaddress') server = host + ":" + port downloadUtils = DownloadUtils() userid = downloadUtils.getUserId() if not fullSync: sortstring = "&Limit=20&SortBy=DateCreated" else: sortstring = "&SortBy=SortName" if fullinfo: url = server + '/mediabrowser/Users/' + userid + '/items?' + sortstring + '&Fields=Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&SortOrder=Descending&IncludeItemTypes=MusicVideo&format=json&ImageTypeLimit=1' else: url = server + '/mediabrowser/Users/' + userid + '/items?' + sortstring + '&Fields=CumulativeRunTimeTicks&Recursive=true&SortOrder=Descending&IncludeItemTypes=MusicVideo&CollapseBoxSetItems=false&format=json&ImageTypeLimit=1' jsonData = downloadUtils.downloadUrl(url, suppress=False, popup=0) if jsonData != None and jsonData != "": result = json.loads(jsonData) if(result.has_key('Items')): result = result['Items'] return result
def getMusicAlbums(self, itemList = []): result = [] doUtils = DownloadUtils() #only get basic info for our sync-compares url = "{server}/mediabrowser/Users/{UserId}/Items?Fields=Etag,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&IncludeItemTypes=MusicAlbum&format=json" jsonData = doUtils.downloadUrl(url) if (jsonData == ""): return result if (jsonData[u'Items'] != ""): result = jsonData[u'Items'] #only return valid albums - which have artists tempresult = [] for item in result: if item["AlbumArtists"]: tempresult.append(item) result = tempresult # Work around to only return items from the given list if (result != None and len(result) > 0 and len(itemList) > 0): newResult = [] for item in result: if (item[u'Id'] in itemList): newResult.append(item) result = newResult return result
def getLatestEpisodes(self, fullinfo = False, itemList = []): result = None addon = xbmcaddon.Addon(id='plugin.video.emby') port = addon.getSetting('port') host = addon.getSetting('ipaddress') server = host + ":" + port downloadUtils = DownloadUtils() userid = downloadUtils.getUserId() limitString = "Limit=20&SortBy=DateCreated&" if(len(itemList) > 0): # if we want a certain list specify it limitString = "Ids=" + ",".join(itemList) + "&" if fullinfo: url = server + '/mediabrowser/Users/' + userid + '/Items?' + limitString + 'IsVirtualUnaired=false&IsMissing=False&Fields=ParentId,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&SortOrder=Descending&IncludeItemTypes=Episode&format=json&ImageTypeLimit=1' else: url = server + '/mediabrowser/Users/' + userid + '/Items?' + limitString + 'IsVirtualUnaired=false&IsMissing=False&Fields=ParentId,Name,SortName,CumulativeRunTimeTicks&Recursive=true&SortOrder=Descending&IncludeItemTypes=Episode&format=json&ImageTypeLimit=1' jsonData = downloadUtils.downloadUrl(url, suppress=False, popup=0) if jsonData != None and jsonData != "": result = json.loads(jsonData) if(result.has_key('Items')): result = result['Items'] return result
def ServiceEntryPoint(self): xbmcgui.Window(10000).setProperty("XBMB3C_Service_Timestamp", str(int(time.time()))) # auth the service try: downloadUtils = DownloadUtils() downloadUtils.authenticate() except Exception, e: pass
def getCollections(self, type): #Build a list of the user views doUtils = DownloadUtils() try: url = "{server}/mediabrowser/Users/{UserId}/Items/Root?format=json" result = doUtils.downloadUrl(url) except Exception, msg: error = "Can't connect: %s" % msg xbmc.log(error) return []
def __init__(self, *args): self.settings = xbmcaddon.Addon(id='plugin.video.xbmb3c') self.downloadUtils = DownloadUtils() try: self.logLevel = int(self.settings.getSetting('logLevel')) except: pass self.printDebug("XBMB3C Service -> starting playback monitor service") self.played_information = {} pass
def getItem(self, id): result = None doUtils = DownloadUtils() url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json&ImageTypeLimit=1&Fields=Etag" % id jsonData = doUtils.downloadUrl(url) if (jsonData != ""): result = jsonData return result
def getFullItem(self, id): result = None doUtils = DownloadUtils() url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json&Fields=Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview" % id jsonData = doUtils.downloadUrl(url) if (jsonData != ""): result = jsonData return result
def checkServer(self): WINDOW = xbmcgui.Window(10000) WINDOW.setProperty("Server_Checked", "True") self.printDebug("XBMB3C Connection Manager Called") self.addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') port = self.addonSettings.getSetting('port') host = self.addonSettings.getSetting('ipaddress') if (len(host) != 0 and host != "<none>"): self.printDebug("XBMB3C server already set") return serverInfo = self.getServerDetails() if (serverInfo == None): self.printDebug("XBMB3C getServerDetails failed") return index = serverInfo.find(":") if (index <= 0): self.printDebug("XBMB3C getServerDetails data not correct : " + serverInfo) return server_address = serverInfo[:index] server_port = serverInfo[index + 1:] self.printDebug("XBMB3C detected server info " + server_address + " : " + server_port) xbmcgui.Dialog().ok(self.__language__(30167), self.__language__(30168), self.__language__(30169) + server_address, self.__language__(30030) + server_port) # get a list of users self.printDebug("Getting user list") jsonData = None downloadUtils = DownloadUtils() try: jsonData = downloadUtils.downloadUrl( server_address + ":" + server_port + "/mediabrowser/Users/Public?format=json") except Exception, msg: error = "Get User unable to connect to " + server_address + ":" + server_port + " : " + str( msg) xbmc.log(error) return ""
def getBoxSets(self): result = [] doUtils = DownloadUtils() url = "{server}/mediabrowser/Users/{UserId}/Items?SortBy=SortName&IsVirtualUnaired=false&IsMissing=False&Fields=Name,SortName,CumulativeRunTimeTicks,Etag&Recursive=true&SortOrder=Ascending&IncludeItemTypes=BoxSet&format=json&ImageTypeLimit=1" jsonData = doUtils.downloadUrl(url) if (jsonData == ""): return result if (jsonData[u'Items'] != ""): result = jsonData[u'Items'] return result
def getTVShowSeasons(self, tvShowId): result = [] doUtils = DownloadUtils() url = "{server}/Shows/%s/Seasons?UserId={UserId}&format=json&ImageTypeLimit=1" % tvShowId jsonData = doUtils.downloadUrl(url) if (jsonData == ""): return result if (jsonData[u'Items'] != ""): result = jsonData[u'Items'] return result
def getMoviesInBoxSet(self,boxsetId): result = [] doUtils = DownloadUtils() url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s&Fields=ItemCounts,Etag&format=json&ImageTypeLimit=1" % boxsetId jsonData = doUtils.downloadUrl(url) if (jsonData == ""): return result if (jsonData[u'Items'] != ""): result = jsonData[u'Items'] return result
def getCollections(self, type): #Build a list of the user views userid = DownloadUtils().getUserId() addon = xbmcaddon.Addon(id='plugin.video.emby') port = addon.getSetting('port') host = addon.getSetting('ipaddress') server = host + ":" + port downloadUtils = DownloadUtils() try: jsonData = downloadUtils.downloadUrl("http://" + server + "/mediabrowser/Users/" + userid + "/Items/Root?format=json") except Exception, msg: error = "Get connect : " + str(msg) xbmc.log (error) return []
def getViewCollections(self, type): #Build a list of the user views doUtils = DownloadUtils() viewsUrl = "{server}/mediabrowser/Users/{UserId}/Views?format=json&ImageTypeLimit=1" result = doUtils.downloadUrl(viewsUrl) collections = [] if (result == ""): return [] result = result[u'Items'] for view in result: if (view[u'Type'] == 'UserView' ): # Need to grab the real main node newViewsUrl = "{server}/mediabrowser/Users/{UserId}/items?ParentId=%s&SortBy=SortName&SortOrder=Ascending&format=json&ImageTypeLimit=1" % view[ u'Id'] newViews = doUtils.downloadUrl(newViewsUrl) if (result == ""): return [] newViews = newViews[u'Items'] for newView in newViews: # There are multiple nodes in here like 'Latest', 'NextUp' - below we grab the full node. if newView[u'CollectionType'] != None: if newView[ u'CollectionType'] == "MovieMovies" or newView[ u'CollectionType'] == "TvShowSeries": view = newView if (view[u'ChildCount'] != 0): Name = view[u'Name'] total = str(view[u'ChildCount']) try: itemtype = view[u'CollectionType'] except: itemtype = "movies" if itemtype == "MovieMovies": itemtype = "movies" if itemtype == "TvShowSeries": itemtype = "tvshows" if itemtype == type: collections.append({ 'title': Name, 'type': type, 'id': view[u'Id'] }) return collections
def getWebSocketPort(self, host, port): userUrl = "http://" + host + ":" + port + "/mediabrowser/System/Info?format=json" downloadUtils = DownloadUtils() jsonData = downloadUtils.downloadUrl(userUrl, suppress=True, popup=1) if (jsonData == ""): return -1 result = json.loads(jsonData) wsPort = result.get("WebSocketPortNumber") if (wsPort != None): return wsPort else: return -1
def getItem(self, id): result = None addon = xbmcaddon.Addon(id='plugin.video.emby') port = addon.getSetting('port') host = addon.getSetting('ipaddress') server = host + ":" + port downloadUtils = DownloadUtils() userid = downloadUtils.getUserId() jsonData = downloadUtils.downloadUrl("http://" + server + "/mediabrowser/Users/" + userid + "/Items/" + id + "?format=json&ImageTypeLimit=1", suppress=False, popup=1 ) if jsonData != None and jsonData != "": result = json.loads(jsonData) return result
def userPreferences(): doUtils = DownloadUtils() addonSettings = xbmcaddon.Addon(id='plugin.video.emby') userPreferencesPage = UserPreferences("script-emby-kodi-UserPreferences.xml", addonSettings.getAddonInfo('path'), "default", "1080i") url = "{server}/mediabrowser/Users/{UserId}" result = doUtils.downloadUrl(url) configuration = result[u'Configuration'] userPreferencesPage.setConfiguration(configuration) userPreferencesPage.setName(result[u'Name']) userPreferencesPage.setImage(API().getUserArtwork(result,"Primary")) userPreferencesPage.doModal() if userPreferencesPage.isSave(): url = "{server}/mediabrowser/Users/{UserId}/Configuration" postdata = userPreferencesPage.getConfiguration() doUtils.downloadUrl(url, postBody=postdata, type="POST")
def getWebSocketPort(self, host, port): userUrl = "http://" + host + ":" + port + "/mediabrowser/System/Info?format=json" downloadUtils = DownloadUtils() jsonData = downloadUtils.downloadUrl(userUrl, suppress=True, popup=1 ) if(jsonData == ""): return -1 result = json.loads(jsonData) wsPort = result.get("WebSocketPortNumber") if(wsPort != None): return wsPort else: return -1
def GetContent(self, url): # first get the url hash m = hashlib.md5() m.update(url) urlHash = m.hexdigest() # build cache data path __addon__ = xbmcaddon.Addon(id='plugin.video.xbmb3c') __addondir__ = xbmc.translatePath(__addon__.getAddonInfo('profile')) if not os.path.exists(os.path.join(__addondir__, "cache")): os.makedirs(os.path.join(__addondir__, "cache")) cacheDataPath = os.path.join(__addondir__, "cache", urlHash) self.logMsg("Cache_Data_Manager:" + cacheDataPath) # are we forcing a reload WINDOW = xbmcgui.Window(10000) force_data_reload = WINDOW.getProperty("force_data_reload") WINDOW.setProperty("force_data_reload", "false") result = None if (os.path.exists(cacheDataPath)) and force_data_reload != "true": try: # load data from cache if it is available and trigger a background # verification process to test cache validity self.logMsg("Loading Cached File") cachedfie = open(cacheDataPath, 'r') jsonData = cachedfie.read() cachedfie.close() result = self.loadJasonData(jsonData) # start a worker thread to process the cache validity self.cacheDataResult = result self.dataUrl = url self.cacheDataPath = cacheDataPath actionThread = CacheManagerThread() actionThread.setCacheData(self) actionThread.start() xbmc.log("Cache_Data_Manager: Returning Cached Result") except: xbmc.log("Error in Cached Data") self.logMsg("Returning Cached Result") return result else: # no cache data so load the url and save it jsonData = DownloadUtils().downloadUrl(url, suppress=False, popup=1) self.logMsg("Loading URL and saving to cache") cachedfie = open(cacheDataPath, 'w') cachedfie.write(jsonData) cachedfie.close() result = self.loadJasonData(jsonData) self.cacheManagerFinished = True self.logMsg("Returning Loaded Result") return result
def __init__(self, parent=None): super(GoogleImagesDownloader, self).__init__(parent) self.webDriverUtils = WebDriverUtils() self.downloadUtils = DownloadUtils() self.save_dir = os.getcwd() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.delete_button.clicked.connect(self.delete_on_click) self.ui.save_button.clicked.connect(self.save_on_click) self.ui.next_image_button.clicked.connect(self.next_image_on_click) self.ui.previous_image_button.clicked.connect(self.previous_image_on_click) self.ui.search_button.clicked.connect(self.search_on_click) self.ui.save_dir_button.clicked.connect(self.save_dir_on_click) self.add_action('d', self.next_image_on_click) self.add_action('a', self.previous_image_on_click) self.add_action('s', self.save_on_click)
def getEpisodes(self, showId, fullinfo = False): result = None doUtils = DownloadUtils() if fullinfo: url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s&IsVirtualUnaired=false&IsMissing=False&SortBy=SortName&Fields=Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&SortOrder=Ascending&IncludeItemTypes=Episode&format=json&ImageTypeLimit=1" % showId else: url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s&IsVirtualUnaired=false&IsMissing=False&SortBy=SortName&Fields=Name,SortName,CumulativeRunTimeTicks&Recursive=true&SortOrder=Ascending&IncludeItemTypes=Episode&format=json&ImageTypeLimit=1" % showId jsonData = doUtils.downloadUrl(url) if (jsonData == ""): return result if (jsonData[u'Items'] != ""): result = jsonData[u'Items'] return result
def userPreferences(): doUtils = DownloadUtils() addonSettings = xbmcaddon.Addon(id='plugin.video.emby') userPreferencesPage = UserPreferences( "script-emby-kodi-UserPreferences.xml", addonSettings.getAddonInfo('path'), "default", "1080i") url = "{server}/mediabrowser/Users/{UserId}" result = doUtils.downloadUrl(url) configuration = result[u'Configuration'] userPreferencesPage.setConfiguration(configuration) userPreferencesPage.setName(result[u'Name']) userPreferencesPage.setImage(API().getUserArtwork(result, "Primary")) userPreferencesPage.doModal() if userPreferencesPage.isSave(): url = "{server}/mediabrowser/Users/{UserId}/Configuration" postdata = userPreferencesPage.getConfiguration() doUtils.downloadUrl(url, postBody=postdata, type="POST")
def SaveLastSync(self): # save last sync time du = DownloadUtils() url = "{server}/Emby.Kodi.SyncQueue/GetServerDateTime?format=json" try: results = du.downloadUrl(url) lastSync = results["ServerDateTime"] self.logMsg("Sync Database, Incremental Sync Using Server Time: %s" % lastSync, 0) lastSync = datetime.strptime(lastSync, "%Y-%m-%dT%H:%M:%SZ") lastSync = (lastSync - timedelta(minutes=5)).strftime('%Y-%m-%dT%H:%M:%SZ') self.logMsg("Sync Database, Incremental Sync Using Server Time -5 min: %s" % lastSync, 0) except: lastSync = (datetime.utcnow() - timedelta(minutes=5)).strftime('%Y-%m-%dT%H:%M:%SZ') self.logMsg("Sync Database, Incremental Sync Using Client Time -5 min: %s" % lastSync, 0) self.logMsg("Sync Database, Incremental Sync Setting Last Run Time Saved: %s" % lastSync, 0) utils.settings("LastIncrenetalSync", lastSync)
def updatePlayCountFromKodi(self, id, type, playcount=0): #when user marks item watched from kodi interface update this in Emby utils.logMsg("Emby", "updatePlayCountFromKodi Called") connection = utils.KodiSQL() cursor = connection.cursor() cursor.execute("SELECT emby_id FROM emby WHERE media_type=? AND kodi_id=?",(type,id)) emby_id = cursor.fetchone()[0] cursor.close if(emby_id != None): addon = xbmcaddon.Addon(id='plugin.video.emby') downloadUtils = DownloadUtils() watchedurl = "{server}/mediabrowser/Users/{UserId}/PlayedItems/%s" % emby_id if playcount != 0: downloadUtils.downloadUrl(watchedurl, type="POST") else: downloadUtils.downloadUrl(watchedurl, type="DELETE")
def checkServer(self): WINDOW = xbmcgui.Window( 10000 ) WINDOW.setProperty("Server_Checked", "True") self.printDebug ("XBMB3C Connection Manager Called") self.addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') port = self.addonSettings.getSetting('port') host = self.addonSettings.getSetting('ipaddress') if(len(host) != 0 and host != "<none>"): self.printDebug ("XBMB3C server already set") return serverInfo = self.getServerDetails() if(serverInfo == None): self.printDebug ("XBMB3C getServerDetails failed") return index = serverInfo.find(":") if(index <= 0): self.printDebug ("XBMB3C getServerDetails data not correct : " + serverInfo) return server_address = serverInfo[:index] server_port = serverInfo[index+1:] self.printDebug ("XBMB3C detected server info " + server_address + " : " + server_port) xbmcgui.Dialog().ok(self.__language__(30167), self.__language__(30168), self.__language__(30169) + server_address, self.__language__(30030) + server_port) # get a list of users self.printDebug ("Getting user list") jsonData = None downloadUtils = DownloadUtils() try: jsonData = downloadUtils.downloadUrl(server_address + ":" + server_port + "/mediabrowser/Users/Public?format=json") except Exception, msg: error = "Get User unable to connect to " + server_address + ":" + server_port + " : " + str(msg) xbmc.log (error) return ""
def getTVShowSeasons(self, tvShowId): result = None addon = xbmcaddon.Addon(id='plugin.video.emby') port = addon.getSetting('port') host = addon.getSetting('ipaddress') server = host + ":" + port downloadUtils = DownloadUtils() userid = downloadUtils.getUserId() url = 'http://' + server + '/Shows/' + tvShowId + '/Seasons?UserId=' + userid + '&format=json&ImageTypeLimit=1' jsonData = downloadUtils.downloadUrl(url, suppress=False, popup=0) if jsonData != None and jsonData != "": result = json.loads(jsonData) if(result.has_key('Items')): result = result['Items'] return result
def getBoxSets(self): result = None addon = xbmcaddon.Addon(id='plugin.video.emby') port = addon.getSetting('port') host = addon.getSetting('ipaddress') server = host + ":" + port downloadUtils = DownloadUtils() userid = downloadUtils.getUserId() url = server + '/mediabrowser/Users/' + userid + '/Items?SortBy=SortName&IsVirtualUnaired=false&IsMissing=False&Fields=Name,SortName,CumulativeRunTimeTicks&Recursive=true&SortOrder=Ascending&IncludeItemTypes=BoxSet&format=json&ImageTypeLimit=1' jsonData = downloadUtils.downloadUrl(url, suppress=False, popup=0) if jsonData != None and jsonData != "": result = json.loads(jsonData) if(result.has_key('Items')): result = result['Items'] return result
def __init__( self, *args ): self.settings = xbmcaddon.Addon(id='plugin.video.emby') self.downloadUtils = DownloadUtils() try: self.logLevel = int(self.settings.getSetting('logLevel')) except: pass self.printDebug("emby Service -> starting playback monitor service",1) self.played_information = {} pass
def getMoviesInBoxSet(self,boxsetId): result = None addon = xbmcaddon.Addon(id='plugin.video.emby') port = addon.getSetting('port') host = addon.getSetting('ipaddress') server = host + ":" + port downloadUtils = DownloadUtils() userid = downloadUtils.getUserId() url = server + '/mediabrowser/Users/' + userid + '/Items?ParentId=' + boxsetId + '&Fields=ItemCounts&format=json&ImageTypeLimit=1' jsonData = downloadUtils.downloadUrl(url, suppress=False, popup=0) if jsonData != None and jsonData != "": result = json.loads(jsonData) if(result.has_key('Items')): result = result['Items'] return result
def on_open(self, ws): clientInfo = ClientInformation() machineId = clientInfo.getMachineId() version = clientInfo.getVersion() messageData = {} messageData["MessageType"] = "Identity" addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') deviceName = addonSettings.getSetting('deviceName') deviceName = deviceName.replace("\"", "_") messageData["Data"] = "Kodi|" + machineId + "|" + version + "|" + deviceName messageString = json.dumps(messageData) self.logMsg("Opened : " + str(messageString)) ws.send(messageString) # Set Capabilities xbmc.log("postcapabilities_called") downloadUtils = DownloadUtils() downloadUtils.postcapabilities()
def getMovies(self, id, fullinfo = False, fullSync = True, itemList = []): result = None addon = xbmcaddon.Addon(id='plugin.video.emby') port = addon.getSetting('port') host = addon.getSetting('ipaddress') server = host + ":" + port downloadUtils = DownloadUtils() userid = downloadUtils.getUserId() if fullSync: sortstring = "&SortBy=SortName" else: if(len(itemList) > 0): # if we want a certain list specify it #sortstring = "&Ids=" + ",".join(itemList) sortstring = "" # work around for now until ParetnId and Id work together else: # just get the last 20 created items sortstring = "&Limit=20&SortBy=DateCreated" if fullinfo: url = server + '/mediabrowser/Users/' + userid + '/items?ParentId=' + id + sortstring + '&Fields=Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&SortOrder=Descending&IncludeItemTypes=Movie&CollapseBoxSetItems=false&format=json&ImageTypeLimit=1' else: url = server + '/mediabrowser/Users/' + userid + '/items?ParentId=' + id + sortstring + '&Fields=CumulativeRunTimeTicks&Recursive=true&SortOrder=Descending&IncludeItemTypes=Movie&CollapseBoxSetItems=false&format=json&ImageTypeLimit=1' jsonData = downloadUtils.downloadUrl(url, suppress=False, popup=0) if jsonData != None and jsonData != "": result = json.loads(jsonData) if(result.has_key('Items')): result = result['Items'] # work around for now until ParetnId and Id work together if(result != None and len(result) > 0 and len(itemList) > 0): newResult = [] for item in result: if(item.get("Id") in itemList): newResult.append(item) result = newResult return result
def getLatestEpisodes(self, fullinfo = False, itemList = []): result = [] doUtils = DownloadUtils() limitString = "Limit=20&SortBy=DateCreated&" if(len(itemList) > 0): # if we want a certain list specify it limitString = "Ids=" + ",".join(itemList) + "&" if fullinfo: url = "{server}/mediabrowser/Users/{UserId}/Items?%sIsVirtualUnaired=false&IsMissing=False&Fields=ParentId,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview,Etag&Recursive=true&SortOrder=Descending&IncludeItemTypes=Episode&format=json&ImageTypeLimit=1" % limitString else: url = "{server}/mediabrowser/Users/{UserId}/Items?%sIsVirtualUnaired=false&IsMissing=False&Fields=ParentId,Name,SortName,CumulativeRunTimeTicks,Etag&Recursive=true&SortOrder=Descending&IncludeItemTypes=Episode&format=json&ImageTypeLimit=1" % limitString jsonData = doUtils.downloadUrl(url) if (jsonData == ""): return result if (jsonData[u'Items'] != ""): result = jsonData[u'Items'] return result
def on_open(self, ws): clientInfo = ClientInformation() machineId = clientInfo.getMachineId() version = clientInfo.getVersion() messageData = {} messageData["MessageType"] = "Identity" addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') deviceName = addonSettings.getSetting('deviceName') deviceName = deviceName.replace("\"", "_") messageData[ "Data"] = "Kodi|" + machineId + "|" + version + "|" + deviceName messageString = json.dumps(messageData) self.logMsg("Opened : " + str(messageString)) ws.send(messageString) # Set Capabilities xbmc.log("postcapabilities_called") downloadUtils = DownloadUtils() downloadUtils.postcapabilities()
def getEpisodes(self, showId, itemList = []): result = [] doUtils = DownloadUtils() url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s&IsVirtualUnaired=false&IsMissing=False&SortBy=SortName&Fields=Name,SortName,CumulativeRunTimeTicks,Etag&Recursive=true&SortOrder=Ascending&IncludeItemTypes=Episode&format=json&ImageTypeLimit=1" % showId jsonData = doUtils.downloadUrl(url) if (jsonData == ""): return result if (jsonData[u'Items'] != ""): result = jsonData[u'Items'] # Work around to only return items from the given list if (result != None and len(result) > 0 and len(itemList) > 0): newResult = [] for item in result: if (item[u'Id'] in itemList): newResult.append(item) result = newResult return result
def run(self): self.logMsg("CacheManagerThread Started") cacheValidatorString = self.dataManager.getCacheValidatorFromData( self.dataManager.cacheDataResult) self.logMsg("Cache Validator String (" + cacheValidatorString + ")") jsonData = DownloadUtils().downloadUrl(self.dataManager.dataUrl, suppress=False, popup=1) loadedResult = self.dataManager.loadJasonData(jsonData) loadedValidatorString = self.dataManager.getCacheValidatorFromData( loadedResult) self.logMsg("Loaded Validator String (" + loadedValidatorString + ")") # if they dont match then save the data and trigger a content reload if (cacheValidatorString != loadedValidatorString): self.logMsg( "CacheManagerThread Saving new cache data and reloading container" ) cachedfie = open(self.dataManager.cacheDataPath, 'w') cachedfie.write(jsonData) cachedfie.close() # we need to refresh but will wait until the main function has finished loops = 0 while (self.dataManager.canRefreshNow == False and loops < 200): #xbmc.log("Cache_Data_Manager: Not finished yet") xbmc.sleep(100) loops = loops + 1 self.logMsg("Sending container refresh (" + str(loops) + ")") xbmc.executebuiltin("Container.Refresh") self.logMsg("CacheManagerThread Exited")
def onNotification(self, sender, method, data): WINDOW = self.WINDOW downloadUtils = DownloadUtils() #player started playing an item - if ("Playlist.OnAdd" in method or "Player.OnPlay" in method) and utils.settings('useDirectPaths') == 'true': jsondata = json.loads(data) if jsondata != None: if jsondata.has_key("item"): if jsondata.get("item").has_key("id") and jsondata.get( "item").has_key("type"): id = jsondata.get("item").get("id") type = jsondata.get("item").get("type") embyid = ReadKodiDB().getEmbyIdByKodiId(id, type) if embyid != None: playurl = xbmc.Player().getPlayingFile() WINDOW = xbmcgui.Window(10000) username = WINDOW.getProperty('currUser') userid = WINDOW.getProperty('userId%s' % username) server = WINDOW.getProperty('server%s' % username) url = "{server}/mediabrowser/Users/{UserId}/Items/" + embyid + "?format=json&ImageTypeLimit=1" result = downloadUtils.downloadUrl(url) print "Here: %s" % result userData = result['UserData'] playurl = PlayUtils().getPlayUrl( server, embyid, result) watchedurl = 'http://' + server + '/mediabrowser/Users/' + userid + '/PlayedItems/' + embyid positionurl = 'http://' + server + '/mediabrowser/Users/' + userid + '/PlayingItems/' + embyid deleteurl = 'http://' + server + '/mediabrowser/Items/' + embyid # set the current playing info WINDOW.setProperty(playurl + "watchedurl", watchedurl) WINDOW.setProperty(playurl + "positionurl", positionurl) WINDOW.setProperty(playurl + "deleteurl", "") WINDOW.setProperty(playurl + "deleteurl", deleteurl) if result.get("Type") == "Episode": WINDOW.setProperty(playurl + "refresh_id", result.get("SeriesId")) else: WINDOW.setProperty(playurl + "refresh_id", embyid) WINDOW.setProperty(playurl + "runtimeticks", str(result.get("RunTimeTicks"))) WINDOW.setProperty(playurl + "type", result.get("Type")) WINDOW.setProperty(playurl + "item_id", embyid) if PlayUtils().isDirectPlay(result) == True: playMethod = "DirectPlay" else: playMethod = "Transcode" WINDOW.setProperty(playurl + "playmethod", playMethod) mediaSources = result.get("MediaSources") if (mediaSources != None): mediaStream = mediaSources[0].get( 'MediaStreams') defaultsubs = "" for stream in mediaStream: if u'Subtitle' in stream[ u'Type'] and stream[u'IsDefault']: if u'Language' in stream: defaultsubs = stream[u'Language'] else: defaultsubs = stream[u'Codec'] WINDOW.setProperty("%ssubs" % playurl, defaultsubs.encode('utf-8')) if mediaSources[0].get( 'DefaultAudioStreamIndex') != None: WINDOW.setProperty( playurl + "AudioStreamIndex", str(mediaSources[0].get( 'DefaultAudioStreamIndex'))) if mediaSources[0].get( 'DefaultSubtitleStreamIndex') != None: WINDOW.setProperty( playurl + "SubtitleStreamIndex", str(mediaSources[0].get( 'DefaultSubtitleStreamIndex'))) if method == "VideoLibrary.OnUpdate": # Triggers 4 times, the following is only for manually marking as watched/unwatched jsondata = json.loads(data) try: playcount = jsondata.get('playcount') item = jsondata['item']['id'] type = jsondata['item']['type'] prop = utils.window('Played%s%s' % (type, item)) except: self.logMsg("Could not process VideoLibrary.OnUpdate data.", 1) else: self.logMsg("VideoLibrary.OnUpdate: %s" % data, 2) if prop != "true": # Set property to prevent the multi triggering utils.window('Played%s%s' % (type, item), "true") WriteKodiVideoDB().updatePlayCountFromKodi( item, type, playcount) self.clearProperty(type, item) if method == "System.OnWake": xbmc.sleep(10000) #Allow network to wake up WINDOW.setProperty("OnWakeSync", "true") if method == "VideoLibrary.OnRemove": xbmc.log('Intercepted remove from sender: ' + sender + ' method: ' + method + ' data: ' + data) jsondata = json.loads(data) id = ReadKodiDB().getEmbyIdByKodiId(jsondata.get("id"), jsondata.get("type")) if id == None: return xbmc.log("Deleting Emby ID: " + id + " from database") connection = utils.KodiSQL() cursor = connection.cursor() cursor.execute("DELETE FROM emby WHERE emby_id = ?", (id, )) connection.commit() cursor.close if jsondata: if jsondata.get("type") == "episode" or "movie": url = '{server}/mediabrowser/Items?Ids=' + id + '&format=json' #This is a check to see if the item exists on the server, if it doesn't it may have already been deleted by another client result = DownloadUtils().downloadUrl(url) item = result.get("Items")[0] if data: return_value = xbmcgui.Dialog().yesno( "Confirm Delete", "Delete file on Emby Server?") if return_value: url = '{server}/mediabrowser/Items/' + id xbmc.log('Deleting via URL: ' + url) DownloadUtils().downloadUrl(url, type="DELETE") elif method == "Playlist.OnClear": self.logMsg("Clear playback properties.", 2) utils.window('PlaylistIntroSet', clear=True) utils.window('PlaylistsetDummy', clear=True) utils.window('PlaylistAdditional', clear=True)
def BrowseChannels(id, folderid=None): _addon_id = int(sys.argv[1]) _addon_url = sys.argv[0] xbmcplugin.setContent(int(sys.argv[1]), 'files') if folderid: url = "{server}/mediabrowser/Channels/" + id + "/Items?userid={UserId}&folderid=" + folderid + "&format=json" else: if id == "0": # id 0 is the root channels folder url = "{server}/mediabrowser/Channels?{UserId}&format=json" else: url = "{server}/mediabrowser/Channels/" + id + "/Items?userid={UserId}&format=json" results = DownloadUtils().downloadUrl(url) if results: result = results.get("Items") if (result == None): result = [] item_count = len(result) current_item = 1 for item in result: id = str(item.get("Id")).encode('utf-8') type = item.get("Type").encode('utf-8') if (item.get("Name") != None): tempTitle = item.get("Name") tempTitle = tempTitle.encode('utf-8') else: tempTitle = "Missing Title" if type == "ChannelFolderItem": isFolder = True else: isFolder = False item_type = str(type).encode('utf-8') if (item.get("ChannelId") != None): channelId = str(item.get("ChannelId")).encode('utf-8') channelName = '' if (item.get("ChannelName") != None): channelName = item.get("ChannelName").encode('utf-8') if (item.get("PremiereDate") != None): premieredatelist = (item.get("PremiereDate")).split("T") premieredate = premieredatelist[0] else: premieredate = "" #mediaStreams=API().getMediaStreams(item, True) #people = API().getPeople(item) # Process Genres genre = API().getGenre(item) # Process UserData userData = item.get("UserData") PlaybackPositionTicks = '100' overlay = "0" favorite = "False" seekTime = 0 if (userData != None): if userData.get("Played") != True: overlay = "7" watched = "true" else: overlay = "6" watched = "false" if userData.get("IsFavorite") == True: overlay = "5" favorite = "True" else: favorite = "False" if userData.get("PlaybackPositionTicks") != None: PlaybackPositionTicks = str( userData.get("PlaybackPositionTicks")) reasonableTicks = int( userData.get("PlaybackPositionTicks")) / 1000 seekTime = reasonableTicks / 10000 playCount = 0 if (userData != None and userData.get("Played") == True): playCount = 1 # Populate the details list details = { 'title': tempTitle, 'channelname': channelName, 'plot': item.get("Overview"), 'Overlay': overlay, 'playcount': str(playCount) } if item.get("Type") == "ChannelVideoItem": xbmcplugin.setContent(_addon_id, 'movies') elif item.get("Type") == "ChannelAudioItem": xbmcplugin.setContent(_addon_id, 'songs') # Populate the extraData list extraData = { 'thumb': API().getArtwork(item, "Primary"), 'fanart_image': API().getArtwork(item, "Backdrop"), 'poster': API().getArtwork(item, "poster"), 'tvshow.poster': API().getArtwork(item, "tvshow.poster"), 'banner': API().getArtwork(item, "Banner"), 'clearlogo': API().getArtwork(item, "Logo"), 'discart': API().getArtwork(item, "Disc"), 'clearart': API().getArtwork(item, "Art"), 'landscape': API().getArtwork(item, "Thumb"), 'id': id, 'rating': item.get("CommunityRating"), 'year': item.get("ProductionYear"), 'premieredate': premieredate, 'genre': genre, 'playcount': str(playCount), 'itemtype': item_type } if extraData['thumb'] == '': extraData['thumb'] = extraData['fanart_image'] liz = xbmcgui.ListItem(tempTitle) artTypes = [ 'poster', 'tvshow.poster', 'fanart_image', 'clearlogo', 'discart', 'banner', 'clearart', 'landscape', 'small_poster', 'tiny_poster', 'medium_poster', 'small_fanartimage', 'medium_fanartimage', 'medium_landscape', 'fanart_noindicators' ] for artType in artTypes: imagePath = str(extraData.get(artType, '')) liz = PlaybackUtils().setArt(liz, artType, imagePath) liz.setThumbnailImage(API().getArtwork(item, "Primary")) liz.setIconImage('DefaultTVShows.png') #liz.setInfo( type="Video", infoLabels={ "Rating": item.get("CommunityRating") }) #liz.setInfo( type="Video", infoLabels={ "Plot": item.get("Overview") }) if type == "Channel": file = _addon_url + "?id=%s&mode=channels" % id xbmcplugin.addDirectoryItem(handle=_addon_id, url=file, listitem=liz, isFolder=True) elif isFolder == True: file = _addon_url + "?id=%s&mode=channelsfolder&folderid=%s" % ( channelId, id) xbmcplugin.addDirectoryItem(handle=_addon_id, url=file, listitem=liz, isFolder=True) else: file = _addon_url + "?id=%s&mode=play" % id liz.setProperty('IsPlayable', 'true') xbmcplugin.addDirectoryItem(handle=_addon_id, url=file, listitem=liz) xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
def addUser(): doUtils = DownloadUtils() clientInfo = ClientInformation() currUser = WINDOW.getProperty("currUser") deviceId = clientInfo.getMachineId() deviceName = clientInfo.getDeviceName() # Get session url = "{server}/mediabrowser/Sessions?DeviceId=%s" % deviceId result = doUtils.downloadUrl(url) try: sessionId = result[0][u'Id'] additionalUsers = result[0][u'AdditionalUsers'] # Add user to session userlist = {} users = [] url = "{server}/mediabrowser/Users?IsDisabled=false&IsHidden=false" result = doUtils.downloadUrl(url) # pull the list of users for user in result: name = user[u'Name'] userId = user[u'Id'] if currUser not in name: userlist[name] = userId users.append(name) # Display dialog if there's additional users if additionalUsers: option = xbmcgui.Dialog().select( "Add/Remove user from the session", ["Add user", "Remove user"]) # Users currently in the session additionalUserlist = {} additionalUsername = [] # Users currently in the session for user in additionalUsers: name = user[u'UserName'] userId = user[u'UserId'] additionalUserlist[name] = userId additionalUsername.append(name) if option == 1: # User selected Remove user resp = xbmcgui.Dialog().select("Remove user from the session", additionalUsername) if resp > -1: selected = additionalUsername[resp] selected_userId = additionalUserlist[selected] url = "{server}/mediabrowser/Sessions/%s/Users/%s" % ( sessionId, selected_userId) postdata = {} doUtils.downloadUrl(url, postBody=postdata, type="DELETE") xbmcgui.Dialog().notification( "Success!", "%s removed from viewing session" % selected, time=1000) # clear picture position = WINDOW.getProperty( 'EmbyAdditionalUserPosition.' + selected_userId) WINDOW.clearProperty('EmbyAdditionalUserImage.' + str(position)) return else: return elif option == 0: # User selected Add user for adduser in additionalUsername: try: # Remove from selected already added users. It is possible they are hidden. users.remove(adduser) except: pass elif option < 0: # User cancelled return # Subtract any additional users xbmc.log("Displaying list of users: %s" % users) resp = xbmcgui.Dialog().select("Add user to the session", users) # post additional user if resp > -1: selected = users[resp] selected_userId = userlist[selected] url = "{server}/mediabrowser/Sessions/%s/Users/%s" % ( sessionId, selected_userId) postdata = {} doUtils.downloadUrl(url, postBody=postdata, type="POST") xbmcgui.Dialog().notification("Success!", "%s added to viewing session" % selected, time=1000) except: xbmc.log("Failed to add user to session.") xbmcgui.Dialog().notification( "Error", "Unable to add/remove user from the session.", xbmcgui.NOTIFICATION_ERROR) try: # Add additional user images #always clear the individual items first totalNodes = 10 for i in range(totalNodes): if not WINDOW.getProperty('EmbyAdditionalUserImage.' + str(i)): break WINDOW.clearProperty('EmbyAdditionalUserImage.' + str(i)) url = "{server}/mediabrowser/Sessions?DeviceId=%s" % deviceId result = doUtils.downloadUrl(url) additionalUsers = result[0][u'AdditionalUsers'] count = 0 for additionaluser in additionalUsers: url = "{server}/mediabrowser/Users/%s?format=json" % ( additionaluser[u'UserId']) result = doUtils.downloadUrl(url) WINDOW.setProperty("EmbyAdditionalUserImage." + str(count), API().getUserArtwork(result, "Primary")) WINDOW.setProperty( "EmbyAdditionalUserPosition." + str(additionaluser[u'UserId']), str(count)) count += 1 except: pass
def updateThemeMedia(self): self.logMsg("updateThemeMedia Called") downloadUtils = DownloadUtils() addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') mb3Host = addonSettings.getSetting('ipaddress') mb3Port = addonSettings.getSetting('port') WINDOW = xbmcgui.Window( 10025 ) newid = xbmc.getInfoLabel('ListItem.Property(ItemGUID)') if newid == '' and xbmcgui.getCurrentWindowId() == 10025: self.logMsg("updateThemeMedia Called using 10025 id"+ xbmc.getInfoLabel( "ListItem.Path" )) newid = WINDOW.getProperty("ItemGUID") if newid == '' and xbmcgui.getCurrentWindowId() == 10000: newid = xbmcgui.Window( 10000 ) .getProperty("ItemGUID") if newid != self.themeId: if self.playingTheme == True: if xbmc.Player().isPlaying(): self.stop() self.event.wait(1.5) time.sleep(2) id = xbmc.getInfoLabel('ListItem.Property(ItemGUID)') if id == '' and xbmcgui.getCurrentWindowId() == 10025: self.logMsg("updateThemeMedia Called had a sleep using 10025 id") id = WINDOW.getProperty("ItemGUID") if id == '' and xbmcgui.getCurrentWindowId() == 10000: self.logMsg("updateThemeMedia Called had a sleep using 10000 id") id = xbmcgui.Window( 10000 ).getProperty("ItemGUID") if id != newid: return self.logMsg("updateThemeMedia itemGUID : " + id) if self.isPlayingZone() and self.isChangeTheme(): self.themeId = id themeMusicUrl = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Items/" + id + "/ThemeSongs?format=json" self.logMsg("updateThemeMedia themeUrl : " + themeMusicUrl) if themeMusicUrl not in self.themeMusicMap: jsonData = downloadUtils.downloadUrl(themeMusicUrl, suppress=True, popup=1 ) themeMusic = json.loads(jsonData) if(themeMusic == None): themeMusic = [] self.logMsg("updateThemeMedia added music theme to map : " + themeMusicUrl) self.themeMusicMap[themeMusicUrl] = themeMusic elif themeMusicUrl in self.themeMusicMap: themeMusic = self.themeMusicMap.get(themeMusicUrl) self.logMsg("updateThemeMedia retrieved music theme from map : " + themeMusicUrl) themeMoviesUrl = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Items/" + id + "/ThemeVideos?format=json" if themeMoviesUrl not in self.themeMoviesMap: jsonData = downloadUtils.downloadUrl(themeMoviesUrl, suppress=True, popup=1 ) themeMovies = json.loads(jsonData) if(themeMovies == None): themeMovies = [] self.logMsg("updateThemeMovie added movies theme to map : " + themeMoviesUrl) self.themeMoviesMap[themeMoviesUrl] = themeMovies elif themeMoviesUrl in self.themeMoviesMap: themeMovies = self.themeMoviesMap.get(themeMoviesUrl) self.logMsg("updateThemeMovie retrieved movies theme from map : " + themeMoviesUrl) if addonSettings.getSetting('useThemeMovies') == "true" : themeItems = themeMovies.get("Items") self.playingMovie = True if themeItems == [] and addonSettings.getSetting('useThemeMusic') == "true" : themeItems = themeMusic.get("Items") self.playingMovie = False elif addonSettings.getSetting('useThemeMusic') == "true" : themeItems = themeMusic.get("Items") self.playingMovie = False if themeItems != []: themePlayUrl = PlayUtils().getPlayUrl(mb3Host + ":" + mb3Port,themeItems[0].get("Id"),themeItems[0]) self.logMsg("updateThemeMedia themePath : " + str(themePlayUrl)) self.playingTheme = True self.setVolume(60) if self.playingMovie == True: xbmc.Player().play(themePlayUrl,windowed=True) else: xbmc.Player().play(themePlayUrl) ThemeTunesStatus.setAliveState(True) elif themeItems == [] and self.playingTheme == True: self.stop(True) if not self.isPlayingZone() and self.playingTheme == True: # stop if xbmc.Player().isPlaying(): self.stop() self.setVolume(self.volume) if not self.isPlayingZone() and self.playingTheme == False: ThemeTunesStatus.setAliveState(False)
class ConnectionManager(): clientInfo = ClientInformation() user = UserClient() doUtils = DownloadUtils() addonName = clientInfo.getAddonName() addonId = clientInfo.getAddonId() addon = xbmcaddon.Addon() WINDOW = xbmcgui.Window(10000) def __init__(self): self.__language__ = self.addon.getLocalizedString def logMsg(self, msg, lvl=1): className = self.__class__.__name__ utils.logMsg("%s %s" % (self.addonName, className), msg, int(lvl)) def checkServer(self): self.WINDOW.setProperty("Server_Checked", "True") self.logMsg("Connection Manager Called", 2) server = self.user.getServer() if server != "": self.logMsg("Server already set", 2) return serverInfo = self.getServerDetails() try: prefix, ip, port = serverInfo.split(":") setServer = xbmcgui.Dialog().yesno( self.__language__(30167), "Proceed with the following server?", self.__language__(30169) + serverInfo) except: # serverInfo is None self.logMsg("getServerDetails failed", 1) xbmc.executebuiltin('Addon.OpenSettings(%s)' % self.addonId) return if setServer == 1: self.logMsg("Server selected. Saving information.", 1) utils.settings("ipaddress", ip.replace("/", "")) utils.settings("port", port) # If https, enable the setting if (prefix == 'https'): utils.settings('https', "true") else: self.logMsg("No server selected.", 1) xbmc.executebuiltin('Addon.OpenSettings(%s)' % self.addonId) return # Get List of public users self.logMsg("Getting user list", 1) server = "%s:%s" % (ip.replace("/", ""), port) url = "%s/mediabrowser/Users/Public?format=json" % serverInfo result = self.doUtils.downloadUrl(url, authenticate=False) if result == "": self.logMsg("Unable to connect to %s." % server, 1) return self.logMsg("Result: %s" % result, 2) # Process the list returned names = [] userList = [] for user in result: name = user['Name'] userList.append(name) if user['HasPassword']: name = "%s (Secure)" % name names.append(name) self.logMsg("User list: %s" % names, 1) resp = xbmcgui.Dialog().select(self.__language__(30200), names) if resp > -1: selected_user = userList[resp] self.logMsg("Selected User: %s" % selected_user, 1) utils.settings("username", selected_user) else: self.logMsg("No user selected.", 1) xbmc.executebuiltin('Addon.OpenSettings(%s)' % self.addonId) return musicDisabled = xbmcgui.Dialog().yesno("Music Setting", "Disable music library?") if musicDisabled: self.logMsg("User opted to disable music library.", 1) utils.settings('enableMusicSync', "false") else: # Music is enabled, prompt for direct stream musicPath = xbmcgui.Dialog().yesno( "Music Setting", "Direct stream the music library?", "Select this option only if you plan on listening to music outside your network." ) if musicPath: self.logMsg("User option to direct stream music library.", 1) utils.settings('directstreammusic', "true") return def getServerDetails(self): self.logMsg("Getting Server Details from Network") MULTI_GROUP = ("<broadcast>", 7359) MESSAGE = "who is EmbyServer?" sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(6.0) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 20) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1) sock.setsockopt(socket.IPPROTO_IP, socket.SO_REUSEADDR, 1) self.logMsg("MutliGroup : %s" % str(MULTI_GROUP), 2) self.logMsg("Sending UDP Data: %s" % MESSAGE, 2) sock.sendto(MESSAGE, MULTI_GROUP) try: data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes self.logMsg("Received Response: %s" % data) # Get the address data = json.loads(data) return data['Address'] except: self.logMsg("No UDP Response") pass return None
class ConnectionManager(): clientInfo = ClientInformation() uc = UserClient() doUtils = DownloadUtils() addonName = clientInfo.getAddonName() addonId = clientInfo.getAddonId() addon = xbmcaddon.Addon(id=addonId) WINDOW = xbmcgui.Window(10000) logLevel = 0 def __init__(self): self.className = self.__class__.__name__ self.__language__ = self.addon.getLocalizedString def logMsg(self, msg, lvl=1): utils.logMsg("%s %s" % (self.addonName, self.className), msg, int(lvl)) def checkServer(self): self.WINDOW.setProperty("Server_Checked", "True") self.logMsg("Connection Manager Called", 2) addon = self.addon server = self.uc.getServer() if (server != ""): self.logMsg("Server already set", 2) return serverInfo = self.getServerDetails() if (serverInfo == None): self.logMsg("getServerDetails failed", 1) xbmc.executebuiltin('Addon.OpenSettings(%s)' % self.addonId) return prefix,ip,port = serverInfo.split(":") setServer = xbmcgui.Dialog().yesno(self.__language__(30167), "Proceed with the following server?", self.__language__(30169) + serverInfo) if (setServer == 1): self.logMsg("Server selected. Saving information.", 1) addon.setSetting("ipaddress", ip.replace("/", "")) addon.setSetting("port", port) # If https is enabled if (prefix == 'https'): addon.setSetting('https', "true") else: self.logMsg("No server selected.", 1) xbmc.executebuiltin('Addon.OpenSettings(%s)' % self.addonId) return # Get List of public users self.logMsg("Getting user list", 1) server = ip.replace("/", "") + ":" + port url = "%s/mediabrowser/Users/Public?format=json" % serverInfo try: result = self.doUtils.downloadUrl(url, authenticate=False) except Exception, msg: error = "Unable to connect to %s: %s" % (server, msg) self.logMsg(error, 1) return "" if (result == ""): return self.logMsg("jsonData: %s" % result, 2) names = [] userList = [] for user in result: name = user[u'Name'] userList.append(name) if(user[u'HasPassword'] == True): name = name + " (Secure)" names.append(name) self.logMsg("User List: %s" % names, 1) self.logMsg("User List: %s" % userList, 2) return_value = xbmcgui.Dialog().select(self.__language__(30200), names) if (return_value > -1): selected_user = userList[return_value] self.logMsg("Selected User: %s" % selected_user, 1) self.addon.setSetting("username", selected_user) else: self.logMsg("No user selected.", 1) xbmc.executebuiltin('Addon.OpenSettings(%s)' % self.addonId) return # Option to play from http setPlayback = xbmcgui.Dialog().yesno("Playback option", "Play your files using HTTP?") if setPlayback == 1: self.logMsg("Playback will be set using HTTP.", 1) addon.setSetting("playFromStream", "true") else: self.logMsg("Playback will be set using SMB.", 1)
class GoogleImagesDownloader(QtGui.QMainWindow): def __init__(self, parent=None): super(GoogleImagesDownloader, self).__init__(parent) self.webDriverUtils = WebDriverUtils() self.downloadUtils = DownloadUtils() self.save_dir = os.getcwd() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.ui.delete_button.clicked.connect(self.delete_on_click) self.ui.save_button.clicked.connect(self.save_on_click) self.ui.next_image_button.clicked.connect(self.next_image_on_click) self.ui.previous_image_button.clicked.connect(self.previous_image_on_click) self.ui.search_button.clicked.connect(self.search_on_click) self.ui.save_dir_button.clicked.connect(self.save_dir_on_click) self.add_action('d', self.next_image_on_click) self.add_action('a', self.previous_image_on_click) self.add_action('s', self.save_on_click) def closeEvent(self, event): print('On_close') self.webDriverUtils.close() def add_action(self, shortcut, method_name): action = QtGui.QAction(self) action.setShortcut(shortcut) action.setShortcutContext(QtCore.Qt.ApplicationShortcut) self.addAction(action) QtCore.QObject.connect(action, QtCore.SIGNAL("triggered()"), method_name) def next_image_on_click(self): print('Next Image') raw_image = self.downloadUtils.get_next_image() while not raw_image: raw_image = self.downloadUtils.get_next_image() self.update_image_view(raw_image) self.update_current_image_index_label() def previous_image_on_click(self): print('Previous Image') raw_image = self.downloadUtils.get_previous_image() self.update_image_view(raw_image) self.update_current_image_index_label() def update_image_view(self, raw_image): qimage = ImageQt(Image.open(io.BytesIO(raw_image))) pixmap = QtGui.QPixmap.fromImage(qimage).scaled(800, 800, aspectRatioMode=QtCore.Qt.KeepAspectRatio, transformMode=QtCore.Qt.SmoothTransformation) self.ui.image_view.setPixmap(pixmap) def save_on_click(self): print('Saving Image...') saved_filename = self.downloadUtils.save_current_image(self.save_dir) self.update_saved_images_count_label() def delete_on_click(self): print('Deleting Image...') self.downloadUtils.delete_current_image() self.update_saved_images_count_label() def update_saved_images_count_label(self): count = self.downloadUtils.get_saved_images_count() self.ui.saved_images_count_label.setText(count) def search_on_click(self): print('Searching') search_text = self.ui.search_term_text_box.text().strip() new_images_list = self.webDriverUtils.get_image_urls_from_google_images(search_text) for url, _ in new_images_list: self.ui.loaded_url.addItem(str(url)) self.downloadUtils.update_url_list(new_images_list) self.update_current_image_index_label() print(search_text) def update_current_image_index_label(self): count = self.downloadUtils.get_url_count() current_index = self.downloadUtils.get_current_image_index() self.ui.current_image_index_label.setText(str(count)+' \ '+str(current_index)) def save_dir_on_click(self): print('changing save dir') open_dir = QtGui.QFileDialog.getExistingDirectory(self, "Open Directory", self.save_dir, QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontResolveSymlinks).strip() print(open_dir) if not open_dir == 0: print('New Folder : ' + open_dir) self.save_dir = open_dir
class Player(xbmc.Player): # Borg - multiple instances, shared state _shared_state = {} xbmcplayer = xbmc.Player() doUtils = DownloadUtils() clientInfo = ClientInformation() ws = WebSocketThread() librarySync = LibrarySync() addonName = clientInfo.getAddonName() played_information = {} playStats = {} currentFile = None def __init__(self, *args): self.__dict__ = self._shared_state self.logMsg("Starting playback monitor.", 2) def logMsg(self, msg, lvl=1): self.className = self.__class__.__name__ utils.logMsg("%s %s" % (self.addonName, self.className), msg, int(lvl)) def GetPlayStats(self): return self.playStats def onPlayBackStarted(self): # Will be called when xbmc starts playing a file xbmcplayer = self.xbmcplayer self.stopAll() # Get current file try: currentFile = xbmcplayer.getPlayingFile() xbmc.sleep(300) except: currentFile = "" count = 0 while not currentFile: xbmc.sleep(100) try: currentFile = xbmcplayer.getPlayingFile() except: pass if count == 5: # try 5 times self.logMsg("Cancelling playback report...", 1) break else: count += 1 if currentFile: self.currentFile = currentFile # We may need to wait for info to be set in kodi monitor itemId = utils.window("%sitem_id" % currentFile) tryCount = 0 while not itemId: xbmc.sleep(200) itemId = utils.window("%sitem_id" % currentFile) if tryCount == 20: # try 20 times or about 10 seconds self.logMsg( "Could not find itemId, cancelling playback report...", 1) break else: tryCount += 1 else: self.logMsg( "ONPLAYBACK_STARTED: %s ITEMID: %s" % (currentFile, itemId), 0) # Only proceed if an itemId was found. runtime = utils.window("%sruntimeticks" % currentFile) refresh_id = utils.window("%srefresh_id" % currentFile) playMethod = utils.window("%splaymethod" % currentFile) itemType = utils.window("%stype" % currentFile) seekTime = xbmcplayer.getTime() # Get playback volume volume_query = '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": {"properties": ["volume","muted"]}, "id": 1}' result = xbmc.executeJSONRPC(volume_query) result = json.loads(result) result = result.get('result') volume = result.get('volume') muted = result.get('muted') # Postdata structure to send to Emby server url = "{server}/mediabrowser/Sessions/Playing" postdata = { 'QueueableMediaTypes': "Video", 'CanSeek': True, 'ItemId': itemId, 'MediaSourceId': itemId, 'PlayMethod': playMethod, 'VolumeLevel': volume, 'PositionTicks': int(seekTime * 10000000), 'IsMuted': muted } # Get the current audio track and subtitles if playMethod == "Transcode": # property set in PlayUtils.py postdata['AudioStreamIndex'] = utils.window( "%sAudioStreamIndex" % currentFile) postdata['SubtitleStreamIndex'] = utils.window( "%sSubtitleStreamIndex" % currentFile) else: # Get the current kodi audio and subtitles and convert to Emby equivalent track_query = '{"jsonrpc": "2.0", "method": "Player.GetProperties", "params": {"playerid": 1,"properties": ["currentsubtitle","currentaudiostream","subtitleenabled"]} , "id": 1}' result = xbmc.executeJSONRPC(track_query) result = json.loads(result) result = result.get('result') try: # Audio tracks indexAudio = result['currentaudiostream']['index'] except (KeyError, TypeError): indexAudio = 0 try: # Subtitles tracks indexSubs = result['currentsubtitle']['index'] except (KeyError, TypeError): indexSubs = 0 try: # If subtitles are enabled subsEnabled = result['subtitleenabled'] except (KeyError, TypeError): subsEnabled = "" # Postdata for the audio postdata['AudioStreamIndex'] = indexAudio + 1 # Postdata for the subtitles if subsEnabled and len( xbmc.Player().getAvailableSubtitleStreams()) > 0: # Number of audiotracks to help get Emby Index audioTracks = len( xbmc.Player().getAvailableAudioStreams()) mapping = utils.window("%sIndexMapping" % currentFile) if mapping: # Set in PlaybackUtils.py self.logMsg( "Mapping for external subtitles index: %s" % mapping, 2) externalIndex = json.loads(mapping) if externalIndex.get(str(indexSubs)): # If the current subtitle is in the mapping postdata[ 'SubtitleStreamIndex'] = externalIndex[str( indexSubs)] else: # Internal subtitle currently selected postdata[ 'SubtitleStreamIndex'] = indexSubs - len( externalIndex) + audioTracks + 1 else: # Direct paths enabled scenario or no external subtitles set postdata[ 'SubtitleStreamIndex'] = indexSubs + audioTracks + 1 else: postdata['SubtitleStreamIndex'] = "" # Post playback to server self.logMsg("Sending POST play started: %s." % postdata, 2) self.doUtils.downloadUrl(url, postBody=postdata, type="POST") # Ensure we do have a runtime try: runtime = int(runtime) except ValueError: runtime = xbmcplayer.getTotalTime() self.logMsg( "Runtime is missing, grabbing runtime from Kodi player: %s" % runtime, 1) # Save data map for updates and position calls data = { 'runtime': runtime, 'item_id': itemId, 'refresh_id': refresh_id, 'currentfile': currentFile, 'AudioStreamIndex': postdata['AudioStreamIndex'], 'SubtitleStreamIndex': postdata['SubtitleStreamIndex'], 'playmethod': playMethod, 'Type': itemType, 'currentPosition': int(seekTime) } self.played_information[currentFile] = data self.logMsg("ADDING_FILE: %s" % self.played_information, 1) # log some playback stats '''if(itemType != None): if(self.playStats.get(itemType) != None): count = self.playStats.get(itemType) + 1 self.playStats[itemType] = count else: self.playStats[itemType] = 1 if(playMethod != None): if(self.playStats.get(playMethod) != None): count = self.playStats.get(playMethod) + 1 self.playStats[playMethod] = count else: self.playStats[playMethod] = 1''' def reportPlayback(self): self.logMsg("reportPlayback Called", 2) xbmcplayer = self.xbmcplayer # Get current file currentFile = self.currentFile data = self.played_information.get(currentFile) # only report playback if emby has initiated the playback (item_id has value) if data: # Get playback information itemId = data['item_id'] audioindex = data['AudioStreamIndex'] subtitleindex = data['SubtitleStreamIndex'] playTime = data['currentPosition'] playMethod = data['playmethod'] paused = data.get('paused', False) # Get playback volume volume_query = '{"jsonrpc": "2.0", "method": "Application.GetProperties", "params": {"properties": ["volume","muted"]}, "id": 1}' result = xbmc.executeJSONRPC(volume_query) result = json.loads(result) result = result.get('result') volume = result.get('volume') muted = result.get('muted') # Postdata for the websocketclient report postdata = { 'QueueableMediaTypes': "Video", 'CanSeek': True, 'ItemId': itemId, 'MediaSourceId': itemId, 'PlayMethod': playMethod, 'PositionTicks': int(playTime * 10000000), 'IsPaused': paused, 'VolumeLevel': volume, 'IsMuted': muted } if playMethod == "Transcode": # Track can't be changed, keep reporting the same index postdata['AudioStreamIndex'] = audioindex postdata['AudioStreamIndex'] = subtitleindex else: # Get current audio and subtitles track track_query = '{"jsonrpc": "2.0", "method": "Player.GetProperties", "params": {"playerid":1,"properties": ["currentsubtitle","currentaudiostream","subtitleenabled"]} , "id": 1}' result = xbmc.executeJSONRPC(track_query) result = json.loads(result) result = result.get('result') try: # Audio tracks indexAudio = result['currentaudiostream']['index'] except (KeyError, TypeError): indexAudio = 0 try: # Subtitles tracks indexSubs = result['currentsubtitle']['index'] except (KeyError, TypeError): indexSubs = 0 try: # If subtitles are enabled subsEnabled = result['subtitleenabled'] except (KeyError, TypeError): subsEnabled = "" # Postdata for the audio data['AudioStreamIndex'], postdata['AudioStreamIndex'] = [ indexAudio + 1 ] * 2 # Postdata for the subtitles if subsEnabled and len( xbmc.Player().getAvailableSubtitleStreams()) > 0: # Number of audiotracks to help get Emby Index audioTracks = len(xbmc.Player().getAvailableAudioStreams()) mapping = utils.window("%sIndexMapping" % currentFile) if mapping: # Set in PlaybackUtils.py self.logMsg( "Mapping for external subtitles index: %s" % mapping, 2) externalIndex = json.loads(mapping) if externalIndex.get(str(indexSubs)): # If the current subtitle is in the mapping data['SubtitleStreamIndex'], postdata[ 'SubtitleStreamIndex'] = [ externalIndex[str(indexSubs)] ] * 2 else: # Internal subtitle currently selected data['SubtitleStreamIndex'], postdata[ 'SubtitleStreamIndex'] = [ indexSubs - len(externalIndex) + audioTracks + 1 ] * 2 else: # Direct paths enabled scenario or no external subtitles set data['SubtitleStreamIndex'], postdata[ 'SubtitleStreamIndex'] = [ indexSubs + audioTracks + 1 ] * 2 else: data['SubtitleStreamIndex'], postdata[ 'SubtitleStreamIndex'] = [""] * 2 # Report progress via websocketclient postdata = json.dumps(postdata) self.logMsg("Report: %s" % postdata, 2) self.ws.sendProgressUpdate(postdata) def onPlayBackPaused(self): currentFile = self.currentFile self.logMsg("PLAYBACK_PAUSED: %s" % currentFile, 2) if self.played_information.get(currentFile): self.played_information[currentFile]['paused'] = True self.reportPlayback() def onPlayBackResumed(self): currentFile = self.currentFile self.logMsg("PLAYBACK_RESUMED: %s" % currentFile, 2) if self.played_information.get(currentFile): self.played_information[currentFile]['paused'] = False self.reportPlayback() def onPlayBackSeek(self, time, seekOffset): # Make position when seeking a bit more accurate currentFile = self.currentFile self.logMsg("PLAYBACK_SEEK: %s" % currentFile, 2) if self.played_information.get(currentFile): position = self.xbmcplayer.getTime() self.played_information[currentFile]['currentPosition'] = position self.reportPlayback() def onPlayBackStopped(self): # Will be called when user stops xbmc playing a file self.logMsg("ONPLAYBACK_STOPPED", 2) self.stopAll() def onPlayBackEnded(self): # Will be called when xbmc stops playing a file self.logMsg("ONPLAYBACK_ENDED", 2) self.stopAll() def stopAll(self): if not self.played_information: return self.logMsg("Played_information: %s" % self.played_information, 1) # Process each items for item in self.played_information: data = self.played_information.get(item) if data: self.logMsg("Item path: %s" % item, 2) self.logMsg("Item data: %s" % data, 2) runtime = data['runtime'] currentPosition = data['currentPosition'] itemId = data['item_id'] refresh_id = data['refresh_id'] currentFile = data['currentfile'] type = data['Type'] playMethod = data['playmethod'] if currentPosition and runtime: percentComplete = (currentPosition * 10000000) / int(runtime) markPlayedAt = float(utils.settings('markPlayed')) / 100 self.logMsg( "Percent complete: %s Mark played at: %s" % (percentComplete, markPlayedAt), 1) # Prevent manually mark as watched in Kodi monitor > WriteKodiVideoDB().UpdatePlaycountFromKodi() utils.window('SkipWatched%s' % itemId, "true") self.stopPlayback(data) offerDelete = utils.settings('offerDelete') == "true" offerTypeDelete = False if type == "Episode" and utils.settings( 'offerDeleteTV') == "true": offerTypeDelete = True elif type == "Movie" and utils.settings( 'offerDeleteMovies') == "true": offerTypeDelete = True if percentComplete >= markPlayedAt and offerDelete and offerTypeDelete: # Make the bigger setting be able to disable option easily. self.logMsg("Offering deletion for: %s." % itemId, 1) return_value = xbmcgui.Dialog().yesno( "Offer Delete", "Delete %s" % currentFile.split("/")[-1], "on Emby Server?") if return_value: # Delete Kodi entry before Emby listItem = [itemId] LibrarySync().removefromDB(listItem, True) # Stop transcoding if playMethod == "Transcode": self.logMsg("Transcoding for %s terminated." % itemId, 1) deviceId = self.clientInfo.getMachineId() url = "{server}/mediabrowser/Videos/ActiveEncodings?DeviceId=%s" % deviceId self.doUtils.downloadUrl(url, type="DELETE") self.played_information.clear() def stopPlayback(self, data): self.logMsg("stopPlayback called", 2) itemId = data['item_id'] currentPosition = data['currentPosition'] positionTicks = int(currentPosition * 10000000) url = "{server}/mediabrowser/Sessions/Playing/Stopped" postdata = { 'ItemId': itemId, 'MediaSourceId': itemId, 'PositionTicks': positionTicks } self.doUtils.downloadUrl(url, postBody=postdata, type="POST")
class ReadEmbyDB(): doUtils = DownloadUtils() urllimit = 50 def filterbyId(self, result, itemList=[]): newResult = [] for item in result: if item['Id'] in itemList: newResult.append(item) return newResult def getMovies(self, parentId, itemList=[]): result = [] lenlist = len(itemList) < self.urllimit # Only get basic info for our sync-compares url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s&SortBy=SortName&Fields=CumulativeRunTimeTicks,Etag&Recursive=true&SortOrder=Descending&IncludeItemTypes=Movie&CollapseBoxSetItems=false&ImageTypeLimit=1&format=json" % parentId if itemList and lenlist: url = "%s&Ids=%s" % (url, ",".join(itemList)) jsondata = self.doUtils.downloadUrl(url) try: result = jsondata['Items'] except: pass else: # If list was longer than 49 items, we pulled the entire list so we need to sort if not lenlist: result = self.filterbyId(result, itemList) return result def getMusicVideos(self, itemList=[]): result = [] lenlist = len(itemList) < self.urllimit # Only get basic info for our sync-compares url = "{server}/mediabrowser/Users/{UserId}/items?&SortBy=SortName&Fields=CumulativeRunTimeTicks,Etag&Recursive=true&SortOrder=Descending&IncludeItemTypes=MusicVideo&CollapseBoxSetItems=false&ImageTypeLimit=1&format=json" if itemList and lenlist: url = "%s&Ids=%s" % (url, ",".join(itemList)) jsondata = self.doUtils.downloadUrl(url) try: result = jsondata['Items'] except: pass else: # If list was longer than 49 items, we pulled the entire list so we need to sort if not lenlist: result = self.filterbyId(result, itemList) return result def getMusicArtists(self, itemList=[]): result = [] lenlist = len(itemList) < self.urllimit # Only get basic info for our sync-compares url = "{server}/Artists?Recursive=true&Fields=Etag,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&UserId={UserId}&format=json" if itemList and lenlist: url = "%s&Ids=%s" % (url, ",".join(itemList)) jsondata = self.doUtils.downloadUrl(url) try: result = jsondata['Items'] except: pass else: # If list was longer than 49 items, we pulled the entire list so we need to sort if not lenlist: result = self.filterbyId(result, itemList) return result def getMusicArtistsTotal(self): result = [] url = "{server}/Artists?Limit=1&Recursive=true&Fields=Etag,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&UserId={UserId}&format=json" jsondata = self.doUtils.downloadUrl(url) total = jsondata['TotalRecordCount'] index = 1 jump = 200 while index < total: url = "{server}/Artists?StartIndex=%s&Limit=%s&Recursive=true&Fields=Etag,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&UserId={UserId}&format=json" % ( index, jump) jsondata = self.doUtils.downloadUrl(url) result.extend(jsondata['Items']) index += jump return result def getMusicSongs(self, itemList=[]): result = [] lenlist = len(itemList) < self.urllimit # Only get basic info for our sync-compares url = "{server}/mediabrowser/Users/{UserId}/Items?Fields=Etag,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&IncludeItemTypes=Audio&format=json" if itemList and lenlist: url = "%s&Ids=%s" % (url, ",".join(itemList)) jsondata = self.doUtils.downloadUrl(url) try: result = jsondata['Items'] except: pass else: # If list was longer than 49 items, we pulled the entire list so we need to sort if not lenlist: result = self.filterbyId(result, itemList) return result def getMusicSongsTotal(self): result = [] url = "{server}/mediabrowser/Users/{UserId}/Items?Index=1&Limit=1&Fields=Etag,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&IncludeItemTypes=Audio&format=json" jsondata = self.doUtils.downloadUrl(url) total = jsondata['TotalRecordCount'] index = 1 jump = 200 while index < total: url = "{server}/mediabrowser/Users/{UserId}/Items?StartIndex=%s&Limit=%s&Fields=Etag,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&IncludeItemTypes=Audio&format=json" % ( index, jump) jsondata = self.doUtils.downloadUrl(url) result.extend(jsondata['Items']) index += jump return result def getMusicAlbums(self, itemList=[]): result = [] lenlist = len(itemList) < self.urllimit # Only get basic info for our sync-compares url = "{server}/mediabrowser/Users/{UserId}/Items?Fields=Etag,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&IncludeItemTypes=MusicAlbum&format=json" if itemList and lenlist: url = "%s&Ids=%s" % (url, ",".join(itemList)) jsondata = self.doUtils.downloadUrl(url) try: result = jsondata['Items'] except: pass else: tempresult = [] # Only return valid albums - which have artists for item in result: if item['AlbumArtists']: tempresult.append(item) result = tempresult # If list was longer than 49 items, we pulled the entire list so we need to sort if not lenlist: result = self.filterbyId(result, itemList) return result def getMusicAlbumsTotal(self): result = [] url = "{server}/mediabrowser/Users/{UserId}/Items?Limit=1&Fields=Etag,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&Recursive=true&IncludeItemTypes=MusicAlbum&format=json" jsondata = self.doUtils.downloadUrl(url) total = jsondata['TotalRecordCount'] index = 1 jump = 200 while index < total: url = "{server}/mediabrowser/Users/{UserId}/Items?StartIndex=%s&Limit=%s&Fields=Etag,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview&SortBy=DateCreated&Recursive=true&IncludeItemTypes=MusicAlbum&format=json" % ( index, jump) jsondata = self.doUtils.downloadUrl(url) #tempresult = [] # Only return valid albums - which have artists '''for item in jsondata['Items']: if item['AlbumArtists']: tempresult.append(item) result.extend(tempresult)''' result.extend(jsondata['Items']) index += jump return result def getTvShows(self, parentId, itemList=[]): result = [] lenlist = len(itemList) < self.urllimit # Only get basic info for our sync-compares url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s&SortBy=SortName&Fields=CumulativeRunTimeTicks,Etag&Recursive=true&SortOrder=Descending&IncludeItemTypes=Series&format=json&ImageTypeLimit=1" % parentId if itemList and lenlist: url = "%s&Ids=%s" % (url, ",".join(itemList)) jsondata = self.doUtils.downloadUrl(url) try: result = jsondata['Items'] except: pass else: # If list was longer than 49 items, we pulled the entire list so we need to sort if not lenlist: result = self.filterbyId(result, itemList) return result def getTVShowSeasons(self, tvShowId): result = [] url = "{server}/Shows/%s/Seasons?UserId={UserId}&format=json&ImageTypeLimit=1" % tvShowId jsondata = self.doUtils.downloadUrl(url) if jsondata: result = jsondata['Items'] return result def getEpisodes(self, showId, itemList=[]): result = [] lenlist = len(itemList) < self.urllimit url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s&IsVirtualUnaired=false&IsMissing=False&SortBy=SortName&Fields=Name,SortName,CumulativeRunTimeTicks,Etag&Recursive=true&SortOrder=Ascending&IncludeItemTypes=Episode&format=json&ImageTypeLimit=1" % showId if itemList and lenlist: url = "%s&Ids=%s" % (url, ",".join(itemList)) jsondata = self.doUtils.downloadUrl(url) try: result = jsondata['Items'] except: pass else: # If list was longer than 49 items, we pulled the entire list so we need to sort if not lenlist: result = self.filterbyId(result, itemList) return result def getLatestEpisodes(self, fullinfo=False, itemList=[]): result = [] limitString = "Limit=20&SortBy=DateCreated&" if itemList: # if we want a certain list specify it limitString = "Ids=%s&" % ",".join(itemList) if fullinfo: url = "{server}/mediabrowser/Users/{UserId}/Items?%sIsVirtualUnaired=false&IsMissing=False&Fields=ParentId,Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview,Etag&Recursive=true&SortOrder=Descending&IncludeItemTypes=Episode&format=json&ImageTypeLimit=1" % limitString else: url = "{server}/mediabrowser/Users/{UserId}/Items?%sIsVirtualUnaired=false&IsMissing=False&Fields=ParentId,Name,SortName,CumulativeRunTimeTicks,Etag&Recursive=true&SortOrder=Descending&IncludeItemTypes=Episode&format=json&ImageTypeLimit=1" % limitString jsondata = self.doUtils.downloadUrl(url) if jsondata: result = jsondata['Items'] return result def getItem(self, id): result = {} url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json&ImageTypeLimit=1&Fields=Etag" % id jsondata = self.doUtils.downloadUrl(url) if jsondata: result = jsondata return result def getFullItem(self, id): result = {} url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json&Fields=Path,Genres,SortName,Studios,Writer,ProductionYear,Taglines,CommunityRating,OfficialRating,CumulativeRunTimeTicks,Metascore,AirTime,DateCreated,MediaStreams,People,Overview,CriticRating,CriticRatingSummary" % id jsondata = self.doUtils.downloadUrl(url) if jsondata: result = jsondata return result def getCollections(self, type): # Build a list of the user views collections = [] url = "{server}/mediabrowser/Users/{UserId}/Views?format=json" #Items?Sortby=SortName&format=json" jsondata = self.doUtils.downloadUrl(url) try: result = jsondata['Items'] except: pass else: for item in result: name = item['Name'] contentType = item['Type'] itemtype = item.get('CollectionType') content = itemtype if contentType == "Channel": # Ignore channel type otherwise, they get processed as mixed content continue if itemtype is None and type in ("movies", "tvshows"): # Mixed content or rich presentation is disabled itemtype = type content = "mixed" if itemtype == type and name not in ("Collections", "Trailers"): collections.append({ 'title': name, 'type': itemtype, 'id': item['Id'], 'content': content }) return collections def getBoxSets(self): result = [] url = "{server}/mediabrowser/Users/{UserId}/Items?SortBy=SortName&IsVirtualUnaired=false&IsMissing=False&Fields=Name,SortName,CumulativeRunTimeTicks,Etag&Recursive=true&SortOrder=Ascending&IncludeItemTypes=BoxSet&format=json&ImageTypeLimit=1" jsondata = self.doUtils.downloadUrl(url) if jsondata: result = jsondata['Items'] return result def getMoviesInBoxSet(self, boxsetId): result = [] url = "{server}/mediabrowser/Users/{UserId}/Items?ParentId=%s&Fields=ItemCounts,Etag&format=json&ImageTypeLimit=1" % boxsetId jsondata = self.doUtils.downloadUrl(url) if jsondata: result = jsondata['Items'] return result # This is not being used. # To be removed? def getViewCollections(self, type): #Build a list of the user views doUtils = DownloadUtils() viewsUrl = "{server}/mediabrowser/Users/{UserId}/Views?format=json&ImageTypeLimit=1" result = doUtils.downloadUrl(viewsUrl) collections = [] if (result == ""): return [] result = result[u'Items'] for view in result: if (view[u'Type'] == 'UserView' ): # Need to grab the real main node newViewsUrl = "{server}/mediabrowser/Users/{UserId}/items?ParentId=%s&SortBy=SortName&SortOrder=Ascending&format=json&ImageTypeLimit=1" % view[ u'Id'] newViews = doUtils.downloadUrl(newViewsUrl) if (result == ""): return [] newViews = newViews[u'Items'] for newView in newViews: # There are multiple nodes in here like 'Latest', 'NextUp' - below we grab the full node. if newView[u'CollectionType'] != None: if newView[ u'CollectionType'] == "MovieMovies" or newView[ u'CollectionType'] == "TvShowSeries": view = newView if (view[u'ChildCount'] != 0): Name = view[u'Name'] total = str(view[u'ChildCount']) try: itemtype = view[u'CollectionType'] except: itemtype = "movies" if itemtype == "MovieMovies": itemtype = "movies" if itemtype == "TvShowSeries": itemtype = "tvshows" if itemtype == type: collections.append({ 'title': Name, 'type': type, 'id': view[u'Id'] }) return collections
def doPlayback(id): url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json&ImageTypeLimit=1" % id result = DownloadUtils().downloadUrl(url) item = PlaybackUtils().PLAY(result, setup="default")
import xbmc import xbmcgui import xbmcaddon import json import threading from datetime import datetime from DownloadUtils import DownloadUtils from ClientInformation import ClientInformation import urllib import sys import os #define our global download utils downloadUtils = DownloadUtils() clientInfo = ClientInformation() ########################################################################### class PlayUtils(): def getPlayUrl(self, server, id, result): addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') # if the path is local and depending on the video quality play we can direct play it do so- xbmc.log("XBMB3C getPlayUrl") if self.fileExists(result) or self.isDirectPlay(result) == True: xbmc.log("XBMB3C getPlayUrl -> Direct Play") playurl = result.get("Path") if playurl != None: #We have a path to play so play it
def updateNextUp(self): self.logMsg("updateNextUp Called") useBackgroundData = xbmcgui.Window(10000).getProperty("BackgroundDataLoaded") == "true" addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') mb3Host = addonSettings.getSetting('ipaddress') mb3Port = addonSettings.getSetting('port') userName = addonSettings.getSetting('username') downloadUtils = DownloadUtils() userid = downloadUtils.getUserId() self.logMsg("updateNextUp UserID : " + userid) self.logMsg("Updating NextUp List") nextUpUrl = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Shows/NextUp?UserId=" + userid + "&Fields=Path,Genres,MediaStreams,Overview,ShortOverview&format=json&ImageTypeLimit=1" jsonData = downloadUtils.downloadUrl(nextUpUrl, suppress=True, popup=1 ) if(jsonData == ""): return result = json.loads(jsonData) self.logMsg("NextUP TV Show Json Data : " + str(result), level=2) result = result.get("Items") WINDOW = xbmcgui.Window( 10000 ) if(result == None): result = [] db = Database() item_count = 1 for item in result: title = "Missing Title" if(item.get("Name") != None): title = item.get("Name").encode('utf-8') seriesName = "Missing Name" if(item.get("SeriesName") != None): seriesName = item.get("SeriesName").encode('utf-8') eppNumber = "X" tempEpisodeNumber = "XX" if(item.get("IndexNumber") != None): eppNumber = item.get("IndexNumber") if eppNumber < 10: tempEpisodeNumber = "0" + str(eppNumber) else: tempEpisodeNumber = str(eppNumber) seasonNumber = item.get("ParentIndexNumber") tempSeasonNumber = "XX" if seasonNumber < 10: tempSeasonNumber = "0" + str(seasonNumber) else: tempSeasonNumber = str(seasonNumber) rating = str(item.get("CommunityRating")) plot = item.get("Overview") if plot == None: plot='' plot=plot.encode('utf-8') shortplot = item.get("ShortOverview") if shortplot == None: shortplot = '' shortplot = shortplot.encode('utf-8') year = item.get("ProductionYear") item_id = item.get("Id") seriesId = item.get("SeriesId") seriesthumbnail = "" if useBackgroundData != True: seriesJsonData = downloadUtils.downloadUrl("http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Users/" + userid + "/Items/" + seriesId + "?format=json", suppress=True, popup=1 ) if(seriesJsonData != ""): seriesResult = json.loads(seriesJsonData) officialrating = seriesResult.get("OfficialRating") poster = downloadUtils.getArtwork(seriesResult, "Primary3") small_poster = downloadUtils.getArtwork(seriesResult, "Primary2") thumbnail = downloadUtils.getArtwork(item, "Primary") logo = downloadUtils.getArtwork(seriesResult, "Logo") fanart = downloadUtils.getArtwork(item, "Backdrop") medium_fanart = downloadUtils.getArtwork(item, "Backdrop3") banner = downloadUtils.getArtwork(item, "Banner") if (seriesResult.get("ImageTags") != None and seriesResult.get("ImageTags").get("Thumb") != None): seriesthumbnail = downloadUtils.getArtwork(seriesResult, "Thumb3") else: seriesthumbnail = fanart else: # get rid of the call below when we can get the series userdata officialrating = db.get(seriesId + ".OfficialRating") poster = db.get(seriesId + ".Primary3") small_poster = db.get(seriesId + ".Primary2") thumbnail = db.get(seriesId + ".Primary") logo = db.get(seriesId + ".Logo") fanart = db.get(seriesId + ".Backdrop") medium_fanart = db.get(seriesId + ".Backdrop3") banner = db.get(seriesId + ".Banner") if (item.get("SeriesThumbImageTag") != None and item.get("SeriesThumbImageTag") != ""): seriesthumbnail = db.get(seriesId + ".Thumb3") else: seriesthumbnail = fanart url = mb3Host + ":" + mb3Port + ',;' + item_id playUrl = "plugin://plugin.video.xbmb3c/?url=" + url + '&mode=' + str(_MODE_BASICPLAY) playUrl = playUrl.replace("\\\\","smb://") playUrl = playUrl.replace("\\","/") # Process UserData userData = item.get("UserData") if(userData != None): resume = str(userData.get("PlaybackPositionTicks")) if (resume == "0"): resume = "False" else: resume = "True" self.logMsg("NextUpEpisodeMB3." + str(item_count) + ".EpisodeTitle = " + title, level=2) self.logMsg("NextUpEpisodeMB3." + str(item_count) + ".ShowTitle = " + seriesName, level=2) self.logMsg("NextUpEpisodeMB3." + str(item_count) + ".EpisodeNo = " + tempEpisodeNumber, level=2) self.logMsg("NextUpEpisodeMB3." + str(item_count) + ".SeasonNo = " + tempSeasonNumber, level=2) self.logMsg("NextUpEpisodeMB3." + str(item_count) + ".Thumb = " + thumbnail, level=2) self.logMsg("NextUpEpisodeMB3." + str(item_count) + ".Path = " + playUrl, level=2) self.logMsg("NextUpEpisodeMB3." + str(item_count) + ".Rating = " + rating, level=2) self.logMsg("NextUpEpisodeMB3." + str(item_count) + ".Art(tvshow.fanart) = " + fanart, level=2) self.logMsg("NextUpEpisodeMB3." + str(item_count) + ".Art(tvshow.clearlogo) = " + logo, level=2) self.logMsg("NextUpEpisodeMB3." + str(item_count) + ".Art(tvshow.banner) = " + banner, level=2) self.logMsg("NextUpEpisodeMB3." + str(item_count) + ".Art(tvshow.poster) = " + poster, level=2) self.logMsg("NextUpEpisodeMB3." + str(item_count) + ".Plot = " + plot, level=2) self.logMsg("NextUpEpisodeMB3." + str(item_count) + ".Resume = " + resume, level=2) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".EpisodeTitle", title) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".ShowTitle", seriesName) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".EpisodeNo", tempEpisodeNumber) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".SeasonNo", tempSeasonNumber) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".Thumb", thumbnail) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".SeriesThumb", seriesthumbnail) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".Path", playUrl) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".Rating", rating) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".Art(tvshow.fanart)", fanart) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".Art(tvshow.medium_fanart)", medium_fanart) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".Art(tvshow.clearlogo)", logo) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".Art(tvshow.banner)", banner) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".Art(tvshow.poster)", poster) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".Art(tvshow.small_poster)", small_poster) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".Plot", plot) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".ShortPlot", shortplot) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".Year", str(year)) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".MPAA", str(officialrating)) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".ItemGUID", seriesId) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".id", item_id) WINDOW.setProperty("NextUpEpisodeMB3." + str(item_count) + ".Resume", resume) WINDOW.setProperty("NextUpEpisodeMB3.Enabled", "true") item_count = item_count + 1 if(item_count < 10): # blank any not available for x in range(item_count, 11): WINDOW.setProperty("NextUpEpisodeMB3." + str(x) + ".EpisodeTitle", "") WINDOW.setProperty("NextUpEpisodeMB3." + str(x) + ".ShowTitle", "") WINDOW.setProperty("NextUpEpisodeMB3." + str(x) + ".EpisodeNo", "") WINDOW.setProperty("NextUpEpisodeMB3." + str(x) + ".SeasonNo", "") WINDOW.setProperty("NextUpEpisodeMB3." + str(x) + ".Thumb", "") WINDOW.setProperty("NextUpEpisodeMB3." + str(x) + ".Path", "") WINDOW.setProperty("NextUpEpisodeMB3." + str(x) + ".Rating", "") WINDOW.setProperty("NextUpEpisodeMB3." + str(x) + ".Art(tvshow.fanart)", "") WINDOW.setProperty("NextUpEpisodeMB3." + str(x) + ".Art(tvshow.clearlogo)", "") WINDOW.setProperty("NextUpEpisodeMB3." + str(x) + ".Art(tvshow.banner)", "") WINDOW.setProperty("NextUpEpisodeMB3." + str(x) + ".Art(tvshow.poster)", "") WINDOW.setProperty("NextUpEpisodeMB3." + str(x) + ".Plot", "") WINDOW.setProperty("NextUpEpisodeMB3." + str(x) + ".Resume", "")
def updateRandom(self): self.logMsg("updateRandomMovies Called") useBackgroundData = xbmcgui.Window(10000).getProperty( "BackgroundDataLoaded") == "true" addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') mb3Host = addonSettings.getSetting('ipaddress') mb3Port = addonSettings.getSetting('port') userName = addonSettings.getSetting('username') downloadUtils = DownloadUtils() userid = downloadUtils.getUserId() self.logMsg("updateRandomMovies UserID : " + userid) self.logMsg("Updating Random Movie List") randomUrl = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Users/" + userid + "/Items?Limit=30&Recursive=true&SortBy=Random&Fields=Path,Genres,MediaStreams,Overview,ShortOverview,CriticRatingSummary&SortOrder=Descending&Filters=IsUnplayed,IsNotFolder&IncludeItemTypes=Movie&format=json" jsonData = downloadUtils.downloadUrl(randomUrl, suppress=True, popup=1) if (jsonData == ""): return result = json.loads(jsonData) self.logMsg("Random Movie Json Data : " + str(result), level=2) result = result.get("Items") if (result == None): result = [] db = Database() WINDOW = xbmcgui.Window(10000) item_count = 1 for item in result: title = "Missing Title" if (item.get("Name") != None): title = item.get("Name").encode('utf-8') rating = item.get("CommunityRating") criticrating = item.get("CriticRating") officialrating = item.get("OfficialRating") criticratingsummary = "" if (item.get("CriticRatingSummary") != None): criticratingsummary = item.get("CriticRatingSummary").encode( 'utf-8') plot = item.get("Overview") if plot == None: plot = '' plot = plot.encode('utf-8') shortplot = item.get("ShortOverview") if shortplot == None: shortplot = '' shortplot = shortplot.encode('utf-8') year = item.get("ProductionYear") if (item.get("RunTimeTicks") != None): runtime = str(int(item.get("RunTimeTicks")) / (10000000 * 60)) else: runtime = "0" item_id = item.get("Id") if useBackgroundData != True: poster = downloadUtils.getArtwork(item, "Primary3") thumbnail = downloadUtils.getArtwork(item, "Primary") logo = downloadUtils.getArtwork(item, "Logo") fanart = downloadUtils.getArtwork(item, "Backdrop") landscape = downloadUtils.getArtwork(item, "Thumb3") discart = downloadUtils.getArtwork(item, "Disc") medium_fanart = downloadUtils.getArtwork(item, "Backdrop3") if item.get("ImageTags").get("Thumb") != None: realthumb = downloadUtils.getArtwork(item, "Thumb3") else: realthumb = medium_fanart else: poster = db.get(item_id + ".Primary3") thumbnail = db.get(item_id + ".Primary") logo = db.get(item_id + ".Logo") fanart = db.get(item_id + ".Backdrop") landscape = db.get(item_id + ".Thumb3") discart = db.get(item_id + ".Disc") medium_fanart = db.get(item_id + ".Backdrop3") if item.get("ImageTags").get("Thumb") != None: realthumb = db.get(item_id + ".Thumb3") else: realthumb = medium_fanart url = mb3Host + ":" + mb3Port + ',;' + item_id # play or show info selectAction = addonSettings.getSetting('selectAction') if (selectAction == "1"): playUrl = "plugin://plugin.video.xbmb3c/?id=" + item_id + '&mode=' + str( _MODE_ITEM_DETAILS) else: playUrl = "plugin://plugin.video.xbmb3c/?url=" + url + '&mode=' + str( _MODE_BASICPLAY) playUrl = playUrl.replace("\\\\", "smb://") playUrl = playUrl.replace("\\", "/") self.logMsg("RandomMovieMB3." + str(item_count) + ".Title = " + title, level=2) self.logMsg("RandomMovieMB3." + str(item_count) + ".Thumb = " + thumbnail, level=2) self.logMsg("RandomMovieMB3." + str(item_count) + ".Path = " + playUrl, level=2) self.logMsg("RandomMovieMB3." + str(item_count) + ".Art(fanart) = " + fanart, level=2) self.logMsg("RandomMovieMB3." + str(item_count) + ".Art(clearlogo) = " + logo, level=2) self.logMsg("RandomMovieMB3." + str(item_count) + ".Art(poster) = " + thumbnail, level=2) self.logMsg("RandomMovieMB3." + str(item_count) + ".Rating = " + str(rating), level=2) self.logMsg("RandomMovieMB3." + str(item_count) + ".CriticRating = " + str(criticrating), level=2) self.logMsg("RandomMovieMB3." + str(item_count) + ".CriticRatingSummary = " + criticratingsummary, level=2) self.logMsg("RandomMovieMB3." + str(item_count) + ".Plot = " + plot, level=2) self.logMsg("RandomMovieMB3." + str(item_count) + ".Year = " + str(year), level=2) self.logMsg("RandomMovieMB3." + str(item_count) + ".Runtime = " + str(runtime), level=2) WINDOW.setProperty("RandomMovieMB3." + str(item_count) + ".Title", title) WINDOW.setProperty("RandomMovieMB3." + str(item_count) + ".Thumb", realthumb) WINDOW.setProperty("RandomMovieMB3." + str(item_count) + ".Path", playUrl) WINDOW.setProperty( "RandomMovieMB3." + str(item_count) + ".Art(fanart)", fanart) WINDOW.setProperty( "RandomMovieMB3." + str(item_count) + ".Art(landscape)", landscape) WINDOW.setProperty( "RandomMovieMB3." + str(item_count) + ".Art(medium_fanart)", medium_fanart) WINDOW.setProperty( "RandomMovieMB3." + str(item_count) + ".Art(clearlogo)", logo) WINDOW.setProperty( "RandomMovieMB3." + str(item_count) + ".Art(poster)", thumbnail) WINDOW.setProperty( "RandomMovieMB3." + str(item_count) + ".RealThumb", realthumb) WINDOW.setProperty("RandomMovieMB3." + str(item_count) + ".Rating", str(rating)) WINDOW.setProperty("RandomMovieMB3." + str(item_count) + ".Mpaa", str(officialrating)) WINDOW.setProperty( "RandomMovieMB3." + str(item_count) + ".CriticRating", str(criticrating)) WINDOW.setProperty( "RandomMovieMB3." + str(item_count) + ".CriticRatingSummary", criticratingsummary) WINDOW.setProperty("RandomMovieMB3." + str(item_count) + ".Plot", plot) WINDOW.setProperty( "RandomMovieMB3." + str(item_count) + ".ShortPlot", shortplot) WINDOW.setProperty("RandomMovieMB3." + str(item_count) + ".Year", str(year)) WINDOW.setProperty( "RandomMovieMB3." + str(item_count) + ".Runtime", str(runtime)) WINDOW.setProperty("RandomMovieMB3.Enabled", "true") item_count = item_count + 1 self.logMsg("Updating Random TV Show List") randomUrl = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Users/" + userid + "/Items?Limit=10&Recursive=true&SortBy=Random&Fields=Path,Genres,MediaStreams,Overview,ShortOverview&SortOrder=Descending&Filters=IsUnplayed,IsNotFolder&IsVirtualUnaired=false&IsMissing=False&IncludeItemTypes=Episode&format=json" jsonData = downloadUtils.downloadUrl(randomUrl, suppress=True, popup=1) result = json.loads(jsonData) self.logMsg("Random TV Show Json Data : " + str(result), level=2) result = result.get("Items") if (result == None): result = [] item_count = 1 for item in result: title = "Missing Title" if (item.get("Name") != None): title = item.get("Name").encode('utf-8') seriesName = "Missing Name" if (item.get("SeriesName") != None): seriesName = item.get("SeriesName").encode('utf-8') eppNumber = "X" tempEpisodeNumber = "" if (item.get("IndexNumber") != None): eppNumber = item.get("IndexNumber") if eppNumber < 10: tempEpisodeNumber = "0" + str(eppNumber) else: tempEpisodeNumber = str(eppNumber) seasonNumber = item.get("ParentIndexNumber") if seasonNumber < 10: tempSeasonNumber = "0" + str(seasonNumber) else: tempSeasonNumber = str(seasonNumber) rating = str(item.get("CommunityRating")) plot = item.get("Overview") if plot == None: plot = '' plot = plot.encode('utf-8') shortplot = item.get("ShortOverview") if shortplot == None: shortplot = '' shortplot = shortplot.encode('utf-8') item_id = item.get("Id") seriesId = item.get("SeriesId") if useBackgroundData != True: seriesJsonData = downloadUtils.downloadUrl( "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Users/" + userid + "/Items/" + seriesId + "?format=json", suppress=True, popup=1) seriesResult = json.loads(seriesJsonData) officialrating = seriesResult.get("OfficialRating") poster = downloadUtils.getArtwork(seriesResult, "Primary3") small_poster = downloadUtils.getArtwork( seriesResult, "Primary2") thumbnail = downloadUtils.getArtwork(item, "Primary") logo = downloadUtils.getArtwork(seriesResult, "Logo") fanart = downloadUtils.getArtwork(item, "Backdrop") medium_fanart = downloadUtils.getArtwork(item, "Backdrop3") banner = downloadUtils.getArtwork(item, "Banner") if (seriesResult.get("ImageTags") != None and seriesResult.get("ImageTags").get("Thumb") != None): seriesthumbnail = downloadUtils.getArtwork( seriesResult, "Thumb3") else: seriesthumbnail = medium_fanart else: officialrating = db.get(seriesId + ".OfficialRating") poster = db.get(seriesId + ".Primary3") small_poster = db.get(seriesId + ".Primary2") thumbnail = downloadUtils.getArtwork(item, "Primary") logo = db.get(seriesId + ".Logo") fanart = db.get(seriesId + ".Backdrop") medium_fanart = db.get(seriesId + ".Backdrop3") banner = db.get(seriesId + ".Banner") if item.get("SeriesThumbImageTag") != None: seriesthumbnail = db.get(seriesId + ".Thumb3") else: seriesthumbnail = fanart url = mb3Host + ":" + mb3Port + ',;' + item_id selectAction = addonSettings.getSetting('selectAction') if (selectAction == "1"): playUrl = "plugin://plugin.video.xbmb3c/?id=" + item_id + '&mode=' + str( _MODE_ITEM_DETAILS) else: playUrl = "plugin://plugin.video.xbmb3c/?url=" + url + '&mode=' + str( _MODE_BASICPLAY) playUrl = playUrl.replace("\\\\", "smb://") playUrl = playUrl.replace("\\", "/") self.logMsg("RandomEpisodeMB3." + str(item_count) + ".EpisodeTitle = " + title, level=2) self.logMsg("RandomEpisodeMB3." + str(item_count) + ".ShowTitle = " + seriesName, level=2) self.logMsg("RandomEpisodeMB3." + str(item_count) + ".EpisodeNo = " + tempEpisodeNumber, level=2) self.logMsg("RandomEpisodeMB3." + str(item_count) + ".SeasonNo = " + tempSeasonNumber, level=2) self.logMsg("RandomEpisodeMB3." + str(item_count) + ".Thumb = " + thumbnail, level=2) self.logMsg("RandomEpisodeMB3." + str(item_count) + ".Path = " + playUrl, level=2) self.logMsg("RandomEpisodeMB3." + str(item_count) + ".Rating = " + rating, level=2) self.logMsg("RandomEpisodeMB3." + str(item_count) + ".Art(tvshow.fanart) = " + fanart, level=2) self.logMsg("RandomEpisodeMB3." + str(item_count) + ".Art(tvshow.clearlogo) = " + logo, level=2) self.logMsg("RandomEpisodeMB3." + str(item_count) + ".Art(tvshow.banner) = " + banner, level=2) self.logMsg("RandomEpisodeMB3." + str(item_count) + ".Art(tvshow.poster) = " + poster, level=2) self.logMsg("RandomEpisodeMB3." + str(item_count) + ".Plot = " + plot, level=2) WINDOW.setProperty( "RandomEpisodeMB3." + str(item_count) + ".EpisodeTitle", title) WINDOW.setProperty( "RandomEpisodeMB3." + str(item_count) + ".ShowTitle", seriesName) WINDOW.setProperty( "RandomEpisodeMB3." + str(item_count) + ".EpisodeNo", tempEpisodeNumber) WINDOW.setProperty( "RandomEpisodeMB3." + str(item_count) + ".SeasonNo", tempSeasonNumber) WINDOW.setProperty( "RandomEpisodeMB3." + str(item_count) + ".Thumb", thumbnail) WINDOW.setProperty( "RandomEpisodeMB3." + str(item_count) + ".SeriesThumb", seriesthumbnail) WINDOW.setProperty("RandomEpisodeMB3." + str(item_count) + ".Path", playUrl) WINDOW.setProperty( "RandomEpisodeMB3." + str(item_count) + ".Rating", rating) WINDOW.setProperty( "RandomEpisodeMB3." + str(item_count) + ".Art(tvshow.fanart)", fanart) WINDOW.setProperty( "RandomEpisodeMB3." + str(item_count) + ".Art(tvshow.medium_fanart)", medium_fanart) WINDOW.setProperty( "RandomEpisodeMB3." + str(item_count) + ".Art(tvshow.clearlogo)", logo) WINDOW.setProperty( "RandomEpisodeMB3." + str(item_count) + ".Art(tvshow.banner)", banner) WINDOW.setProperty( "RandomEpisodeMB3." + str(item_count) + ".Art(tvshow.poster)", poster) WINDOW.setProperty("RandomEpisodeMB3." + str(item_count) + ".Plot", plot) WINDOW.setProperty( "RandomEpisodeMB3." + str(item_count) + ".ShortPlot", shortplot) WINDOW.setProperty("RandomEpisodeMB3.Enabled", "true") item_count = item_count + 1 # update random music self.logMsg("Updating Random MusicList") randomUrl = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Users/" + userid + "/Items?Limit=30&Recursive=true&SortBy=Random&Fields=Path,Genres,MediaStreams,Overview&SortOrder=Descending&Filters=IsUnplayed,IsFolder&IsVirtualUnaired=false&IsMissing=False&IncludeItemTypes=MusicAlbum&format=json" jsonData = downloadUtils.downloadUrl(randomUrl, suppress=True, popup=1) result = json.loads(jsonData) self.logMsg("Random MusicList Json Data : " + str(result), level=2) result = result.get("Items") if (result == None): result = [] item_count = 1 for item in result: title = "Missing Title" if (item.get("Name") != None): title = item.get("Name").encode('utf-8') artist = "Missing Artist" if (item.get("AlbumArtist") != None): artist = item.get("AlbumArtist").encode('utf-8') year = "0000" if (item.get("ProductionYear") != None): year = str(item.get("ProductionYear")) plot = "Missing Plot" if (item.get("Overview") != None): plot = item.get("Overview").encode('utf-8') item_id = item.get("Id") if item.get("Type") == "MusicAlbum": parentId = item.get("ParentLogoItemId") thumbnail = downloadUtils.getArtwork(item, "Primary") logo = downloadUtils.getArtwork(item, "Logo") fanart = downloadUtils.getArtwork(item, "Backdrop") banner = downloadUtils.getArtwork(item, "Banner") url = mb3Host + ":" + mb3Port + ',;' + item_id playUrl = "plugin://plugin.video.xbmb3c/?url=" + url + '&mode=' + str( _MODE_BASICPLAY) playUrl = playUrl.replace("\\\\", "smb://") playUrl = playUrl.replace("\\", "/") self.logMsg("RandomAlbumMB3." + str(item_count) + ".Title = " + title, level=2) self.logMsg("RandomAlbumMB3." + str(item_count) + ".Artist = " + artist, level=2) self.logMsg("RandomAlbumMB3." + str(item_count) + ".Year = " + year, level=2) self.logMsg("RandomAlbumMB3." + str(item_count) + ".Thumb = " + thumbnail, level=2) self.logMsg("RandomAlbumMB3." + str(item_count) + ".Path = " + playUrl, level=2) self.logMsg("RandomAlbumMB3." + str(item_count) + ".Art(fanart) = " + fanart, level=2) self.logMsg("RandomAlbumMB3." + str(item_count) + ".Art(clearlogo) = " + logo, level=2) self.logMsg("RandomAlbumMB3." + str(item_count) + ".Art(banner) = " + banner, level=2) self.logMsg("RandomAlbumMB3." + str(item_count) + ".Art(poster) = " + thumbnail, level=2) self.logMsg("RandomAlbumMB3." + str(item_count) + ".Plot = " + plot, level=2) WINDOW.setProperty("RandomAlbumMB3." + str(item_count) + ".Title", title) WINDOW.setProperty("RandomAlbumMB3." + str(item_count) + ".Artist", artist) WINDOW.setProperty("RandomAlbumMB3." + str(item_count) + ".Year", year) WINDOW.setProperty("RandomAlbumMB3." + str(item_count) + ".Thumb", thumbnail) WINDOW.setProperty("RandomAlbumMB3." + str(item_count) + ".Path", playUrl) WINDOW.setProperty("RandomAlbumMB3." + str(item_count) + ".Rating", rating) WINDOW.setProperty( "RandomAlbumMB3." + str(item_count) + ".Art(fanart)", fanart) WINDOW.setProperty( "RandomAlbumMB3." + str(item_count) + ".Art(clearlogo)", logo) WINDOW.setProperty( "RandomAlbumMB3." + str(item_count) + ".Art(banner)", banner) WINDOW.setProperty( "RandomAlbumMB3." + str(item_count) + ".Art(poster)", thumbnail) WINDOW.setProperty("RandomAlbumMB3." + str(item_count) + ".Plot", plot) WINDOW.setProperty("RandomAlbumMB3.Enabled", "true") item_count = item_count + 1
class PlaybackUtils(): clientInfo = ClientInformation() doUtils = DownloadUtils() api = API() addon = xbmcaddon.Addon() language = addon.getLocalizedString addonName = clientInfo.getAddonName() def logMsg(self, msg, lvl=1): className = self.__class__.__name__ utils.logMsg("%s %s" % (self.addonName, className), msg, int(lvl)) def PLAY(self, result, setup = "service"): self.logMsg("PLAY Called", 1) api = self.api doUtils = self.doUtils username = utils.window('currUser') server = utils.window('server%s' % username) id = result['Id'] userdata = result['UserData'] # Get the playurl - direct play, direct stream or transcoding playurl = PlayUtils().getPlayUrl(server, id, result) listItem = xbmcgui.ListItem() if utils.window('playurlFalse') == "true": # Playurl failed - set in PlayUtils.py utils.window('playurlFalse', clear=True) self.logMsg("Failed to retrieve the playback path/url or dialog was cancelled.", 1) return xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listItem) ############### RESUME POINT ################ # Resume point for widget only timeInfo = api.getTimeInfo(result) jumpBackSec = int(utils.settings('resumeJumpBack')) seekTime = round(float(timeInfo.get('ResumeTime')), 6) if seekTime > jumpBackSec: # To avoid negative bookmark seekTime = seekTime - jumpBackSec # Show the additional resume dialog if launched from a widget if xbmc.getCondVisibility('Window.IsActive(home)') and seekTime: # Dialog presentation displayTime = str(datetime.timedelta(seconds=(int(seekTime)))) display_list = ["%s %s" % (self.language(30106), displayTime), self.language(30107)] resume_result = xbmcgui.Dialog().select(self.language(30105), display_list) if resume_result == 0: # User selected to resume, append resume point to listitem listItem.setProperty('StartOffset', str(seekTime)) elif resume_result > 0: # User selected to start from beginning seekTime = 0 else: # User cancelled the dialog self.logMsg("User cancelled resume dialog.", 1) return xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listItem) ############### ORGANIZE CURRENT PLAYLIST ################ # In order, intros, original item requested and any additional part playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) startPos = max(playlist.getposition(), 0) # Can return -1 sizePlaylist = playlist.size() currentPosition = startPos self.logMsg("Playlist start position: %s" % startPos, 2) self.logMsg("Playlist current position: %s" % currentPosition, 2) self.logMsg("Playlist size: %s" % sizePlaylist, 2) # Properties to ensure we have have proper playlists with additional items. introsPlaylist = False introProperty = utils.window('PlaylistIntroSet') == "true" dummyProperty = utils.window('PlaylistsetDummy') == "true" additionalProperty = utils.window('PlaylistAdditional') == "true" ############### -- CHECK FOR INTROS ################ if utils.settings('disableCinema') == "false" and not introProperty and not seekTime: # if we have any play them when the movie/show is not being resumed url = "{server}/mediabrowser/Users/{UserId}/Items/%s/Intros?format=json&ImageTypeLimit=1&Fields=Etag" % id intros = doUtils.downloadUrl(url) if intros['TotalRecordCount'] != 0: # The server randomly returns one custom intro intro = intros['Items'][0] introId = intro['Id'] introListItem = xbmcgui.ListItem() introPlayurl = PlayUtils().getPlayUrl(server, introId, intro) self.logMsg("Intro play: %s" % introPlayurl, 1) self.setProperties(introPlayurl, intro, introListItem) self.setListItemProps(server, introId, introListItem, intro) introsPlaylist = True utils.window('PlaylistIntroSet', value="true") playlist.add(introPlayurl, introListItem, index=currentPosition) currentPosition += 1 elif introProperty: # Play main item, do not play the intro since we already played it. Reset property for next time. utils.window('PlaylistIntroSet', clear=True) self.logMsg("Clear intro property.", 2) ############### -- SETUP MAIN ITEM ################ ##### Set listitem and properties for main item self.logMsg("Returned playurl: %s" % playurl, 1) listItem.setPath(playurl) self.setProperties(playurl, result, listItem) mainArt = API().getArtwork(result, "Primary") listItem.setThumbnailImage(mainArt) listItem.setIconImage(mainArt) if introsPlaylist and not sizePlaylist: # Extend our current playlist with the actual item to play only if there's no playlist first self.logMsg("No playlist detected at the start. Creating playlist with intro and play item.", 1) self.logMsg("Playlist current position: %s" % (currentPosition), 1) playlist.add(playurl, listItem, index=currentPosition) currentPosition += 1 ############### -- CHECK FOR ADDITIONAL PARTS ################ if result.get('PartCount') and not additionalProperty: # Only add to the playlist after intros have played url = "{server}/mediabrowser/Videos/%s/AdditionalParts" % id parts = doUtils.downloadUrl(url) for part in parts['Items']: partId = part['Id'] additionalPlayurl = PlayUtils().getPlayUrl(server, partId, part) additionalListItem = xbmcgui.ListItem() # Set listitem and properties for each additional parts self.logMsg("Adding to playlist: %s position: %s" % (additionalPlayurl, currentPosition), 1) self.setProperties(additionalPlayurl, part, additionalListItem) self.setListItemProps(server, partId, additionalListItem, part) # Add item to playlist, after the main item utils.window('PlaylistAdditional', value="true") playlist.add(additionalPlayurl, additionalListItem, index=currentPosition+1) currentPosition += 1 elif additionalProperty: # Additional parts are already set, reset property for next time utils.window('PlaylistAdditional', clear=True) self.logMsg("Clear additional property", 2) ############### PLAYBACK ################ if setup == "service" or xbmc.getCondVisibility('Window.IsActive(home)'): # Sent via websocketclient.py or default.py but via widgets self.logMsg("Detecting playback happening via service.py or home menu.", 1) self.setListItemProps(server, id, listItem, result) playlistPlayer = False if introsPlaylist and not sizePlaylist: # Extend our current playlist with the actual item to play only if there's no playlist first playlistPlayer = True elif sizePlaylist > 0 and not dummyProperty: # Playlist will fail on the current position. Adding dummy url playlist.add(playurl, index=startPos) self.logMsg("Adding dummy path as replacement for position: %s" % startPos, 2) utils.window('PlaylistsetDummy', value="true") playlistPlayer = True elif dummyProperty: # Already failed, play the item as a single item utils.window('PlaylistsetDummy', clear=True) self.logMsg("Clear dummy property.", 2) if playlistPlayer: self.logMsg("Processed as a playlist.", 1) return xbmc.Player().play(playlist) else: self.logMsg("Processed as a single item.", 1) return xbmc.Player().play(playurl, listItem) elif setup == "default": self.logMsg("Detecting playback happening via default.py.", 1) playlistPlayer = False if sizePlaylist > 0 and not dummyProperty: # Playlist will fail on the current position. Adding dummy url playlist.add(playurl, index=startPos) self.logMsg("Adding dummy path as replacement for position: %s" % startPos, 2) utils.window('PlaylistsetDummy', value="true") playlistPlayer = True elif dummyProperty: # Already failed, play the item as a single item utils.window('PlaylistsetDummy', clear=True) self.logMsg("Clear dummy property.", 2) if playlistPlayer: self.logMsg("Processed as a playlist.", 1) return xbmc.Player().play(playlist, startpos=startPos) else: # Sent via default.py self.logMsg("Processed as a single item.", 1) return xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listItem) def externalSubs(self, id, playurl, mediaSources): username = utils.window('currUser') server = utils.window('server%s' % username) externalsubs = [] mapping = {} mediaStream = mediaSources[0].get('MediaStreams') kodiindex = 0 for stream in mediaStream: index = stream['Index'] # Since Emby returns all possible tracks together, have to pull only external subtitles. # IsTextSubtitleStream if true, is available to download from emby. if "Subtitle" in stream['Type'] and stream['IsExternal'] and stream['IsTextSubtitleStream']: playmethod = utils.window("%splaymethod" % playurl) if "DirectPlay" in playmethod: # Direct play, get direct path url = PlayUtils().directPlay(stream) elif "DirectStream" in playmethod: # Direct stream url = "%s/Videos/%s/%s/Subtitles/%s/Stream.srt" % (server, id, id, index) # map external subtitles for mapping mapping[kodiindex] = index externalsubs.append(url) kodiindex += 1 mapping = json.dumps(mapping) utils.window('%sIndexMapping' % playurl, value=mapping) return externalsubs def setProperties(self, playurl, result, listItem): # Set runtimeticks, type, refresh_id and item_id id = result.get('Id') type = result.get('Type', "") utils.window("%sruntimeticks" % playurl, value=str(result.get('RunTimeTicks'))) utils.window("%stype" % playurl, value=type) utils.window("%sitem_id" % playurl, value=id) if type == "Episode": utils.window("%srefresh_id" % playurl, value=result.get('SeriesId')) else: utils.window("%srefresh_id" % playurl, value=id) if utils.window("%splaymethod" % playurl) != "Transcode": # Only for direct play and direct stream # Append external subtitles to stream subtitleList = self.externalSubs(id, playurl, result['MediaSources']) listItem.setSubtitles(subtitleList) def setArt(self, list, name, path): if name in {"thumb", "fanart_image", "small_poster", "tiny_poster", "medium_landscape", "medium_poster", "small_fanartimage", "medium_fanartimage", "fanart_noindicators"}: list.setProperty(name, path) else: list.setArt({name:path}) return list def setListItemProps(self, server, id, listItem, result): # Set up item and item info api = self.api type = result.get('Type') people = api.getPeople(result) studios = api.getStudios(result) metadata = { 'title': result.get('Name', "Missing name"), 'year': result.get('ProductionYear'), 'plot': api.getOverview(result), 'director': people.get('Director'), 'writer': people.get('Writer'), 'mpaa': api.getMpaa(result), 'genre': api.getGenre(result), 'studio': " / ".join(studios), 'aired': api.getPremiereDate(result), 'rating': result.get('CommunityRating'), 'votes': result.get('VoteCount') } if "Episode" in type: # Only for tv shows thumbId = result.get('SeriesId') season = result.get('ParentIndexNumber', -1) episode = result.get('IndexNumber', -1) show = result.get('SeriesName', "") metadata['TVShowTitle'] = show metadata['season'] = season metadata['episode'] = episode listItem.setProperty('IsPlayable', 'true') listItem.setProperty('IsFolder', 'false') listItem.setInfo('video', infoLabels=metadata) # Set artwork for listitem self.setArt(listItem,'poster', API().getArtwork(result, "Primary")) self.setArt(listItem,'tvshow.poster', API().getArtwork(result, "SeriesPrimary")) self.setArt(listItem,'clearart', API().getArtwork(result, "Art")) self.setArt(listItem,'tvshow.clearart', API().getArtwork(result, "Art")) self.setArt(listItem,'clearlogo', API().getArtwork(result, "Logo")) self.setArt(listItem,'tvshow.clearlogo', API().getArtwork(result, "Logo")) self.setArt(listItem,'discart', API().getArtwork(result, "Disc")) self.setArt(listItem,'fanart_image', API().getArtwork(result, "Backdrop")) self.setArt(listItem,'landscape', API().getArtwork(result, "Thumb")) def seekToPosition(self, seekTo): # Set a loop to wait for positive confirmation of playback count = 0 while not xbmc.Player().isPlaying(): count += 1 if count >= 10: return else: xbmc.sleep(500) # Jump to seek position count = 0 while xbmc.Player().getTime() < (seekToTime - 5) and count < 11: # only try 10 times count += 1 xbmc.Player().seekTime(seekTo) xbmc.sleep(100) def PLAYAllItems(self, items, startPositionTicks): self.logMsg("== ENTER: PLAYAllItems ==") self.logMsg("Items: %s" % items) doUtils = self.doUtils playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() started = False for itemId in items: self.logMsg("Adding Item to playlist: %s" % itemId, 1) url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json" % itemId result = doUtils.downloadUrl(url) addition = self.addPlaylistItem(playlist, result) if not started and addition: started = True self.logMsg("Starting Playback Pre", 1) xbmc.Player().play(playlist) if not started: self.logMsg("Starting Playback Post", 1) xbmc.Player().play(playlist) # Seek to position if startPositionTicks: seekTime = startPositionTicks / 10000000.0 self.seekToPosition(seekTime) def AddToPlaylist(self, itemIds): self.logMsg("== ENTER: PLAYAllItems ==") doUtils = self.doUtils playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) for itemId in itemIds: self.logMsg("Adding Item to Playlist: %s" % itemId) url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json" % itemId result = doUtils.downloadUrl(url) self.addPlaylistItem(playlist, result) return playlist def addPlaylistItem(self, playlist, item): id = item['Id'] username = utils.window('currUser') server = utils.window('server%s' % username) playurl = PlayUtils().getPlayUrl(server, id, item) if utils.window('playurlFalse') == "true": # Playurl failed - set in PlayUtils.py utils.window('playurlFalse', clear=True) self.logMsg("Failed to retrieve the playback path/url or dialog was cancelled.", 1) return self.logMsg("Playurl: %s" % playurl) thumb = API().getArtwork(item, "Primary") listItem = xbmcgui.ListItem(path=playurl, iconImage=thumb, thumbnailImage=thumb) self.setListItemProps(server, id, listItem, item) self.setProperties(playurl, item) playlist.add(playurl, listItem) # Not currently being used '''def PLAYAllEpisodes(self, items):
class PlaybackUtils(): settings = None language = addon.getLocalizedString logLevel = 0 downloadUtils = DownloadUtils() def __init__(self, *args): pass def PLAY(self, id): xbmc.log("PLAY Called") WINDOW = xbmcgui.Window(10000) username = WINDOW.getProperty('currUser') userid = WINDOW.getProperty('userId%s' % username) server = WINDOW.getProperty('server%s' % username) url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json&ImageTypeLimit=1" % id result = self.downloadUtils.downloadUrl(url) userData = result[u'UserData'] resume_result = 0 seekTime = 0 #get the resume point from Kodi DB for a Movie kodiItem = ReadKodiDB().getKodiMovie(id) if kodiItem != None: seekTime = int(round(kodiItem['resume'].get("position"))) else: #get the resume point from Kodi DB for an episode episodeItem = ReadEmbyDB().getItem(id) if episodeItem != None and str(episodeItem["Type"]) == "Episode": kodiItem = ReadKodiDB().getKodiEpisodeByMbItem(id,episodeItem["SeriesId"]) if kodiItem != None: seekTime = int(round(kodiItem['resume'].get("position"))) playurl = PlayUtils().getPlayUrl(server, id, result) isStrmFile = False thumbPath = API().getArtwork(result, "Primary") #workaround for when the file to play is a strm file itself if playurl.endswith(".strm"): isStrmFile = True tempPath = os.path.join(addondir,"library","temp.strm") xbmcvfs.copy(playurl, tempPath) sfile = open(tempPath, 'r') playurl = sfile.readline() sfile.close() xbmcvfs.delete(tempPath) WINDOW.setProperty("virtualstrm", id) WINDOW.setProperty("virtualstrmtype", result.get("Type")) listItem = xbmcgui.ListItem(path=playurl, iconImage=thumbPath, thumbnailImage=thumbPath) self.setListItemProps(server, id, listItem, result) # Can not play virtual items if (result.get("LocationType") == "Virtual"): xbmcgui.Dialog().ok(self.language(30128), self.language(30129)) watchedurl = "%s/mediabrowser/Users/%s/PlayedItems/%s" % (server, userid, id) positionurl = "%s/mediabrowser/Users/%s/PlayingItems/%s" % (server, userid, id) deleteurl = "%s/mediabrowser/Items/%s" % (server, id) # set the current playing info WINDOW.setProperty(playurl+"watchedurl", watchedurl) WINDOW.setProperty(playurl+"positionurl", positionurl) WINDOW.setProperty(playurl+"deleteurl", "") WINDOW.setProperty(playurl+"deleteurl", deleteurl) if seekTime != 0: displayTime = str(datetime.timedelta(seconds=seekTime)) display_list = [ self.language(30106) + ' ' + displayTime, self.language(30107)] resumeScreen = xbmcgui.Dialog() resume_result = resumeScreen.select(self.language(30105), display_list) if resume_result == 0: WINDOW.setProperty(playurl+"seektime", str(seekTime)) else: WINDOW.clearProperty(playurl+"seektime") else: WINDOW.clearProperty(playurl+"seektime") if result.get("Type")=="Episode": WINDOW.setProperty(playurl+"refresh_id", result.get("SeriesId")) else: WINDOW.setProperty(playurl+"refresh_id", id) WINDOW.setProperty(playurl+"runtimeticks", str(result.get("RunTimeTicks"))) WINDOW.setProperty(playurl+"type", result.get("Type")) WINDOW.setProperty(playurl+"item_id", id) if PlayUtils().isDirectPlay(result) == True: playMethod = "DirectPlay" else: playMethod = "Transcode" WINDOW.setProperty(playurl+"playmethod", playMethod) mediaSources = result.get("MediaSources") if(mediaSources != None): if mediaSources[0].get('DefaultAudioStreamIndex') != None: WINDOW.setProperty(playurl+"AudioStreamIndex", str(mediaSources[0].get('DefaultAudioStreamIndex'))) if mediaSources[0].get('DefaultSubtitleStreamIndex') != None: WINDOW.setProperty(playurl+"SubtitleStreamIndex", str(mediaSources[0].get('DefaultSubtitleStreamIndex'))) #this launches the playback #artwork only works with both resolvedurl and player command if isStrmFile: xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listItem) else: xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listItem) if(addon.getSetting("addExtraPlaybackArt") == "true"): utils.logMsg("PLAY", "Doing second xbmc.Player().play to add extra art") xbmc.Player().play(playurl,listItem) def setArt(self, list,name,path): if name=='thumb' or name=='fanart_image' or name=='small_poster' or name=='tiny_poster' or name == "medium_landscape" or name=='medium_poster' or name=='small_fanartimage' or name=='medium_fanartimage' or name=='fanart_noindicators': list.setProperty(name, path) else: list.setArt({name:path}) return list def setListItemProps(self, server, id, listItem, result): # set up item and item info thumbID = id eppNum = -1 seasonNum = -1 tvshowTitle = "" if(result.get("Type") == "Episode"): thumbID = result.get("SeriesId") seasonNum = result.get("ParentIndexNumber") eppNum = result.get("IndexNumber") tvshowTitle = result.get("SeriesName") self.setArt(listItem,'poster', API().getArtwork(result, "Primary")) self.setArt(listItem,'tvshow.poster', API().getArtwork(result, "SeriesPrimary")) self.setArt(listItem,'clearart', API().getArtwork(result, "Art")) self.setArt(listItem,'tvshow.clearart', API().getArtwork(result, "Art")) self.setArt(listItem,'clearlogo', API().getArtwork(result, "Logo")) self.setArt(listItem,'tvshow.clearlogo', API().getArtwork(result, "Logo")) self.setArt(listItem,'discart', API().getArtwork(result, "Disc")) self.setArt(listItem,'fanart_image', API().getArtwork(result, "Backdrop")) self.setArt(listItem,'landscape', API().getArtwork(result, "Thumb")) listItem.setProperty('IsPlayable', 'true') listItem.setProperty('IsFolder', 'false') # Process Studios studios = API().getStudios(result) if studios == []: studio = "" else: studio = studios[0] listItem.setInfo('video', {'studio' : studio}) # play info playinformation = '' if PlayUtils().isDirectPlay(result) == True: playinformation = self.language(30165) else: playinformation = self.language(30166) details = { 'title' : result.get("Name", "Missing Name") + ' - ' + playinformation, 'plot' : result.get("Overview") } if(eppNum > -1): details["episode"] = str(eppNum) if(seasonNum > -1): details["season"] = str(seasonNum) if tvshowTitle != None: details["TVShowTitle"] = tvshowTitle listItem.setInfo( "Video", infoLabels=details ) people = API().getPeople(result) # Process Genres genre = API().getGenre(result) listItem.setInfo('video', {'director' : people.get('Director')}) listItem.setInfo('video', {'writer' : people.get('Writer')}) listItem.setInfo('video', {'mpaa': result.get("OfficialRating")}) listItem.setInfo('video', {'genre': genre}) def seekToPosition(self, seekTo): #Set a loop to wait for positive confirmation of playback count = 0 while not xbmc.Player().isPlaying(): count = count + 1 if count >= 10: return else: xbmc.sleep(500) #Jump to resume point jumpBackSec = 10#int(self.settings.getSetting("resumeJumpBack")) seekToTime = seekTo - jumpBackSec count = 0 while xbmc.Player().getTime() < (seekToTime - 5) and count < 11: # only try 10 times count = count + 1 #xbmc.Player().pause #xbmc.sleep(100) xbmc.Player().seekTime(seekToTime) xbmc.sleep(100) #xbmc.Player().play() def PLAYAllItems(self, items, startPositionTicks): utils.logMsg("PlayBackUtils", "== ENTER: PLAYAllItems ==") utils.logMsg("PlayBackUtils", "Items : " + str(items)) WINDOW = xbmcgui.Window(10000) username = WINDOW.getProperty('currUser') userid = WINDOW.getProperty('userId%s' % username) server = WINDOW.getProperty('server%s' % username) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() started = False for itemID in items: utils.logMsg("PlayBackUtils", "Adding Item to Playlist : " + itemID) item_url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json" % itemID jsonData = self.downloadUtils.downloadUrl(item_url) item_data = jsonData added = self.addPlaylistItem(playlist, item_data, server, userid) if(added and started == False): started = True utils.logMsg("PlayBackUtils", "Starting Playback Pre") xbmc.Player().play(playlist) if(started == False): utils.logMsg("PlayBackUtils", "Starting Playback Post") xbmc.Player().play(playlist) #seek to position seekTime = 0 if(startPositionTicks != None): seekTime = (startPositionTicks / 1000) / 10000 if seekTime > 0: self.seekToPosition(seekTime) def PLAYAllEpisodes(self, items): WINDOW = xbmcgui.Window(10000) username = WINDOW.getProperty('currUser') userid = WINDOW.getProperty('userId%s' % username) server = WINDOW.getProperty('server%s' % username) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() for item in items: item_url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json&ImageTypeLimit=1" % item["Id"] jsonData = self.downloadUtils.downloadUrl(item_url) item_data = jsonData self.addPlaylistItem(playlist, item_data, server, userid) xbmc.Player().play(playlist) def AddToPlaylist(self, itemIds): utils.logMsg("PlayBackUtils", "== ENTER: PLAYAllItems ==") WINDOW = xbmcgui.Window(10000) username = WINDOW.getProperty('currUser') userid = WINDOW.getProperty('userId%s' % username) server = WINDOW.getProperty('server%s' % username) playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) for itemID in itemIds: utils.logMsg("PlayBackUtils", "Adding Item to Playlist : " + itemID) item_url = "{server}/mediabrowser/Users/{UserId}/Items/%s?format=json" % itemID jsonData = self.downloadUtils.downloadUrl(item_url) item_data = jsonData self.addPlaylistItem(playlist, item_data, server, userid) return playlist def addPlaylistItem(self, playlist, item, server, userid): id = item.get("Id") playurl = PlayUtils().getPlayUrl(server, id, item) utils.logMsg("PlayBackUtils", "Play URL: " + playurl) thumbPath = API().getArtwork(item, "Primary") listItem = xbmcgui.ListItem(path=playurl, iconImage=thumbPath, thumbnailImage=thumbPath) self.setListItemProps(server, id, listItem, item) WINDOW = xbmcgui.Window(10000) username = WINDOW.getProperty('currUser') userid = WINDOW.getProperty('userId%s' % username) server = WINDOW.getProperty('server%s' % username) # Can not play virtual items if (item.get("LocationType") == "Virtual") or (item.get("IsPlaceHolder") == True): xbmcgui.Dialog().ok(self.language(30128), self.language(30129)) return False else: watchedurl = "%s/mediabrowser/Users/%s/PlayedItems/%s" % (server, userid, id) positionurl = "%s/mediabrowser/Users/%s/PlayingItems/%s" % (server, userid, id) deleteurl = "%s/mediabrowser/Items/%s" % (server, id) # set the current playing info WINDOW = xbmcgui.Window( 10000 ) WINDOW.setProperty(playurl + "watchedurl", watchedurl) WINDOW.setProperty(playurl + "positionurl", positionurl) WINDOW.setProperty(playurl + "deleteurl", "") if item.get("Type") == "Episode" and addon.getSetting("offerDelete")=="true": WINDOW.setProperty(playurl + "deleteurl", deleteurl) WINDOW.setProperty(playurl + "runtimeticks", str(item.get("RunTimeTicks"))) WINDOW.setProperty(playurl+"type", item.get("Type")) WINDOW.setProperty(playurl + "item_id", id) if (item.get("Type") == "Episode"): WINDOW.setProperty(playurl + "refresh_id", item.get("SeriesId")) else: WINDOW.setProperty(playurl + "refresh_id", id) utils.logMsg("PlayBackUtils", "PlayList Item Url : " + str(playurl)) playlist.add(playurl, listItem) return True
def doSearch(self, searchTerm): movieResultsList = self.searchDialog.getControl(3110) while(movieResultsList.size() > 0): movieResultsList.removeItem(0) #movieResultsList.reset() seriesResultsList = self.searchDialog.getControl(3111) while(seriesResultsList.size() > 0): seriesResultsList.removeItem(0) #seriesResultsList.reset() episodeResultsList = self.searchDialog.getControl(3112) while(episodeResultsList.size() > 0): episodeResultsList.removeItem(0) #episodeResultsList.reset() if(len(searchTerm) == 0): return __settings__ = xbmcaddon.Addon(id='plugin.video.xbmb3c') port = __settings__.getSetting('port') host = __settings__.getSetting('ipaddress') server = host + ":" + port downloadUtils = DownloadUtils() userid = downloadUtils.getUserId() # # Process movies # search = urllib.quote(searchTerm) url = "http://" + server + "/mediabrowser/Search/Hints?SearchTerm=" + search + "&UserId=" + userid + "&Limit=10&IncludeItemTypes=Movie&format=json" jsonData = downloadUtils.downloadUrl(url, suppress=False, popup=1) result = json.loads(jsonData) items = result.get("SearchHints") if(items == None or len(items) == 0): item = [] for item in items: xbmc.log(str(item)) item_id = item.get("ItemId") item_name = item.get("Name") item_type = item.get("Type") typeLabel = "Movie" thumbPath = downloadUtils.imageUrl(item_id, "Primary", 0, 200, 200) xbmc.log(thumbPath) listItem = xbmcgui.ListItem(label=item_name, label2=typeLabel, iconImage=thumbPath, thumbnailImage=thumbPath) actionUrl = "plugin://plugin.video.xbmb3c?id=" + item_id + "&mode=" + str(_MODE_ITEM_DETAILS) listItem.setProperty("ActionUrl", actionUrl) movieResultsList.addItem(listItem) # # Process series # search = urllib.quote(searchTerm) url = "http://" + server + "/mediabrowser/Search/Hints?SearchTerm=" + search + "&UserId=" + userid + "&Limit=10&IncludeItemTypes=Series&format=json" jsonData = downloadUtils.downloadUrl(url, suppress=False, popup=1 ) result = json.loads(jsonData) items = result.get("SearchHints") if(items == None or len(items) == 0): item = [] for item in items: xbmc.log(str(item)) item_id = item.get("ItemId") item_name = item.get("Name") item_type = item.get("Type") typeLabel = "" image_id = "" image_id = item.get("ItemId") typeLabel = "Series" thumbPath = downloadUtils.imageUrl(image_id, "Primary", 0, 200, 200) xbmc.log(thumbPath) listItem = xbmcgui.ListItem(label=item_name, label2=typeLabel, iconImage=thumbPath, thumbnailImage=thumbPath) actionUrl = "plugin://plugin.video.xbmb3c?id=" + item_id + "&mode=" + str(_MODE_ITEM_DETAILS) listItem.setProperty("ActionUrl", actionUrl) seriesResultsList.addItem(listItem) # # Process episodes # search = urllib.quote(searchTerm) url = "http://" + server + "/mediabrowser/Search/Hints?SearchTerm=" + search + "&UserId=" + userid + "&Limit=10&IncludeItemTypes=Episode&format=json" jsonData = downloadUtils.downloadUrl(url, suppress=False, popup=1 ) result = json.loads(jsonData) items = result.get("SearchHints") if(items == None or len(items) == 0): item = [] for item in items: xbmc.log(str(item)) item_id = item.get("ItemId") item_name = item.get("Name") item_type = item.get("Type") image_id = item.get("ThumbImageItemId") season = item.get("ParentIndexNumber") eppNum = item.get("IndexNumber") typeLabel = "S" + str(season).zfill(2) + "E" + str(eppNum).zfill(2) thumbPath = downloadUtils.imageUrl(image_id, "Primary", 0, 200, 200) xbmc.log(thumbPath) listItem = xbmcgui.ListItem(label=item_name, label2=typeLabel, iconImage=thumbPath, thumbnailImage=thumbPath) actionUrl = "plugin://plugin.video.xbmb3c?id=" + item_id + "&mode=" + str(_MODE_ITEM_DETAILS) listItem.setProperty("ActionUrl", actionUrl) episodeResultsList.addItem(listItem)
def updateInfo(self): self.logMsg("updateInfo Called") addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') mb3Host = addonSettings.getSetting('ipaddress') mb3Port = addonSettings.getSetting('port') userName = addonSettings.getSetting('username') downloadUtils = DownloadUtils() userid = downloadUtils.getUserId() self.logMsg("updateInfo UserID : " + userid) self.logMsg("Updating info List") infoUrl = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Users/" + userid + "/Items?Fields=CollectionType&format=json" jsonData = downloadUtils.downloadUrl(infoUrl, suppress=True, popup=1 ) if(jsonData == ""): return result = json.loads(jsonData) result = result.get("Items") WINDOW = xbmcgui.Window( 10000 ) if(result == None): result = [] item_count = 1 movie_count = 0 movie_unwatched_count = 0 tv_count = 0 episode_count = 0 episode_unwatched_count = 0 tv_unwatched_count = 0 music_count = 0 music_songs_count = 0 music_songs_unplayed_count = 0 musicvideos_count = 0 musicvideos_unwatched_count = 0 trailers_count = 0 trailers_unwatched_count = 0 photos_count = 0 channels_count = 0 for item in result: collectionType = item.get("CollectionType") if collectionType==None: collectionType="unknown" self.logMsg("collectionType " + collectionType) userData = item.get("UserData") if(collectionType == "movies"): movie_count = movie_count + item.get("RecursiveItemCount") movie_unwatched_count = movie_unwatched_count + userData.get("UnplayedItemCount") if(collectionType == "musicvideos"): musicvideos_count = musicvideos_count + item.get("RecursiveItemCount") musicvideos_unwatched_count = musicvideos_unwatched_count + userData.get("UnplayedItemCount") if(collectionType == "tvshows"): tv_count = tv_count + item.get("ChildCount") episode_count = episode_count + item.get("RecursiveItemCount") episode_unwatched_count = episode_unwatched_count + userData.get("UnplayedItemCount") if(collectionType == "music"): music_count = music_count + item.get("ChildCount") music_songs_count = music_songs_count + item.get("RecursiveItemCount") music_songs_unplayed_count = music_songs_unplayed_count + userData.get("UnplayedItemCount") if(collectionType == "photos"): photos_count = photos_count + item.get("RecursiveItemCount") if(item.get("Name") == "Trailers"): trailers_count = trailers_count + item.get("RecursiveItemCount") trailers_unwatched_count = trailers_unwatched_count + userData.get("UnplayedItemCount") self.logMsg("MoviesCount " + str(movie_count), level=2) self.logMsg("MoviesUnWatchedCount " + str(movie_unwatched_count), level=2) self.logMsg("MusicVideosCount " + str(musicvideos_count), level=2) self.logMsg("MusicVideosUnWatchedCount " + str(musicvideos_unwatched_count), level=2) self.logMsg("TVCount " + str(tv_count), level=2) self.logMsg("EpisodeCount " + str(episode_count), level=2) self.logMsg("EpisodeUnWatchedCount " + str(episode_unwatched_count), level=2) self.logMsg("MusicCount " + str(music_count), level=2) self.logMsg("SongsCount " + str(music_songs_count), level=2) self.logMsg("SongsUnPlayedCount " + str(music_songs_unplayed_count), level=2) self.logMsg("TrailersCount" + str(trailers_count), level=2) self.logMsg("TrailersUnWatchedCount" + str(trailers_unwatched_count), level=2) self.logMsg("PhotosCount" + str(photos_count), level=2) #item_count = item_count + 1 movie_watched_count = movie_count - movie_unwatched_count musicvideos_watched_count = musicvideos_count - musicvideos_unwatched_count episode_watched_count = episode_count - episode_unwatched_count music_songs_played_count = music_songs_count - music_songs_unplayed_count trailers_watched_count = trailers_count - trailers_unwatched_count WINDOW.setProperty("MB3TotalMovies", str(movie_count)) WINDOW.setProperty("MB3TotalUnWatchedMovies", str(movie_unwatched_count)) WINDOW.setProperty("MB3TotalWatchedMovies", str(movie_watched_count)) WINDOW.setProperty("MB3TotalMusicVideos", str(musicvideos_count)) WINDOW.setProperty("MB3TotalUnWatchedMusicVideos", str(musicvideos_unwatched_count)) WINDOW.setProperty("MB3TotalWatchedMusicVideos", str(musicvideos_watched_count)) WINDOW.setProperty("MB3TotalTvShows", str(tv_count)) WINDOW.setProperty("MB3TotalEpisodes", str(episode_count)) WINDOW.setProperty("MB3TotalUnWatchedEpisodes", str(episode_unwatched_count)) WINDOW.setProperty("MB3TotalWatchedEpisodes", str(episode_watched_count)) WINDOW.setProperty("MB3TotalMusicAlbums", str(music_count)) WINDOW.setProperty("MB3TotalMusicSongs", str(music_songs_count)) WINDOW.setProperty("MB3TotalUnPlayedMusicSongs", str(music_songs_unplayed_count)) WINDOW.setProperty("MB3TotalPlayedMusicSongs", str(music_songs_played_count)) WINDOW.setProperty("MB3TotalTrailers", str(trailers_count)) WINDOW.setProperty("MB3TotalUnWatchedTrailers", str(trailers_unwatched_count)) WINDOW.setProperty("MB3TotalWatchedTrailers", str(trailers_watched_count)) WINDOW.setProperty("MB3TotalPhotos", str(photos_count)) userUrl = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Users/" + userid + "?format=json" jsonData = downloadUtils.downloadUrl(userUrl, suppress=True, popup=1 ) result = json.loads(jsonData) userImage = downloadUtils.getUserArtwork(result, "Primary") WINDOW.setProperty("MB3UserImage", userImage) if(result.get("Name") != None): userName = result.get("Name").encode('utf-8') WINDOW.setProperty("MB3UserName", userName) self.logMsg("InfoTV start") infoTVUrl = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Users/" + userid + "/Items?&IncludeItemTypes=Series&Recursive=true&SeriesStatus=Continuing&format=json" jsonData = downloadUtils.downloadUrl(infoTVUrl, suppress=True, popup=1 ) result = json.loads(jsonData) self.logMsg("InfoTV Json Data : " + str(result), level=2) totalRunning = result.get("TotalRecordCount") self.logMsg("TotalRunningCount " + str(totalRunning)) WINDOW.setProperty("MB3TotalRunningTvShows", str(totalRunning)) self.logMsg("InfoNextAired start") InfoNextAiredUrl = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Users/" + userid + "/Items?IsUnaired=true&SortBy=PremiereDate%2CAirTime%2CSortName&SortOrder=Ascending&IncludeItemTypes=Episode&Limit=1&Recursive=true&Fields=SeriesInfo%2CUserData&format=json" jsonData = downloadUtils.downloadUrl(InfoNextAiredUrl, suppress=True, popup=1 ) result = json.loads(jsonData) self.logMsg("InfoNextAired Json Data : " + str(result), level=2) result = result.get("Items") if(result == None): result = [] episode = "" for item in result: title = "" seriesName = "" if(item.get("SeriesName") != None): seriesName = item.get("SeriesName").encode('utf-8') if(item.get("Name") != None): title = item.get("Name").encode('utf-8') eppNumber = "" tempEpisodeNumber = "" if(item.get("IndexNumber") != None): eppNumber = item.get("IndexNumber") if eppNumber < 10: tempEpisodeNumber = "0" + str(eppNumber) else: tempEpisodeNumber = str(eppNumber) seasonNumber = item.get("ParentIndexNumber") if seasonNumber < 10: tempSeasonNumber = "0" + str(seasonNumber) else: tempSeasonNumber = str(seasonNumber) episode = seriesName + " - " + title + " - S" + tempSeasonNumber + "E" + tempEpisodeNumber self.logMsg("MB3NextAiredEpisode" + episode) WINDOW.setProperty("MB3NextAiredEpisode", episode) self.logMsg("InfoNextAired end") today = datetime.today() dateformat = today.strftime("%Y-%m-%d") nextAiredUrl = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Users/" + userid + "/Items?IsUnaired=true&SortBy=PremiereDate%2CAirTime%2CSortName&SortOrder=Ascending&IncludeItemTypes=Episode&Recursive=true&Fields=SeriesInfo%2CUserData&MinPremiereDate=" + str(dateformat) + "&MaxPremiereDate=" + str(dateformat) + "&format=json" jsonData = downloadUtils.downloadUrl(nextAiredUrl, suppress=True, popup=1 ) result = json.loads(jsonData) self.logMsg("InfoNextAired total url: " + nextAiredUrl) self.logMsg("InfoNextAired total Json Data : " + str(result), level=2) totalToday = result.get("TotalRecordCount") self.logMsg("MB3NextAiredTotalToday " + str(totalToday)) WINDOW.setProperty("MB3NextAiredTotalToday", str(totalToday)) self.logMsg("Channels start") channelsUrl = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Channels/?format=json" jsonData = downloadUtils.downloadUrl(channelsUrl, suppress=True, popup=1 ) result = json.loads(jsonData) self.logMsg("Channels Json Data : " + str(result), level=2) totalChannels = result.get("TotalRecordCount") self.logMsg("TotalChannels " + str(totalRunning)) WINDOW.setProperty("MB3TotalChannels", str(totalChannels))
class ItemInfo(xbmcgui.WindowXMLDialog): id = "" playUrl = "" trailerUrl = "" couchPotatoUrl = "" userid = "" server = "" downloadUtils = DownloadUtils() item = [] isTrailer = False def __init__(self, *args, **kwargs): xbmcgui.WindowXMLDialog.__init__(self, *args, **kwargs) xbmc.log("WINDOW INITIALISED") def onInit(self): self.action_exitkeys_id = [10, 13] __settings__ = xbmcaddon.Addon(id='plugin.video.xbmb3c') port = __settings__.getSetting('port') host = __settings__.getSetting('ipaddress') server = host + ":" + port self.server = server db = Database() userid = self.downloadUtils.getUserId() self.userid = userid jsonData = self.downloadUtils.downloadUrl( "http://" + server + "/mediabrowser/Users/" + userid + "/Items/" + self.id + "?Fields=SeriesGenres,AirTime&format=json", suppress=False, popup=1) item = json.loads(jsonData) self.item = item id = item.get("Id") WINDOW = xbmcgui.Window(10025) WINDOW.setProperty('ItemGUID', id) name = item.get("Name") image = self.downloadUtils.getArtwork(item, "poster") fanArt = self.downloadUtils.getArtwork(item, "BackdropNoIndicators") discart = db.get(id + ".Disc") # calculate the percentage complete userData = item.get("UserData") cappedPercentage = 0 if (userData != None): playBackTicks = float(userData.get("PlaybackPositionTicks")) if (playBackTicks != None and playBackTicks > 0): runTimeTicks = float(item.get("RunTimeTicks", "0")) if (runTimeTicks > 0): percentage = int((playBackTicks / runTimeTicks) * 100.0) cappedPercentage = percentage - (percentage % 10) if (cappedPercentage == 0): cappedPercentage = 10 if (cappedPercentage == 100): cappedPercentage = 90 try: watchedButton = self.getControl(3192) except: watchedButton = None if (watchedButton != None): if userData.get("Played") == True: watchedButton.setSelected(True) else: watchedButton.setSelected(False) try: dislikeButton = self.getControl(3193) except: dislikeButton = None if (dislikeButton != None): if userData.get("Likes") != None and userData.get( "Likes") == False: dislikeButton.setSelected(True) else: dislikeButton.setSelected(False) try: likeButton = self.getControl(3194) except: likeButton = None if (likeButton != None): if userData.get("Likes") != None and userData.get( "Likes") == True: likeButton.setSelected(True) else: likeButton.setSelected(False) try: favouriteButton = self.getControl(3195) except: favouriteButton = None if (favouriteButton != None): if userData.get("IsFavorite") == True: favouriteButton.setSelected(True) else: favouriteButton.setSelected(False) episodeInfo = "" type = item.get("Type") WINDOW.setProperty('ItemType', type) if (type == "Episode" or type == "Season"): WINDOW.setProperty('ItemGUID', item.get("SeriesId")) name = item.get("SeriesName") + ": " + name season = str(item.get("ParentIndexNumber")).zfill(2) episodeNum = str(item.get("IndexNumber")).zfill(2) episodeInfo = "S" + season + "xE" + episodeNum elif type == "Movie": if item.get("Taglines") != None and item.get( "Taglines") != [] and item.get("Taglines")[0] != None: episodeInfo = item.get("Taglines")[0] elif type == "ChannelVideoItem": if item.get("ExtraType") != None: if item.get('ExtraType') == "Trailer": self.isTrailer = True url = server + ',;' + id url = urllib.quote(url) self.playUrl = "plugin://plugin.video.xbmb3c/?url=" + url + '&mode=' + str( _MODE_BASICPLAY) self.peopleUrl = "XBMC.Container.Update(plugin://plugin.video.xbmb3c?mode=" + str( _MODE_CAST_LIST) + "&id=" + id + ")" #self.peopleUrl = "XBMC.RunPlugin(plugin://plugin.video.xbmb3c?mode=" + str(_MODE_CAST_LIST) + "&id=" + id + ")" try: trailerButton = self.getControl(3102) if (trailerButton != None): if not self.isTrailer and item.get( "LocalTrailerCount") != None and item.get( "LocalTrailerCount") > 0: itemTrailerUrl = "http://" + server + "/mediabrowser/Users/" + userid + "/Items/" + id + "/LocalTrailers?format=json" jsonData = self.downloadUtils.downloadUrl(itemTrailerUrl, suppress=False, popup=1) trailerItem = json.loads(jsonData) trailerUrl = server + ',;' + trailerItem[0].get("Id") trailerUrl = urllib.quote(trailerUrl) self.trailerUrl = "plugin://plugin.video.xbmb3c/?mode=" + str( _MODE_BASICPLAY) + "&url=" + trailerUrl else: trailerButton.setEnabled(False) except: pass try: couchPotatoButton = self.getControl(3103) if (couchPotatoButton != None): if self.isTrailer and item.get( "ProviderIds") != None and item.get("ProviderIds").get( "Imdb") != None: self.couchPotatoUrl = CP_ADD_VIA_IMDB + item.get( "ProviderIds").get("Imdb") elif self.isTrailer: self.couchPotatoUrl = CP_ADD_URL + name elif not self.isTrailer: couchPotatoButton.setEnabled(False) except: pass # all the media stream info mediaList = self.getControl(3220) mediaStreams = item.get("MediaStreams") if (mediaStreams != None): for mediaStream in mediaStreams: if (mediaStream.get("Type") == "Video"): videocodec = mediaStream.get("Codec") if (videocodec == "mpeg2video"): videocodec = "mpeg2" height = str(mediaStream.get("Height")) width = str(mediaStream.get("Width")) aspectratio = mediaStream.get("AspectRatio") fr = mediaStream.get("RealFrameRate") videoInfo = width + "x" + height + " " + videocodec + " " + str( round(fr, 2)) listItem = xbmcgui.ListItem("Video:", videoInfo) mediaList.addItem(listItem) if (mediaStream.get("Type") == "Audio"): audiocodec = mediaStream.get("Codec") channels = mediaStream.get("Channels") lang = mediaStream.get("Language") audioInfo = audiocodec + " " + str(channels) if (lang != None and len(lang) > 0 and lang != "und"): audioInfo = audioInfo + " " + lang listItem = xbmcgui.ListItem("Audio:", audioInfo) mediaList.addItem(listItem) if (mediaStream.get("Type") == "Subtitle"): lang = mediaStream.get("Language") codec = mediaStream.get("Codec") subInfo = codec if (lang != None and len(lang) > 0 and lang != "und"): subInfo = subInfo + " " + lang listItem = xbmcgui.ListItem("Sub:", subInfo) mediaList.addItem(listItem) #for x in range(0, 10): # listItem = xbmcgui.ListItem("Test:", "Test 02 " + str(x)) # mediaList.addItem(listItem) # add overview overview = item.get("Overview") self.getControl(3223).setText(overview) # add people peopleList = self.getControl(3230) people = item.get("People") director = '' writer = '' for person in people: displayName = person.get("Name") if person.get("Role") != None and person.get("Role") != '': role = "as " + person.get("Role") else: role = '' id = person.get("Id") tag = person.get("PrimaryImageTag") baseName = person.get("Name") baseName = baseName.replace(" ", "+") baseName = baseName.replace("&", "_") baseName = baseName.replace("?", "_") baseName = baseName.replace("=", "_") actionUrl = "plugin://plugin.video.xbmb3c?mode=" + str( _MODE_PERSON_DETAILS) + "&name=" + baseName if (tag != None and len(tag) > 0): thumbPath = self.downloadUtils.imageUrl( id, "Primary", 0, 400, 400) listItem = xbmcgui.ListItem(label=displayName, label2=role, iconImage=thumbPath, thumbnailImage=thumbPath) else: listItem = xbmcgui.ListItem(label=displayName, label2=role) listItem.setProperty("ActionUrl", actionUrl) peopleList.addItem(listItem) if (person.get("Type") == "Director") and director == '': director = displayName if (tag != None and len(tag) > 0): thumbPath = self.downloadUtils.imageUrl( id, "Primary", 0, 580, 860) directorlistItem = xbmcgui.ListItem( "Director:", label2=displayName, iconImage=thumbPath, thumbnailImage=thumbPath) else: directorlistItem = xbmcgui.ListItem("Director:", label2=displayName) directorlistItem.setProperty("ActionUrl", actionUrl) if (person.get("Type") == "Writing") and writer == '': writer = person.get("Name") if (tag != None and len(tag) > 0): thumbPath = self.downloadUtils.imageUrl( id, "Primary", 0, 580, 860) writerlistItem = xbmcgui.ListItem("Writer:", label2=displayName, iconImage=thumbPath, thumbnailImage=thumbPath) else: writerlistItem = xbmcgui.ListItem("Writer:", label2=displayName) writerlistItem.setProperty("ActionUrl", actionUrl) if (person.get("Type") == "Writer") and writer == '': writer = person.get("Name") if (tag != None and len(tag) > 0): thumbPath = self.downloadUtils.imageUrl( id, "Primary", 0, 580, 860) writerlistItem = xbmcgui.ListItem("Writer:", label2=displayName, iconImage=thumbPath, thumbnailImage=thumbPath) else: writerlistItem = xbmcgui.ListItem("Writer:", label2=displayName) writerlistItem.setProperty("ActionUrl", actionUrl) # add general info infoList = self.getControl(3226) listItem = xbmcgui.ListItem("Year:", str(item.get("ProductionYear"))) infoList.addItem(listItem) listItem = xbmcgui.ListItem("Rating:", str(item.get("CommunityRating"))) infoList.addItem(listItem) listItem = xbmcgui.ListItem("MPAA:", str(item.get("OfficialRating"))) infoList.addItem(listItem) duration = str(int(item.get("RunTimeTicks", "0")) / (10000000 * 60)) listItem = xbmcgui.ListItem("RunTime:", str(duration) + " Minutes") infoList.addItem(listItem) genre = "" genres = item.get("Genres") if genres != None and genres != []: for genre_string in genres: if genre == "": #Just take the first genre genre = genre_string else: genre = genre + " / " + genre_string elif item.get("SeriesGenres") != None and item.get( "SeriesGenres") != '': genres = item.get("SeriesGenres") if genres != None and genres != []: for genre_string in genres: if genre == "": #Just take the first genre genre = genre_string else: genre = genre + " / " + genre_string genrelistItem = xbmcgui.ListItem("Genre:", genre) genrelistItem2 = xbmcgui.ListItem("Genre:", genre) infoList.addItem(genrelistItem) path = item.get('Path') pathlistItem = xbmcgui.ListItem("Path:", path) pathlistItem2 = xbmcgui.ListItem("Path:", path) infoList.addItem(pathlistItem) if item.get("CriticRating") != None: listItem = xbmcgui.ListItem("CriticRating:", str(item.get("CriticRating"))) infoList.addItem(listItem) # Process Studio studio = "" if item.get("SeriesStudio") != None and item.get("SeriesStudio") != '': studio = item.get("SeriesStudio") if studio == "": studios = item.get("Studios") if (studios != None): for studio_string in studios: if studio == "": #Just take the first one temp = studio_string.get("Name") studio = temp.encode('utf-8') if studio != "": listItem = xbmcgui.ListItem("Studio:", studio) infoList.addItem(listItem) if item.get("Metascore") != None: listItem = xbmcgui.ListItem("Metascore:", str(item.get("Metascore"))) infoList.addItem(listItem) playCount = 0 if (userData != None and userData.get("Played") == True): playCount = 1 listItem = xbmcgui.ListItem("PlayedCount:", str(playCount)) infoList.addItem(listItem) if item.get("ProviderIds") != None and item.get("ProviderIds").get( "Imdb") != None and type == "Movie": listItem = xbmcgui.ListItem("ID:", item.get("ProviderIds").get("Imdb")) infoList.addItem(listItem) elif item.get("ProviderIds") != None and item.get("ProviderIds").get( "Tvdb") != None and type == "Series": listItem = xbmcgui.ListItem("ID:", item.get("ProviderIds").get("Tvdb")) infoList.addItem(listItem) elif (type == "Episode" or type == "Season"): jsonData = self.downloadUtils.downloadUrl( "http://" + server + "/mediabrowser/Users/" + userid + "/Items/" + item.get("SeriesId") + "?Fields=SeriesGenres,AirTime&format=json", suppress=False, popup=1) seriesitem = json.loads(jsonData) if seriesitem.get("ProviderIds") != None and seriesitem.get( "ProviderIds").get("Tvdb") != None: listItem = xbmcgui.ListItem( "ID:", seriesitem.get("ProviderIds").get("Tvdb")) infoList.addItem(listItem) # alternate list try: alternateList = self.getControl(3291) if alternateList != None: if directorlistItem != None: alternateList.addItem(directorlistItem) if writerlistItem != None: alternateList.addItem(writerlistItem) alternateList.addItem(genrelistItem2) if item.get("ProductionLocations") != None and item.get( "ProductionLocations") != []: listItem = xbmcgui.ListItem( "Country:", item.get("ProductionLocations")[0]) alternateList.addItem(listItem) elif item.get("AirTime") != None: listItem = xbmcgui.ListItem("Air Time:", item.get("AirTime")) alternateList.addItem(listItem) if (item.get("PremiereDate") != None): premieredatelist = (item.get("PremiereDate")).split("T") premieredate = premieredatelist[0] listItem = xbmcgui.ListItem("Premiered Date:", premieredate) alternateList.addItem(listItem) alternateList.addItem(pathlistItem2) except: pass # add resume percentage text to name addResumePercent = __settings__.getSetting( 'addResumePercent') == 'true' if (addResumePercent and cappedPercentage != 0): name = name + " (" + str(cappedPercentage) + "%)" self.getControl(3000).setLabel(name) self.getControl(3003).setLabel(episodeInfo) self.getControl(3001).setImage(fanArt) try: discartImageControl = self.getControl(3091) artImageControl = self.getControl(3092) thumbImageControl = self.getControl(3093) if discartImageControl != None and artImageControl != None and thumbImageControl != None: if discart != '': self.getControl(3091).setImage(discart) self.getControl(3092).setVisible(False) self.getControl(3093).setVisible(False) else: self.getControl(3091).setVisible(False) art = db.get(id + ".Art") if (artImageControl != None): if art != '': self.getControl(3092).setImage(art) self.getControl(3093).setVisible(False) else: self.getControl(3092).setVisible(False) if (type == "Episode"): thumb = db.get(item.get("SeriesId") + ".Thumb") else: thumb = db.get(id + ".Thumb") if (thumbImageControl != None): if thumb != '': self.getControl(3093).setImage(thumb) else: self.getControl(3093).setVisible(False) except: pass if (type == "Episode"): # null_pointer - I have removed this in favor of letting the user chose from the setting and using the "poster" type in the above image url create #image = self.downloadUtils.getArtwork(seriesitem, "Primary") seriesimage = db.get(item.get("SeriesId") + ".Primary3") try: self.getControl(3099).setImage(seriesimage) except: pass self.getControl(3009).setImage(image) if (cappedPercentage != None): self.getControl(3010).setImage("Progress\progress_" + str(cappedPercentage) + ".png") else: self.getControl(3011).setImage(image) if (cappedPercentage != None): self.getControl(3012).setImage("Progress\progress_" + str(cappedPercentage) + ".png") # disable play button if (type == "Season" or type == "Series"): self.setFocusId(3226) self.getControl(3002).setEnabled(False) def setId(self, id): self.id = id def onFocus(self, controlId): pass def doAction(self): pass def closeDialog(self): self.close() def onClick(self, controlID): if (controlID == 3002): # close all dialogs when playing an item xbmc.executebuiltin("Dialog.Close(all,true)") xbmc.executebuiltin("RunPlugin(" + self.playUrl + ")") self.close() elif (controlID == 3102): # close all dialogs when playing an item xbmc.executebuiltin("Dialog.Close(all,true)") xbmc.executebuiltin("RunPlugin(" + self.trailerUrl + ")") self.close() elif (controlID == 3103): # close all dialogs when playing an item xbmc.executebuiltin("Dialog.Close(all,true)") xbmc.executebuiltin("RunPlugin(" + self.couchPotatoUrl + ")") elif (controlID == 3230): peopleList = self.getControl(3230) item = peopleList.getSelectedItem() action = item.getProperty("ActionUrl") xbmc.log(action) xbmc.executebuiltin("RunPlugin(" + action + ")") elif (controlID == 3291): list = self.getControl(3291) item = list.getSelectedItem() action = item.getProperty("ActionUrl") xbmc.log(action) xbmc.executebuiltin("RunPlugin(" + action + ")") elif (controlID == 3192): url = 'http://' + self.server + '/mediabrowser/Users/' + self.userid + '/PlayedItems/' + self.id button = self.getControl(3192) watched = button.isSelected() if watched == True: self.postUrl(url) else: self.deleteUrl(url) self.onInit() elif (controlID == 3193): url = 'http://' + self.server + '/mediabrowser/Users/' + self.userid + '/Items/' + self.id + '/Rating' dislikebutton = self.getControl(3193) dislike = dislikebutton.isSelected() if dislike == True: url = url + '?likes=false' self.postUrl(url) else: self.deleteUrl(url) self.onInit() elif (controlID == 3194): url = 'http://' + self.server + '/mediabrowser/Users/' + self.userid + '/Items/' + self.id + '/Rating' likebutton = self.getControl(3194) like = likebutton.isSelected() if like == True: url = url + '?likes=true' self.postUrl(url) else: self.deleteUrl(url) self.onInit() elif (controlID == 3195): url = 'http://' + self.server + '/mediabrowser/Users/' + self.userid + '/FavoriteItems/' + self.id button = self.getControl(3195) favourite = button.isSelected() if favourite == True: self.postUrl(url) else: self.deleteUrl(url) self.onInit() elif (controlID == 3006): url = "http://" + self.server + "/mediabrowser/Users/" + self.userid + "/PlayingItems/" + self.id + "/Progress?PositionTicks=0" self.postUrl(url) self.onInit() pass def postUrl(self, url): self.downloadUtils.downloadUrl(url, postBody="", type="POST") WINDOW = xbmcgui.Window(10000) WINDOW.setProperty("force_data_reload", "true") guid = xbmcgui.Window(10025).getProperty("ItemGUID") BackgroundDataUpdaterThread().updateItem(guid) xbmc.executebuiltin("Container.Refresh") def deleteUrl(self, url): self.downloadUtils.downloadUrl(url, type="DELETE") WINDOW = xbmcgui.Window(10000) WINDOW.setProperty("force_data_reload", "true") guid = xbmcgui.Window(10025).getProperty("ItemGUID") BackgroundDataUpdaterThread().updateItem(guid) xbmc.executebuiltin("Container.Refresh")
def onInit(self): self.action_exitkeys_id = [10, 13] __settings__ = xbmcaddon.Addon(id='plugin.video.xbmb3c') port = __settings__.getSetting('port') host = __settings__.getSetting('ipaddress') server = host + ":" + port downloadUtils = DownloadUtils() userid = downloadUtils.getUserId() jsonData = downloadUtils.downloadUrl( "http://" + server + "/mediabrowser/Persons/" + self.personName + "?format=json", suppress=False, popup=1) result = json.loads(jsonData) name = result.get("Name") id = result.get("Id") # other lib items count contentCounts = "" if (result.get("AdultVideoCount") != None and result.get("AdultVideoCount") > 0): contentCounts = contentCounts + "\nAdult Count : " + str( result.get("AdultVideoCount")) if (result.get("MovieCount") != None and result.get("MovieCount") > 0): contentCounts = contentCounts + "\nMovie Count : " + str( result.get("MovieCount")) if (result.get("SeriesCount") != None and result.get("SeriesCount") > 0): contentCounts = contentCounts + "\nSeries Count : " + str( result.get("SeriesCount")) if (result.get("EpisodeCount") != None and result.get("EpisodeCount") > 0): contentCounts = contentCounts + "\nEpisode Count : " + str( result.get("EpisodeCount")) if (len(contentCounts) > 0): contentCounts = "Total Library Counts:" + contentCounts #overview overview = "" if (len(contentCounts) > 0): overview = contentCounts + "\n\n" over = result.get("Overview") if (over == None or over == ""): overview = overview + "No details available" else: overview = overview + over #person image image = downloadUtils.getArtwork(result, "Primary") #get other movies encoded = name.encode("utf-8") encoded = urllib.quote(encoded) url = "http://" + server + "/mediabrowser/Users/" + userid + "/Items/?Recursive=True&Person=" + encoded + "&format=json" xbmc.log("URL: " + url) jsonData = downloadUtils.downloadUrl(url, suppress=False, popup=1) otherMovieResult = json.loads(jsonData) baseName = name.replace(" ", "+") baseName = baseName.replace("&", "_") baseName = baseName.replace("?", "_") baseName = baseName.replace("=", "_") #detailsString = getDetailsString() #search_url = "http://" + host + ":" + port + "/mediabrowser/Users/" + userid + "/Items/?Recursive=True&Person=PERSON_NAME&Fields=" + detailsString + "&format=json" search_url = "http://" + host + ":" + port + "/mediabrowser/Users/" + userid + "/Items/?Recursive=True&Person=PERSON_NAME&format=json" search_url = urllib.quote(search_url) search_url = search_url.replace("PERSON_NAME", baseName) self.pluginCastLink = "XBMC.Container.Update(plugin://plugin.video.xbmb3c?mode=" + str( _MODE_GETCONTENT) + "&url=" + search_url + ")" otherItemsList = None try: otherItemsList = self.getControl(3010) items = otherMovieResult.get("Items") if (items == None): items = [] for item in items: item_id = item.get("Id") item_name = item.get("Name") type_info = "" image_id = item_id item_type = item.get("Type") if (item_type == "Season"): image_id = item.get("SeriesId") season = item.get("IndexNumber") type_info = "Season " + str(season).zfill(2) elif (item_type == "Series"): image_id = item.get("Id") type_info = "Series" elif (item_type == "Movie"): image_id = item.get("Id") type_info = "Movie" elif (item_type == "Episode"): image_id = item.get("SeriesId") season = item.get("ParentIndexNumber") eppNum = item.get("IndexNumber") type_info = "S" + str(season).zfill(2) + "E" + str( eppNum).zfill(2) thumbPath = downloadUtils.imageUrl(image_id, "Primary", 0, 200, 200) fanArt = downloadUtils.imageUrl(image_id, "Backdrop", 0, 10000, 10000) listItem = xbmcgui.ListItem(label=item_name, label2=type_info, iconImage=thumbPath, thumbnailImage=thumbPath) listItem.setArt({"fanart": fanArt}) actionUrl = "plugin://plugin.video.xbmb3c?id=" + item_id + "&mode=" + str( _MODE_ITEM_DETAILS) listItem.setProperty("ActionUrl", actionUrl) otherItemsList.addItem(listItem) except Exception, e: xbmc.log("Exception : " + str(e)) pass
class UserClient(threading.Thread): # Borg - multiple instances, shared state _shared_state = {} clientInfo = ClientInformation() doUtils = DownloadUtils() KodiMonitor = KodiMonitor.Kodi_Monitor() addonName = clientInfo.getAddonName() addon = xbmcaddon.Addon() WINDOW = xbmcgui.Window(10000) stopClient = False logLevel = int(addon.getSetting('logLevel')) auth = True retry = 0 currUser = None currUserId = None currServer = None currToken = None HasAccess = True AdditionalUser = [] def __init__(self, *args): self.__dict__ = self._shared_state threading.Thread.__init__(self, *args) def logMsg(self, msg, lvl=1): className = self.__class__.__name__ utils.logMsg("%s %s" % (self.addonName, className), str(msg), int(lvl)) def getUsername(self): username = utils.settings('username') if (username == ""): self.logMsg("No username saved.", 2) return "" return username def getAdditionalUsers(self): additionalUsers = utils.settings('additionalUsers') if additionalUsers: self.AdditionalUser = additionalUsers.split(',') def getLogLevel(self): try: logLevel = int(utils.settings('logLevel')) except: logLevel = 0 return logLevel def getUserId(self): username = self.getUsername() w_userId = self.WINDOW.getProperty('userId%s' % username) s_userId = utils.settings('userId%s' % username) # Verify the window property if (w_userId != ""): self.logMsg( "Returning userId from WINDOW for username: %s UserId: %s" % (username, w_userId), 2) return w_userId # Verify the settings elif (s_userId != ""): self.logMsg( "Returning userId from SETTINGS for username: %s userId: %s" % (username, s_userId), 2) return s_userId # No userId found else: self.logMsg("No userId saved for username: %s." % username) return def getServer(self, prefix=True): alternate = utils.settings('altip') == "true" # For https support HTTPS = utils.settings('https') host = utils.settings('ipaddress') port = utils.settings('port') # Alternate host if alternate: HTTPS = utils.settings('secondhttps') host = utils.settings('secondipaddress') port = utils.settings('secondport') server = host + ":" + port if host == "": self.logMsg("No server information saved.", 2) return "" # If https is true if prefix and (HTTPS == "true"): server = "https://%s" % server return server # If https is false elif prefix and (HTTPS == "false"): server = "http://%s" % server return server # If only the host:port is required elif (prefix == False): return server def getToken(self): username = self.getUsername() w_token = self.WINDOW.getProperty('accessToken%s' % username) s_token = utils.settings('accessToken') # Verify the window property if (w_token != ""): self.logMsg( "Returning accessToken from WINDOW for username: %s accessToken: %s" % (username, w_token), 2) return w_token # Verify the settings elif (s_token != ""): self.logMsg( "Returning accessToken from SETTINGS for username: %s accessToken: %s" % (username, s_token), 2) self.WINDOW.setProperty('accessToken%s' % username, s_token) return s_token else: self.logMsg("No token found.") return "" def getSSLverify(self): # Verify host certificate s_sslverify = utils.settings('sslverify') if utils.settings('altip') == "true": s_sslverify = utils.settings('secondsslverify') if s_sslverify == "true": return True else: return False def getSSL(self): # Client side certificate s_cert = utils.settings('sslcert') if utils.settings('altip') == "true": s_cert = utils.settings('secondsslcert') if s_cert == "None": return None else: return s_cert def setUserPref(self): player = Player() server = self.getServer() userId = self.getUserId() url = "{server}/mediabrowser/Users/{UserId}?format=json" result = self.doUtils.downloadUrl(url) # Set user image for skin display self.WINDOW.setProperty("EmbyUserImage", API().getUserArtwork(result, "Primary")) # Load the resume point from Emby and set as setting url = "{server}/mediabrowser/System/Configuration?format=json" result = self.doUtils.downloadUrl(url) utils.settings('markPlayed', value=str(result['MaxResumePct'])) return True def getPublicUsers(self): server = self.getServer() # Get public Users url = "%s/mediabrowser/Users/Public?format=json" % server result = self.doUtils.downloadUrl(url, authenticate=False) users = [] if (result != ""): users = result else: # Server connection failed return False return users def hasAccess(self): url = "{server}/mediabrowser/Users" result = self.doUtils.downloadUrl(url) if result is False: # Access is restricted self.logMsg("Access is restricted.") self.HasAccess = False return elif self.WINDOW.getProperty('Server_online') != "true": # Server connection failed return if self.WINDOW.getProperty("Server_status") == "restricted": self.logMsg("Access is granted.") self.HasAccess = True self.WINDOW.setProperty("Server_status", "") xbmcgui.Dialog().notification("Emby server", "Access is enabled.") return def loadCurrUser(self, authenticated=False): WINDOW = self.WINDOW doUtils = self.doUtils username = self.getUsername() # Only to be used if token exists self.currUserId = self.getUserId() self.currServer = self.getServer() self.currToken = self.getToken() self.ssl = self.getSSLverify() self.sslcert = self.getSSL() # Test the validity of current token if authenticated == False: url = "%s/mediabrowser/Users/%s" % (self.currServer, self.currUserId) WINDOW.setProperty("currUser", username) WINDOW.setProperty("accessToken%s" % username, self.currToken) result = doUtils.downloadUrl(url) if result == 401: # Token is no longer valid self.resetClient() return False # Set to windows property WINDOW.setProperty("currUser", username) WINDOW.setProperty("accessToken%s" % username, self.currToken) WINDOW.setProperty("server%s" % username, self.currServer) WINDOW.setProperty("server_%s" % username, self.getServer(prefix=False)) WINDOW.setProperty("userId%s" % username, self.currUserId) # Set DownloadUtils values doUtils.setUsername(username) doUtils.setUserId(self.currUserId) doUtils.setServer(self.currServer) doUtils.setToken(self.currToken) doUtils.setSSL(self.ssl, self.sslcert) # parental control - let's verify if access is restricted self.hasAccess() # Start DownloadUtils session doUtils.startSession() self.getAdditionalUsers() # Set user preferences in settings self.setUserPref() self.currUser = username def authenticate(self): WINDOW = self.WINDOW addon = self.addon username = self.getUsername() server = self.getServer() addondir = xbmc.translatePath( self.addon.getAddonInfo('profile')).decode('utf-8') hasSettings = xbmcvfs.exists("%ssettings.xml" % addondir) # If there's no settings.xml if (hasSettings == 0): self.logMsg("No settings.xml found.") self.auth = False return # If no user information if (server == "") or (username == ""): self.logMsg("Missing server information.") self.auth = False return # If there's a token if (self.getToken() != ""): result = self.loadCurrUser() if result == False: pass else: self.logMsg("Current user: %s" % self.currUser, 0) self.logMsg("Current userId: %s" % self.currUserId, 0) self.logMsg("Current accessToken: %s" % self.currToken, 0) return users = self.getPublicUsers() password = "" # Find user in list for user in users: name = user[u'Name'] userHasPassword = False if (unicode(username, 'utf-8') in name): # Verify if user has a password if (user.get("HasPassword") == True): userHasPassword = True # If user has password if (userHasPassword): password = xbmcgui.Dialog().input( "Enter password for user: %s" % username, option=xbmcgui.ALPHANUM_HIDE_INPUT) # If password dialog is cancelled if (password == ""): self.logMsg("No password entered.", 0) self.WINDOW.setProperty("Server_status", "Stop") self.auth = False return break else: # Manual login, user is hidden password = xbmcgui.Dialog().input( "Enter password for user: %s" % username, option=xbmcgui.ALPHANUM_HIDE_INPUT) sha1 = hashlib.sha1(password) sha1 = sha1.hexdigest() # Authenticate username and password url = "%s/mediabrowser/Users/AuthenticateByName?format=json" % server data = {'username': username, 'password': sha1} self.logMsg(data, 2) result = self.doUtils.downloadUrl(url, postBody=data, type="POST", authenticate=False) accessToken = None try: self.logMsg("Auth_Reponse: %s" % result, 1) accessToken = result[u'AccessToken'] except: pass if (result != None and accessToken != None): self.currUser = username xbmcgui.Dialog().notification("Emby server", "Welcome %s!" % self.currUser) userId = result[u'User'][u'Id'] utils.settings("accessToken", accessToken) utils.settings("userId%s" % username, userId) self.logMsg("User Authenticated: %s" % accessToken) self.loadCurrUser(authenticated=True) self.WINDOW.setProperty("Server_status", "") self.retry = 0 return else: self.logMsg("User authentication failed.") utils.settings("accessToken", "") utils.settings("userId%s" % username, "") xbmcgui.Dialog().ok("Error connecting", "Invalid username or password.") # Give two attempts at entering password self.retry += 1 if self.retry == 2: self.logMsg( "Too many retries. You can retry by selecting the option in the addon settings." ) self.WINDOW.setProperty("Server_status", "Stop") xbmcgui.Dialog().ok( "Error connecting", "Failed to authenticate too many times. You can retry by selecting the option in the addon settings." ) self.auth = False return def resetClient(self): username = self.getUsername() self.logMsg("Reset UserClient authentication.", 1) if (self.currToken != None): # In case of 401, removed saved token utils.settings("accessToken", "") self.WINDOW.setProperty("accessToken%s" % username, "") self.currToken = None self.logMsg("User token has been removed.", 1) self.auth = True self.currUser = None return def run(self): self.logMsg("|---- Starting UserClient ----|", 0) while not self.KodiMonitor.abortRequested(): # Verify the log level currLogLevel = self.getLogLevel() if self.logLevel != currLogLevel: # Set new log level self.logLevel = currLogLevel self.logMsg("New Log Level: %s" % currLogLevel, 0) self.WINDOW.setProperty('getLogLevel', str(currLogLevel)) if (self.WINDOW.getProperty("Server_status") != ""): status = self.WINDOW.getProperty("Server_status") if status == "restricted": # Parental control is restricting access self.HasAccess = False elif status == "401": self.WINDOW.setProperty("Server_status", "Auth") # Revoked token self.resetClient() if self.auth and (self.currUser == None): status = self.WINDOW.getProperty("Server_status") if (status == "") or (status == "Auth"): self.auth = False self.authenticate() if (self.auth == False) and (self.currUser == None): # Only if there's information found to login server = self.getServer() username = self.getUsername() status = self.WINDOW.getProperty("Server_status") # If user didn't enter a password when prompted if status == "Stop": pass elif (server != "") and (username != ""): self.logMsg("Server found: %s" % server) self.logMsg("Username found: %s" % username) self.auth = True # If stopping the client didn't work if self.stopClient == True: break if self.KodiMonitor.waitForAbort(1): # Abort was requested while waiting. We should exit break self.doUtils.stopSession() self.logMsg("|---- UserClient Stopped ----|", 0) def stopClient(self): # As last resort self.stopClient = True