def stopAll(played_information): if(len(played_information) == 0): return addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') xbmc.log ("XBMB3C Service -> played_information : " + str(played_information)) for item_url in played_information: data = played_information.get(item_url) if(data != None): xbmc.log ("XBMB3C Service -> item_url : " + item_url) xbmc.log ("XBMB3C Service -> item_data : " + str(data)) watchedurl = data.get("watchedurl") positionurl = data.get("positionurl") deleteurl = data.get("deleteurl") runtime = data.get("runtime") currentPossition = data.get("currentPossition") item_id = data.get("item_id") if(currentPossition != None and hasData(runtime) and hasData(positionurl) and hasData(watchedurl)): runtimeTicks = int(runtime) xbmc.log ("XBMB3C Service -> runtimeticks:" + str(runtimeTicks)) percentComplete = (currentPossition * 10000000) / runtimeTicks markPlayedAt = float(addonSettings.getSetting("markPlayedAt")) / 100 xbmc.log ("XBMB3C Service -> Percent Complete:" + str(percentComplete) + " Mark Played At:" + str(markPlayedAt)) if (percentComplete > markPlayedAt): gotDeleted = 0 if(deleteurl != None and deleteurl != ""): xbmc.log ("XBMB3C Service -> Offering Delete:" + str(deleteurl)) gotDeleted = deleteItem(deleteurl) if(gotDeleted == 0): setPosition(positionurl + '/Progress?PositionTicks=0', 'POST') if(newWebSocketThread != None): newWebSocketThread.playbackStopped(item_id, str(0)) markWatched(watchedurl) else: #markUnWatched(watchedurl) # this resets the LastPlayedDate and that causes issues with sortby PlayedDate so I removed it for now if(newWebSocketThread != None): newWebSocketThread.playbackStopped(item_id, str(int(currentPossition * 10000000))) setPosition(positionurl + '?PositionTicks=' + str(int(currentPossition * 10000000)), 'DELETE') if(newNextUpThread != None): newNextUpThread.updateNextUp() if(artworkRotationThread != None): artworkRotationThread.updateActionUrls() played_information.clear() # stop transcoding - todo check we are actually transcoding? clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() url = ("http://%s:%s/mediabrowser/Videos/ActiveEncodings" % (addonSettings.getSetting('ipaddress'), addonSettings.getSetting('port'))) url = url + '?DeviceId=' + txt_mac stopTranscoding(url)
def getAuthHeader(self, authenticate=True): clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() version = clientInfo.getVersion() deviceName = self.addonSettings.getSetting('deviceName') deviceName = deviceName.replace("\"", "_") if (authenticate == False): authString = "MediaBrowser Client=\"Kodi\",Device=\"" + deviceName + "\",DeviceId=\"" + txt_mac + "\",Version=\"" + version + "\"" headers = { "Accept-encoding": "gzip", "Accept-Charset": "UTF-8,*", "Authorization": authString } return headers else: userid = self.getUserId() authString = "MediaBrowser UserId=\"" + userid + "\",Client=\"Kodi\",Device=\"" + deviceName + "\",DeviceId=\"" + txt_mac + "\",Version=\"" + version + "\"" headers = { "Accept-encoding": "gzip", "Accept-Charset": "UTF-8,*", "Authorization": authString } authToken = self.authenticate() if (authToken != ""): headers["X-MediaBrowser-Token"] = authToken self.logMsg("Authentication Header : " + str(headers)) return headers
def postcapabilities(self): self.logMsg("postcapabilities called") # Set Capabilities mb3Port = self.addonSettings.getSetting('port') mb3Host = self.addonSettings.getSetting('ipaddress') clientInfo = ClientInformation() machineId = clientInfo.getMachineId() # get session id url = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Sessions?DeviceId=" + machineId + "&format=json" self.logMsg("Session URL : " + url); jsonData = self.downloadUrl(url) self.logMsg("Session JsonData : " + jsonData) result = json.loads(jsonData) self.logMsg("Session JsonData : " + str(result)) sessionId = result[0].get("Id") self.logMsg("Session Id : " + str(sessionId)) # post capability data playableMediaTypes = "Audio,Video,Photo" supportedCommands = "Play,Playstate,DisplayContent,GoHome,SendString,GoToSettings,DisplayMessage,PlayNext" url = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Sessions/Capabilities?Id=" + sessionId + "&PlayableMediaTypes=" + playableMediaTypes + "&SupportedCommands=" + supportedCommands + "&SupportsMediaControl=True" postData = {} #postData["Id"] = sessionId; #postData["PlayableMediaTypes"] = "Video"; #postData["SupportedCommands"] = "MoveUp"; stringdata = json.dumps(postData) self.logMsg("Capabilities URL : " + url); self.logMsg("Capabilities Data : " + stringdata) self.downloadUrl(url, postBody=stringdata, type="POST")
def postcapabilities(self): self.logMsg("postcapabilities called") # Set Capabilities mb3Port = self.addonSettings.getSetting('port') mb3Host = self.addonSettings.getSetting('ipaddress') clientInfo = ClientInformation() machineId = clientInfo.getMachineId() # get session id url = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Sessions?DeviceId=" + machineId + "&format=json" self.logMsg("Session URL : " + url) jsonData = self.downloadUrl(url) self.logMsg("Session JsonData : " + jsonData) result = json.loads(jsonData) self.logMsg("Session JsonData : " + str(result)) sessionId = result[0].get("Id") self.logMsg("Session Id : " + str(sessionId)) # post capability data playableMediaTypes = "Audio,Video,Photo" supportedCommands = "Play,Playstate,DisplayContent,GoHome,SendString,GoToSettings,DisplayMessage,PlayNext" url = "http://" + mb3Host + ":" + mb3Port + "/mediabrowser/Sessions/Capabilities?Id=" + sessionId + "&PlayableMediaTypes=" + playableMediaTypes + "&SupportedCommands=" + supportedCommands + "&SupportsMediaControl=True" postData = {} #postData["Id"] = sessionId; #postData["PlayableMediaTypes"] = "Video"; #postData["SupportedCommands"] = "MoveUp"; stringdata = json.dumps(postData) self.logMsg("Capabilities URL : " + url) self.logMsg("Capabilities Data : " + stringdata) self.downloadUrl(url, postBody=stringdata, type="POST")
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.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 USER_AGENT = 'QuickTime/7.7.4' # If the file it is not a media stub if (result.get("IsPlaceHolder") != True): if (result.get("VideoType") == "Dvd"): playurl = playurl + "/VIDEO_TS/VIDEO_TS.IFO" elif (result.get("VideoType") == "BluRay"): playurl = playurl + "/BDMV/index.bdmv" if addonSettings.getSetting('smbusername') == '': playurl = playurl.replace("\\\\", "smb://") else: playurl = playurl.replace("\\\\", "smb://" + addonSettings.getSetting('smbusername') + ':' + addonSettings.getSetting('smbpassword') + '@') playurl = playurl.replace("\\", "/") if ("apple.com" in playurl): playurl += '?|User-Agent=%s' % USER_AGENT if addonSettings.getSetting('playFromStream') == "true": playurl = 'http://' + server + '/mediabrowser/Videos/' + id + '/stream?static=true' mediaSources = result.get("MediaSources") if(mediaSources != None): if mediaSources[0].get('DefaultAudioStreamIndex') != None: playurl = playurl + "&AudioStreamIndex=" +str(mediaSources[0].get('DefaultAudioStreamIndex')) if mediaSources[0].get('DefaultSubtitleStreamIndex') != None: playurl = playurl + "&SubtitleStreamIndex=" + str(mediaSources[0].get('DefaultAudioStreamIndex')) else: #No path or has a path but not sufficient network so transcode xbmc.log("XBMB3C getPlayUrl -> Transcode") if result.get("Type") == "Audio": playurl = 'http://' + server + '/mediabrowser/Audio/' + id + '/stream.mp3' else: clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() playurl = 'http://' + server + '/mediabrowser/Videos/' + id + '/master.m3u8?mediaSourceId=' + id playurl = playurl + '&videoCodec=h264' playurl = playurl + '&AudioCodec=aac,ac3' playurl = playurl + '&deviceId=' + txt_mac playurl = playurl + '&VideoBitrate=' + str(int(self.getVideoBitRate()) * 1000) mediaSources = result.get("MediaSources") if(mediaSources != None): if mediaSources[0].get('DefaultAudioStreamIndex') != None: playurl = playurl + "&AudioStreamIndex=" +str(mediaSources[0].get('DefaultAudioStreamIndex')) if mediaSources[0].get('DefaultSubtitleStreamIndex') != None: playurl = playurl + "&SubtitleStreamIndex=" + str(mediaSources[0].get('DefaultSubtitleStreamIndex')) return playurl.encode('utf-8')
def stopAll(self): if(len(self.played_information) == 0): return addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') self.printDebug("XBMB3C Service -> played_information : " + str(self.played_information)) for item_url in self.played_information: data = self.played_information.get(item_url) if(data != None): self.printDebug("XBMB3C Service -> item_url : " + item_url) self.printDebug("XBMB3C Service -> item_data : " + str(data)) deleteurl = data.get("deleteurl") runtime = data.get("runtime") currentPossition = data.get("currentPossition") item_id = data.get("item_id") refresh_id = data.get("refresh_id") currentFile = data.get("currentfile") if(refresh_id != None): BackgroundDataUpdaterThread().updateItem(refresh_id) if(currentPossition != None and self.hasData(runtime)): runtimeTicks = int(runtime) self.printDebug("XBMB3C Service -> runtimeticks:" + str(runtimeTicks)) percentComplete = (currentPossition * 10000000) / runtimeTicks offerDeleteAt = float(addonSettings.getSetting("offerDeleteAt")) / 100 self.printDebug("XBMB3C Service -> Percent Complete:" + str(percentComplete) + " Mark Played At:" + str(offerDeleteAt)) self.stopPlayback(data) if (percentComplete > offerDeleteAt): gotDeleted = 0 if(deleteurl != None and deleteurl != ""): self.printDebug("XBMB3C Service -> Offering Delete:" + str(deleteurl)) gotDeleted = self.deleteItem(deleteurl) # update some of the display info if self.settings.getSetting('useNextUp') == "true": NextUpUpdaterThread().updateNextUp() if self.settings.getSetting('useBackgroundLoader') == "true": ArtworkRotationThread().updateActionUrls() self.played_information.clear() # stop transcoding - todo check we are actually transcoding? clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() url = ("http://%s:%s/mediabrowser/Videos/ActiveEncodings" % (addonSettings.getSetting('ipaddress'), addonSettings.getSetting('port'))) url = url + '?DeviceId=' + txt_mac self.downloadUtils.downloadUrl(url, type="DELETE")
def getAuthHeader(): addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') deviceName = addonSettings.getSetting('deviceName') deviceName = deviceName.replace("\"", "_") # might need to url encode this as it is getting added to the header and is user entered data clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() version = clientInfo.getVersion() userid = xbmcgui.Window( 10000 ).getProperty("userid") authString = "MediaBrowser UserId=\"" + userid + "\",Client=\"XBMC\",Device=\"" + deviceName + "\",DeviceId=\"" + txt_mac + "\",Version=\"" + version + "\"" headers = {'Accept-encoding': 'gzip', 'Authorization' : authString} xbmc.log("XBMB3C Authentication Header : " + str(headers)) return headers
def authenticate(self): WINDOW = xbmcgui.Window( 10000 ) token = WINDOW.getProperty("AccessToken"+self.addonSettings.getSetting('username')) if(token != None and token != ""): self.logMsg("DownloadUtils -> Returning saved AccessToken for user : "******" token: "+ token) return token port = self.addonSettings.getSetting("port") host = self.addonSettings.getSetting("ipaddress") if(host == None or host == "" or port == None or port == ""): return "" url = "http://" + self.addonSettings.getSetting("ipaddress") + ":" + self.addonSettings.getSetting("port") + "/mediabrowser/Users/AuthenticateByName?format=json" clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() version = clientInfo.getVersion() deviceName = self.addonSettings.getSetting('deviceName') deviceName = deviceName.replace("\"", "_") authString = "Mediabrowser Client=\"XBMC\",Device=\"" + deviceName + "\",DeviceId=\"" + txt_mac + "\",Version=\"" + version + "\"" headers = {'Accept-encoding': 'gzip', 'Authorization' : authString} if self.addonSettings.getSetting('password') !=None and self.addonSettings.getSetting('password') !='': sha1 = hashlib.sha1(self.addonSettings.getSetting('password')) sha1 = sha1.hexdigest() else: sha1 = 'da39a3ee5e6b4b0d3255bfef95601890afd80709' messageData = "username="******"&password="******"POST", authenticate=False) accessToken = None try: result = json.loads(resp) accessToken = result.get("AccessToken") except: pass if(accessToken != None): self.logMsg("User Authenticated : " + accessToken) WINDOW.setProperty("AccessToken"+self.addonSettings.getSetting('username'), accessToken) WINDOW.setProperty("userid", result.get("User").get("Id")) return accessToken else: self.logMsg("User NOT Authenticated") WINDOW.setProperty("AccessToken"+self.addonSettings.getSetting('username'), "") return ""
def stopAll(self): self.ws.processPendingActions() if(len(self.played_information) == 0): return addonSettings = xbmcaddon.Addon(id='plugin.video.emby') self.logMsg("emby Service -> played_information : " + str(self.played_information)) for item_url in self.played_information: data = self.played_information.get(item_url) if (data is not None): self.logMsg("emby Service -> item_url : " + item_url) self.logMsg("emby Service -> item_data : " + str(data)) runtime = data.get("runtime") currentPosition = data.get("currentPosition") item_id = data.get("item_id") refresh_id = data.get("refresh_id") currentFile = data.get("currentfile") type = data.get("Type") if(currentPosition != None and self.hasData(runtime)): runtimeTicks = int(runtime) self.logMsg("emby Service -> runtimeticks:" + str(runtimeTicks)) percentComplete = (currentPosition * 10000000) / runtimeTicks markPlayedAt = float(90) / 100 self.logMsg("emby Service -> Percent Complete:" + str(percentComplete) + " Mark Played At:" + str(markPlayedAt)) self.stopPlayback(data) if(refresh_id != None): #report updates playcount and resume status to Kodi and MB3 librarySync.updatePlayCount(item_id) self.played_information.clear() # stop transcoding - todo check we are actually transcoding? clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() url = "{server}/mediabrowser/Videos/ActiveEncodings" url = url + '?DeviceId=' + txt_mac self.doUtils.downloadUrl(url, type="DELETE")
def on_open(self, ws): try: 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"] = "XBMC|" + machineId + "|" + version + "|" + deviceName messageString = json.dumps(messageData) self.logMsg("Opened : " + str(messageString)) ws.send(messageString) except Exception, e: self.logMsg("Exception : " + str(e), level=0)
def on_open(self, ws): try: 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) except Exception, e: self.logMsg("Exception : " + str(e), level=0)
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 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 getAuthHeader(self, authenticate=True): clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() version = clientInfo.getVersion() deviceName = self.addonSettings.getSetting('deviceName') deviceName = deviceName.replace("\"", "_") if(authenticate == False): authString = "MediaBrowser Client=\"Kodi\",Device=\"" + deviceName + "\",DeviceId=\"" + txt_mac + "\",Version=\"" + version + "\"" headers = {"Accept-encoding": "gzip", "Accept-Charset" : "UTF-8,*", "Authorization" : authString} return headers else: userid = self.getUserId() authString = "MediaBrowser UserId=\"" + userid + "\",Client=\"Kodi\",Device=\"" + deviceName + "\",DeviceId=\"" + txt_mac + "\",Version=\"" + version + "\"" headers = {"Accept-encoding": "gzip", "Accept-Charset" : "UTF-8,*", "Authorization" : authString} authToken = self.authenticate() if(authToken != ""): headers["X-MediaBrowser-Token"] = authToken self.logMsg("Authentication Header : " + str(headers)) return headers
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) return else: return elif option == 0: # User selected Add user for adduser in additionalUsername: xbmc.log(str(adduser)) users.remove(adduser) 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)
def authenticate(self, retreive=True): WINDOW = xbmcgui.Window(10000) self.addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') username = self.addonSettings.getSetting('username') token = WINDOW.getProperty("AccessToken" + username) if(token != None and token != ""): self.logMsg("DownloadUtils -> Returning saved (WINDOW) AccessToken for user:"******" token:" + token) return token token = self.addonSettings.getSetting("AccessToken" + username) if(token != None and token != ""): WINDOW.setProperty("AccessToken" + username, token) self.logMsg("DownloadUtils -> Returning saved (SETTINGS) AccessToken for user:"******" token:" + token) return token port = self.addonSettings.getSetting("port") host = self.addonSettings.getSetting("ipaddress") if(host == None or host == "" or host == "<none>" or port == None or port == ""): return "" if(retreive == False): return "" url = "http://" + host + ":" + port + "/mediabrowser/Users/AuthenticateByName?format=json" clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() version = clientInfo.getVersion() # get user info jsonData = self.downloadUrl("http://" + host + ":" + port + "/mediabrowser/Users/Public?format=json", authenticate=False) users = [] if(jsonData != ""): users = json.loads(jsonData) userHasPassword = False for user in users: name = user.get("Name") if(username == name): if(user.get("HasPassword") == True): userHasPassword = True break password = "" if(userHasPassword): password = xbmcgui.Dialog().input("Enter Password for user : "******""): sha1 = hashlib.sha1(password) sha1 = sha1.hexdigest() else: sha1 = 'da39a3ee5e6b4b0d3255bfef95601890afd80709' messageData = "username="******"&password="******"POST", authenticate=False) result = None accessToken = None try: xbmc.log("Auth_Reponce: " + str(resp)) result = json.loads(resp) accessToken = result.get("AccessToken") except: pass if(result != None and accessToken != None): userID = result.get("User").get("Id") self.logMsg("User Authenticated : " + accessToken) WINDOW.setProperty("AccessToken" + username, accessToken) WINDOW.setProperty("userid" + username, userID) self.addonSettings.setSetting("AccessToken" + username, accessToken) self.addonSettings.setSetting("userid" + username, userID) return accessToken else: self.logMsg("User NOT Authenticated") WINDOW.setProperty("AccessToken" + username, "") WINDOW.setProperty("userid" + username, "") self.addonSettings.setSetting("AccessToken" + username, "") self.addonSettings.setSetting("userid" + username, "") return ""
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.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 USER_AGENT = 'QuickTime/7.7.4' # If the file it is not a media stub if (result.get("IsPlaceHolder") != True): if (result.get("VideoType") == "Dvd"): playurl = playurl + "/VIDEO_TS/VIDEO_TS.IFO" elif (result.get("VideoType") == "BluRay"): playurl = playurl + "/BDMV/index.bdmv" if addonSettings.getSetting('smbusername') == '': playurl = playurl.replace("\\\\", "smb://") else: playurl = playurl.replace( "\\\\", "smb://" + addonSettings.getSetting('smbusername') + ':' + addonSettings.getSetting('smbpassword') + '@') playurl = playurl.replace("\\", "/") if ("apple.com" in playurl): playurl += '?|User-Agent=%s' % USER_AGENT if addonSettings.getSetting('playFromStream') == "true": playurl = 'http://' + server + '/mediabrowser/Videos/' + id + '/stream?static=true' mediaSources = result.get("MediaSources") if (mediaSources != None): if mediaSources[0].get( 'DefaultAudioStreamIndex') != None: playurl = playurl + "&AudioStreamIndex=" + str( mediaSources[0].get('DefaultAudioStreamIndex')) if mediaSources[0].get( 'DefaultSubtitleStreamIndex') != None: playurl = playurl + "&SubtitleStreamIndex=" + str( mediaSources[0].get('DefaultAudioStreamIndex')) else: #No path or has a path but not sufficient network so transcode xbmc.log("XBMB3C getPlayUrl -> Transcode") if result.get("Type") == "Audio": playurl = 'http://' + server + '/mediabrowser/Audio/' + id + '/stream.mp3' else: clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() playurl = 'http://' + server + '/mediabrowser/Videos/' + id + '/master.m3u8?mediaSourceId=' + id playurl = playurl + '&videoCodec=h264' playurl = playurl + '&AudioCodec=aac,ac3' playurl = playurl + '&deviceId=' + txt_mac playurl = playurl + '&VideoBitrate=' + str( int(self.getVideoBitRate()) * 1000) mediaSources = result.get("MediaSources") if (mediaSources != None): if mediaSources[0].get('DefaultAudioStreamIndex') != None: playurl = playurl + "&AudioStreamIndex=" + str( mediaSources[0].get('DefaultAudioStreamIndex')) if mediaSources[0].get( 'DefaultSubtitleStreamIndex') != None: playurl = playurl + "&SubtitleStreamIndex=" + str( mediaSources[0].get('DefaultSubtitleStreamIndex')) return playurl.encode('utf-8')
def stopAll(played_information): if (len(played_information) == 0): return addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') printDebug("XBMB3C Service -> played_information : " + str(played_information)) for item_url in played_information: data = played_information.get(item_url) if (data != None): printDebug("XBMB3C Service -> item_url : " + item_url) printDebug("XBMB3C Service -> item_data : " + str(data)) watchedurl = data.get("watchedurl") positionurl = data.get("positionurl") deleteurl = data.get("deleteurl") runtime = data.get("runtime") currentPossition = data.get("currentPossition") item_id = data.get("item_id") refresh_id = data.get("refresh_id") currentFile = data.get("currentfile") BackgroundDataUpdaterThread().updateItem(refresh_id) if (currentPossition != None and hasData(runtime) and hasData(positionurl) and hasData(watchedurl)): runtimeTicks = int(runtime) printDebug("XBMB3C Service -> runtimeticks:" + str(runtimeTicks)) percentComplete = (currentPossition * 10000000) / runtimeTicks markPlayedAt = float( addonSettings.getSetting("markPlayedAt")) / 100 printDebug("XBMB3C Service -> Percent Complete:" + str(percentComplete) + " Mark Played At:" + str(markPlayedAt)) stopPlayback(currentFile, str(int(currentPossition * 10000000))) if (percentComplete > markPlayedAt): gotDeleted = 0 if (deleteurl != None and deleteurl != ""): printDebug("XBMB3C Service -> Offering Delete:" + str(deleteurl)) gotDeleted = deleteItem(deleteurl) if (newNextUpThread != None): newNextUpThread.updateNextUp() if (artworkRotationThread != None): artworkRotationThread.updateActionUrls() played_information.clear() # stop transcoding - todo check we are actually transcoding? clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() url = ("http://%s:%s/mediabrowser/Videos/ActiveEncodings" % (addonSettings.getSetting('ipaddress'), addonSettings.getSetting('port'))) url = url + '?DeviceId=' + txt_mac stopTranscoding(url)
def authenticate(self): WINDOW = xbmcgui.Window(10000) self.addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') token = WINDOW.getProperty("AccessToken" + self.addonSettings.getSetting('username')) if (token != None and token != ""): self.logMsg( "DownloadUtils -> Returning saved AccessToken for user : "******" token: " + token) return token port = self.addonSettings.getSetting("port") host = self.addonSettings.getSetting("ipaddress") if (host == None or host == "" or port == None or port == ""): return "" url = "http://" + self.addonSettings.getSetting( "ipaddress") + ":" + self.addonSettings.getSetting( "port") + "/mediabrowser/Users/AuthenticateByName?format=json" clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() version = clientInfo.getVersion() deviceName = self.addonSettings.getSetting('deviceName') deviceName = deviceName.replace("\"", "_") authString = "Mediabrowser Client=\"Kodi\",Device=\"" + deviceName + "\",DeviceId=\"" + txt_mac + "\",Version=\"" + version + "\"" headers = {'Accept-encoding': 'gzip', 'Authorization': authString} if self.addonSettings.getSetting( 'password') != None and self.addonSettings.getSetting( 'password') != '': sha1 = hashlib.sha1(self.addonSettings.getSetting('password')) sha1 = sha1.hexdigest() else: sha1 = 'da39a3ee5e6b4b0d3255bfef95601890afd80709' messageData = "username="******"&password="******"POST", authenticate=False, suppress=True) accessToken = None try: result = json.loads(resp) accessToken = result.get("AccessToken") except: pass if (accessToken != None): self.logMsg("User Authenticated : " + accessToken) WINDOW.setProperty( "AccessToken" + self.addonSettings.getSetting('username'), accessToken) WINDOW.setProperty( "userid" + self.addonSettings.getSetting('username'), result.get("User").get("Id")) return accessToken else: self.logMsg("User NOT Authenticated") WINDOW.setProperty( "AccessToken" + self.addonSettings.getSetting('username'), "") return ""
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) 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)
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 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 authenticate(self, retreive=True): WINDOW = xbmcgui.Window(10000) self.addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') username = self.addonSettings.getSetting('username') token = WINDOW.getProperty("AccessToken" + username) if (token != None and token != ""): self.logMsg( "DownloadUtils -> Returning saved (WINDOW) AccessToken for user:"******" token:" + token) return token token = self.addonSettings.getSetting("AccessToken" + username) if (token != None and token != ""): WINDOW.setProperty("AccessToken" + username, token) self.logMsg( "DownloadUtils -> Returning saved (SETTINGS) AccessToken for user:"******" token:" + token) return token port = self.addonSettings.getSetting("port") host = self.addonSettings.getSetting("ipaddress") if (host == None or host == "" or host == "<none>" or port == None or port == ""): return "" if (retreive == False): return "" url = "http://" + host + ":" + port + "/mediabrowser/Users/AuthenticateByName?format=json" clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() version = clientInfo.getVersion() # get user info jsonData = self.downloadUrl("http://" + host + ":" + port + "/mediabrowser/Users/Public?format=json", authenticate=False) users = [] if (jsonData != ""): users = json.loads(jsonData) userHasPassword = False for user in users: name = user.get("Name") if (username == name): if (user.get("HasPassword") == True): userHasPassword = True break password = "" if (userHasPassword): password = xbmcgui.Dialog().input("Enter Password for user : "******""): sha1 = hashlib.sha1(password) sha1 = sha1.hexdigest() else: sha1 = 'da39a3ee5e6b4b0d3255bfef95601890afd80709' messageData = "username="******"&password="******"POST", authenticate=False) result = None accessToken = None try: xbmc.log("Auth_Reponce: " + str(resp)) result = json.loads(resp) accessToken = result.get("AccessToken") except: pass if (result != None and accessToken != None): userID = result.get("User").get("Id") self.logMsg("User Authenticated : " + accessToken) WINDOW.setProperty("AccessToken" + username, accessToken) WINDOW.setProperty("userid" + username, userID) self.addonSettings.setSetting("AccessToken" + username, accessToken) self.addonSettings.setSetting("userid" + username, userID) return accessToken else: self.logMsg("User NOT Authenticated") WINDOW.setProperty("AccessToken" + username, "") WINDOW.setProperty("userid" + username, "") self.addonSettings.setSetting("AccessToken" + username, "") self.addonSettings.setSetting("userid" + username, "") return ""
def stopAll(self): if(len(self.played_information) == 0): return addonSettings = xbmcaddon.Addon(id='plugin.video.emby') self.printDebug("emby Service -> played_information : " + str(self.played_information)) for item_url in self.played_information: data = self.played_information.get(item_url) if(data != None): self.printDebug("emby Service -> item_url : " + item_url) self.printDebug("emby Service -> item_data : " + str(data)) runtime = data.get("runtime") currentPosition = data.get("currentPosition") item_id = data.get("item_id") refresh_id = data.get("refresh_id") currentFile = data.get("currentfile") type = data.get("Type") if(currentPosition != None and self.hasData(runtime)): runtimeTicks = int(runtime) self.printDebug("emby Service -> runtimeticks:" + str(runtimeTicks)) percentComplete = (currentPosition * 10000000) / runtimeTicks markPlayedAt = float(90) / 100 self.printDebug("emby Service -> Percent Complete:" + str(percentComplete) + " Mark Played At:" + str(markPlayedAt)) self.stopPlayback(data) if(refresh_id != None): #report updates playcount and resume status to Kodi and MB3 librarySync.updatePlayCount(item_id,type) # if its an episode see if autoplay is enabled if addonSettings.getSetting("autoPlaySeason")=="true" and type=="Episode": port = addonSettings.getSetting('port') host = addonSettings.getSetting('ipaddress') server = host + ":" + port userid = self.downloadUtils.getUserId() # add remaining unplayed episodes if applicable MB3Episode = ReadEmbyDB().getItem(item_id) userData = MB3Episode["UserData"] if userData!=None and userData["Played"]==True: pDialog = xbmcgui.DialogProgress() pDialog.create("Auto Play","Further Episode(s) in "+MB3Episode["SeasonName"]+" for "+MB3Episode["SeriesName"]+ " found","Cancel to stop automatic play of remaining episodes") count = 0 while(pDialog.iscanceled==False or count < 10): xbmc.sleep(1000) count += 1 progress = count * 10 remainingsecs = 10 - count pDialog.update(progress,"Further Episode(s) in "+MB3Episode["SeasonName"]+" for "+MB3Episode["SeriesName"]+ " found","Cancel to stop automatic play of remaining episodes", str(remainingsecs) + " second(s) until auto dismiss") if pDialog.iscanceled()==False: seasonId = MB3Episode["SeasonId"] jsonData = self.downloadUtils.downloadUrl("http://" + server + "/mediabrowser/Users/" + userid + "/Items?ParentId=" + seasonId + "&ImageTypeLimit=1&SortBy=SortName&SortOrder=Ascending&Filters=IsUnPlayed&IncludeItemTypes=Episode&IsVirtualUnaired=false&Recursive=true&IsMissing=False&format=json", suppress=False, popup=1 ) if(jsonData != ""): seasonData = json.loads(jsonData) if seasonData.get("Items") != None: PlaybackUtils().PLAYAllEpisodes(seasonData.get("Items")) self.played_information.clear() # stop transcoding - todo check we are actually transcoding? clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() url = ("http://%s:%s/mediabrowser/Videos/ActiveEncodings" % (addonSettings.getSetting('ipaddress'), addonSettings.getSetting('port'))) url = url + '?DeviceId=' + txt_mac self.downloadUtils.downloadUrl(url, type="DELETE")
def stopAll(self): if (len(self.played_information) == 0): return addonSettings = xbmcaddon.Addon(id='plugin.video.xbmb3c') self.printDebug("XBMB3C Service -> played_information : " + str(self.played_information)) for item_url in self.played_information: data = self.played_information.get(item_url) if (data != None): self.printDebug("XBMB3C Service -> item_url : " + item_url) self.printDebug("XBMB3C Service -> item_data : " + str(data)) deleteurl = data.get("deleteurl") runtime = data.get("runtime") currentPossition = data.get("currentPossition") item_id = data.get("item_id") refresh_id = data.get("refresh_id") currentFile = data.get("currentfile") if (refresh_id != None): BackgroundDataUpdaterThread().updateItem(refresh_id) if (currentPossition != None and self.hasData(runtime)): runtimeTicks = int(runtime) self.printDebug("XBMB3C Service -> runtimeticks:" + str(runtimeTicks)) percentComplete = (currentPossition * 10000000) / runtimeTicks offerDeleteAt = float( addonSettings.getSetting("offerDeleteAt")) / 100 self.printDebug("XBMB3C Service -> Percent Complete:" + str(percentComplete) + " Mark Played At:" + str(offerDeleteAt)) self.stopPlayback(data) if (percentComplete > offerDeleteAt): gotDeleted = 0 if (deleteurl != None and deleteurl != ""): self.printDebug( "XBMB3C Service -> Offering Delete:" + str(deleteurl)) gotDeleted = self.deleteItem(deleteurl) # update some of the display info if self.settings.getSetting('useNextUp') == "true": NextUpUpdaterThread().updateNextUp() if self.settings.getSetting('useBackgroundLoader') == "true": ArtworkRotationThread().updateActionUrls() self.played_information.clear() # stop transcoding - todo check we are actually transcoding? clientInfo = ClientInformation() txt_mac = clientInfo.getMachineId() url = ("http://%s:%s/mediabrowser/Videos/ActiveEncodings" % (addonSettings.getSetting('ipaddress'), addonSettings.getSetting('port'))) url = url + '?DeviceId=' + txt_mac self.downloadUtils.downloadUrl(url, type="DELETE")