def CleanUp(self): try: if self.WS.isSocketConnected() == True: self.WS.terminate() del self.WS except Exception as e: log(__language__(30000) + repr(e), xbmc.LOGERROR) kodiutils.dialogokerror(__language__(30000) + repr(e)) finally: log("Cleanup finished")
def terminate(self): try: if self.WS != None: self.WS.isConnected = False self.WS.close(1000, "MOTR Kodi going away") except Exception as e: xbmc.log(__lang__(30201) + repr(e), xbmc.LOGERROR) kodiutils.dialogokerror(__lang__(30201) + repr(e)) finally: self.MainGUI.onWebsocketDisconnected()
def CheckIfValidProfile(self, nReturn): if len(self.sProfile) == 0 and nReturn != 0: kodiutils.dialogokerror(__lang__(30300), __lang__(30301)) return self.nReturnStatus = nReturn self.close()
def HandleJSONData(self, m): if m.is_text: textreceived = m.data.decode("utf-8") else: return #Nothing received, nothing todo if len(textreceived) == 0: return #Here catch all exceptions try: JSONData = json.loads(textreceived) except Exception as e: log( __language__(30021) + repr(e) + "-->" + textreceived, xbmc.LOGERROR) kodiutils.dialogokerror( __language__(30021) + repr(e) + ": " + textreceived) return Command = JSONData['command'] if Command == 'ERRORNOTLOGGEDIN': sUser = kodiutils.get_setting('username') sPassword = kodiutils.get_setting('password') self.WS.SendMOTRCommand("APPLOGIN", sUser + ";" + sPassword) if Command == 'APPLOGIN': kodiutils.set_setting('SessionID', JSONData['aArray'][0]) kodiutils.set_setting('AuthID', JSONData['aArray'][2]) self.WS.SendMOTRCommand("GETAVAILABLEDIRS", "") #Same as "Sessionrestore" handling if Command == 'SESSIONRESTORE': self.WS.SendMOTRCommand("GETAVAILABLEDIRS", "") if Command == 'AVAILABLEDIRS': for x in range(0, int(JSONData['count'])): self.AddToDirectory(JSONData['aArray'][x]['sDisplayName'], JSONData['aArray'][x]['nID']) self.WS.SendMOTRCommand("GETFILESORTING", "") if Command == 'FILESORTING': print("Filesorting is: " + JSONData['aArray'][0]) sTmpSorting = JSONData['aArray'][0] sTmpSetting = kodiutils.get_setting('sorting') if sTmpSetting == "": sTmpSetting = sTmpSorting if sTmpSetting == "0": sTmpSetting = "NAME" if sTmpSetting == "1": sTmpSetting = "MODIFY" if sTmpSetting == "2": sTmpSetting = "SIZE" if sTmpSetting == sTmpSorting: self.SetSorting(sTmpSorting) else: self.SetSorting(sTmpSetting, True) #Local override, always self.WS.SendMOTRCommand("GETCLEANFILENAMES", "") if Command == 'GETCLEANFILENAMES': print("Clean filenames is: " + JSONData['aArray'][0]) sTmpCleanFile = JSONData['aArray'][0] sTmpCleanSetting = kodiutils.get_setting('cleanfilename') if sTmpCleanFile == sTmpCleanSetting: self.SetCleanFilename(sTmpCleanFile) else: self.SetCleanFilename(sTmpCleanSetting, True) self.WS.SendMOTRCommand("QUEUEREFRESH", "") if Command == 'QUEUEREFRESH': self.getControl(600).reset() self.getControl(600).selectItem(-1) sLastStatus = "" for x in range(0, int(JSONData['count'])): sStatus = JSONData['aArray'][x]['sDisplayStatus'] if sStatus != sLastStatus: sLastStatus = sStatus self.AddQueueSeparator(sStatus) QueueID = JSONData['aArray'][x]['nQueueID'] sFilename = JSONData['aArray'][x]['sDisplayName'] sProfile = JSONData['aArray'][x]['sHandbrakeProfile'] sDrive = JSONData['aArray'][x]['sDisplayDirectory'] nPercent = JSONData['aArray'][x]['iProcentage'] sETA = JSONData['aArray'][x]['sETA'] nStatus = JSONData['aArray'][x]['nStatus'] #Set the finished as actually finished if nStatus == "FINISHED": nPercent = 100 if nStatus == "FINISHEDANDFAIL": nPercent = 100 self.AddToQueue(QueueID, sFilename, sProfile, sDrive, nPercent, sETA, nStatus) self.WS.SendMOTRCommand("RESTOREFILELIST", "") if Command == 'UPDATEQUEUEPROCENTAGE': nQueueID = JSONData['aArray'][0] nPercent = JSONData['aArray'][1] sETA = JSONData['aArray'][2] for x in range(0, self.getControl(600).size()): oListItem = self.getControl(600).getListItem(x) if oListItem.getProperty('queueid') == str(nQueueID): oListItem.setProperty('progress', str(nPercent)) oListItem.setProperty('eta', sETA) break if Command == 'RESTOREFILELIST': #Selects the correct directory after connection oDirs = self.getControl(100) for x in range(0, oDirs.size()): if oDirs.getListItem(x).getLabel() == JSONData['aArray'][0]: oDirs.selectItem(x) break if Command == 'FILELIST': self.getControl(500).reset() for x in range(0, int(JSONData['count'])): self.AddToFileList(JSONData['aArray'][x]['sDisplayName'], JSONData['aArray'][x]['nID'], JSONData['aArray'][x]['bIsFolder'], JSONData['aArray'][x]['sFileSize']) self.WS.SendMOTRCommand("LASTFOLDER", "") if Command == 'LASTFOLDER': oFiles = self.getControl(500) for x in range(0, oFiles.size()): if oFiles.getListItem(x).getLabel() == JSONData['aArray'][0]: oFiles.selectItem(x) break if Command == 'ERROR': kodiutils.dialogokerror(JSONData['aArray'][0]) self.onClick(9102) #disconnect after showing error kodiutils.show_settings() if Command == 'DOWNLOAD': #sHost = kodiutils.get_setting('host') #sPort = kodiutils.get_setting('port') #bUseSSL = kodiutils.get_setting_as_bool('usessl') #sWebConnect = 'http://' #if bUseSSL == True: # sWebConnect = 'https://' #sWebConnectClean = sWebConnect + sHost + ":" + sPort + "/MOTR-download/" sWebConnect = self.DownloadLink( 'MOTR-download') + JSONData['aArray'][0] log("Download/stream link: " + sWebConnect) if self.Download == False: listitem = xbmcgui.ListItem( self.Streamname ) #To add the filename / streamname we are showing #xbmc.Player().play(sWebConnect, listitem) self.MyPlayer.onInit() #Zero before start #print("MOTRPlayer resume position: " + str(self.StreamResumePosition)) self.MyPlayer.play( sWebConnect + "|verifypeer=false", listitem, False, self.StreamResumePosition ) #Resume position is not 0 when seek to is selected if self.StreamResumePosition == 0: #No resume, no need to trigger seek self.MyPlayer.SeekDone() #print("MOTRPlayer In waiting loop") self.TmpPosition = 0 nTimeCounter = 0 nTimeCheckSpan = 3 while self.MyPlayer.is_active: if self.MyPlayer.isPlaying() == True: #Get position in movie nPositionNow = self.MyPlayer.getTime() #Handle resume if self.MyPlayer.seek_done == False: self.MyPlayer.seekTime(self.StreamResumePosition) nTimeCheck = self.MyPlayer.getTime() if nTimeCheck <= self.StreamResumePosition + nTimeCheckSpan and nTimeCheck >= self.StreamResumePosition - nTimeCheckSpan: kodiutils.notification(__language__(30025), __language__(30026)) self.MyPlayer.SeekDone() #Seek detection, show message when seeking manually, not resume if nPositionNow >= self.TmpPosition + nTimeCheckSpan or nPositionNow <= self.TmpPosition - nTimeCheckSpan: kodiutils.notification(__language__(30027), __language__(30028)) nTimeCounter = 0 #Get status from player bCaching = xbmc.getCondVisibility("Player.Caching") bPlaying = xbmc.getCondVisibility("Player.Playing") #Reset the timer if we are not caching, if bPlaying == True and bCaching == False and nTimeCounter > 0: nTimeCounter = 0 #If cache, then start counting if bCaching == True: nTimeCounter = nTimeCounter + 1 #Showing messages when you are waiting for cache to be handleded if nTimeCounter == 10: kodiutils.notification(__language__(30029), __language__(30030)) if nTimeCounter == 20: kodiutils.notification(__language__(30029), __language__(30031)) if nTimeCounter == 30: kodiutils.notification(__language__(30029), __language__(30032)) if nTimeCounter == 40: kodiutils.notification(__language__(30029), __language__(30033)) if nTimeCounter == 50: kodiutils.notification(__language__(30029), __language__(30034)) if nTimeCounter == 60: kodiutils.notification(__language__(30029), __language__(30035)) #Store the position for saving self.TmpPosition = self.MyPlayer.getTime() self.MyPlayer.sleep(1000) #print("MOTRPlayer Out of waiting loop, time exited: " + str(self.TmpPosition) + " - Resumepos: " + str(self.StreamResumePosition)) #Set position only during the 30 first secs and no position was set. After that ignore if you past 30 secs and sets it below that (eg start from beginning with an error) if (self.TmpPosition > 30 and self.StreamResumePosition > 0 ) or (self.TmpPosition <= 30 and self.StreamResumePosition <= 30) or self.StreamResumePosition == 0: self.WS.SendMOTRCommand( "SETSTOREDPARAMETER", self.StreamID + ";PLAYPOSITION;" + str(self.TmpPosition)) #Store the position else: sPath = kodiutils.get_setting('saveto') self.DownloadURL(sWebConnect + "|verifypeer=false", sPath + self.DownloadFilename) if Command == 'SETQUEUESELECTED': iOutput = JSONData['count'] - 1 sOutput = "" for x in range(len(JSONData['aArray'][iOutput]) - 1, 0, -1): sOutput += JSONData['aArray'][iOutput][x] + "\n" kodiutils.dialogtext(__language__(30018), sOutput) if Command == 'GETSTOREDPARAMETER': print("GETSTOREDPARAMETER - Command " + JSONData['aArray'][0] + " with value: " + JSONData['aArray'][1]) sCommand = JSONData['aArray'][0] sValue = JSONData['aArray'][1] if sCommand == "PLAYPOSITION": if len(sValue) == 0: self.WS.SendMOTRCommand("DOWNLOAD", self.StreamID) else: nTime = int(round(float(sValue))) sTime = " (" + str(datetime.timedelta(seconds=nTime)) + ")" DialogReturn = xbmcgui.Dialog().select( __language__(30022), [__language__(30023) + sTime, __language__(30024)]) if DialogReturn == -1: #Cancel... return if DialogReturn == 0: #We resuming position self.StreamResumePosition = nTime #Sets the new position we are going to seek self.WS.SendMOTRCommand("DOWNLOAD", self.StreamID) if Command == 'MOVIEINFOQUERY': #log("MOVIEINFOQUERY aArray: " + JSONData['aArray'] ) #movieList = json.loads(JSONData['aArray']) if JSONData['count'] == 0: kodiutils.notification("Movie information", "No information found on that query") return nSel = 0 #Default select first item if JSONData[ 'count'] > 1: #If there are more than one item show a selector nSel = xbmcgui.Dialog().select("Movie information", JSONData['aArray']) if nSel == -1: return self.WS.SendMOTRCommand("MOVIEINFOSELECT", self.MovieQueryID + ";" + str(nSel)) if Command == 'MOVIEINFO': if JSONData['count'] > 0: #sHTTPSource = "https://image.tmdb.org/t/p/original/" #alternative directly on tmdb.org sHTTPSource = self.DownloadLink("MovieInfo") sMovieReceived = JSONData['aArray'][0] MovieJSON = json.loads(sMovieReceived) liz = xbmcgui.ListItem(MovieJSON['Title']) liz.setProperty("IsPlayable", "false") liz.setArt({ 'poster': sHTTPSource + MovieJSON['PosterPath'], 'banner': 'logo.png' }) liz.setInfo(type='Video', infoLabels={ 'plot': MovieJSON['Overview'], 'year': MovieJSON['ReleaseDate'], 'genre': MovieJSON['Genres'] }) liz.setRating("tmdb", MovieJSON['VoteAverage'], MovieJSON['VoteCount'], True) liz.setPath('/') self.getControl(11).setImage(sHTTPSource + MovieJSON['BackdropPath']) self.getControl(11).setVisible(True) xbmcgui.Dialog().info(liz) self.getControl(11).setVisible(False)
def onWebsocketError(self, sLine1, sLine2): #Typical during connection kodiutils.dialogokerror(sLine1, sLine2, '') self.getControl(9100).setEnabled( True) #Enable the connect button when we try to connect
def onClickFilelist(self): testitem = self.getControl(500).getSelectedItem() nID = testitem.getProperty('nID') bFolder = testitem.getProperty('bFolder') if bFolder.upper() == 'TRUE': self.WS.SendMOTRCommand("SETFOLDER", nID) else: sMovie = testitem.getProperty('bIsMovie') if sMovie == "True": ret = kodiutils.dialogstreamordownload(testitem.getLabel()) if ret == 0: #stream log("Streaming movie " + testitem.getLabel()) self.Download = False self.StreamResumePosition = 0 #We don't know if the user has a resume yet self.Streamname = testitem.getLabel() self.StreamID = nID #Store the stream ID for after resume-dialog #self.WS.SendMOTRCommand("DOWNLOAD", self.StreamID) self.WS.SendMOTRCommand( "GETSTOREDPARAMETER", nID + ";PLAYPOSITION") #Ask for resumedata elif ret == 1: #View movie information self.MovieQueryID = nID #Store when replied self.WS.SendMOTRCommand("MOVIEINFOQUERY", nID + ";" + testitem.getLabel()) elif ret == 2: #Convert dialog myconvertdlg = DialogConvertSelect( "convertdialog.xml", __cwd__, "Default", filename=testitem.getLabel()) myconvertdlg.doModal( ) #Gives the selected item as parameter sProfile = myconvertdlg.GetProfile() sFileName = myconvertdlg.GetFilename() nReturn = myconvertdlg.GetReturnStatus() #del myconvertdlg #Cancel = nReturn == 0 if nReturn == 0: return #Check if we are converting if len(sProfile) == 0: kodiutils.dialogokerror(__language__(30004)) return #Now send the convert message to MOTR based on the filename / profile sTop = "False" if nReturn == 1: sTop = "True" self.WS.SendMOTRCommand( "QUEUEADD", nID + ";" + sFileName + ";" + sProfile + ";" + sTop) kodiutils.notification( __language__(30005), sFileName + " " + __language__(30006)) log("Converting movie " + testitem.getLabel() + " with profile: " + sProfile) elif ret == 3: #Download self.onDownloadFile(nID, testitem.getLabel()) else: sArchive = testitem.getProperty('bIsArchive') if sArchive == "True": ret = kodiutils.dialogunpackordownload(testitem.getLabel()) if ret == 0: #Extract self.WS.SendMOTRCommand( "QUEUEADD", nID + ';;Extracting file(s);false') log("Extracting file " + testitem.getLabel()) if ret == 1: #Download self.onDownloadFile(nID, testitem.getLabel()) else: ret = kodiutils.dialogyesno(__language__(30007), testitem.getLabel()) if ret == True: self.onDownloadFile(nID, testitem.getLabel())