def _hasRecordingProcess(self): pidInfo = OSTools.getProcessPID(self._recordCmd.Command) if pidInfo is None: xtime.sleep(2) # in case of adjacent films pidInfo = OSTools.getProcessPID(self._recordCmd.Command) return pidInfo is not None
def _argusWait(self,secondsToWait): startTime = datetime.now() #self._log("Observing recorder queue for %s. Use 'sleepModeOn' for VCR mode"%OSTools.convertSecondsToString(secondsToWait)) self._log("Observing recorder queue until %s. Execute 'sleepModeOn' for VCR mode"%OSTools.showDateTimeWithOffset(secondsToWait)) lastQCheck=None while (OSTools.getDifferenceInSeconds(datetime.now(),startTime) < secondsToWait): xtime.sleep(self.PRERUN_SECONDS) path=self._config().getRecQueuePath() try: currentModificationTime=OSTools.getLastModificationTime(path) except OSError as osError: currentModificationTime=0.0 self._config().logError("Error checking rec file:"+osError.strerror) print("Error checking rec file") #check for socket or file changes... if lastQCheck is None: lastQCheck=currentModificationTime #we came from a queue check-so thats the last time we checked if currentModificationTime-lastQCheck>0: self._log("Rec Q modified-looking for jobs") return False if self._daemon.isVCRPolicyChangeRequested(): return False return True
def launchRecording(self,recInfo): #As opposed to a previous version no AT queue is used. Reason: recording needs to be supervised #anyhow, so there is need for a supervising/scheduling process channel = recInfo.getEPGInfo().getChannel() OSTools.ensureDirectory(self._config.getRecordingPath(),channel.getEscapedName()) jobID= recInfo.getEPGInfo().getJobID() self._syncRecordIndex(jobID) scheduler= Recorder(self._config,self._recordCmd,self._recordPartIndex) return scheduler.scheduleRecording(recInfo)
def main(): if OSTools.checkIfInstanceRunning("RecorderWebServer"): global KXD argv = sys.argv #OSTools.changeWorkingDirectory(argv[0]) OSTools.changeWorkingDirectory(OSTools.getWorkingDirectory()) port = argv[1] tmp = argv[2].encode('utf-8') KXD = base64.b64encode(tmp).decode('utf-8') runHTTPServer(port)
def __init__(self,): self._config = Config() self._setUpLogging() self.epgUpdater = EpgUpdater(self._config) OSTools.ensureDirectory(self._config.getRecordingPath(),'') self._inhibitor = OSTools.Inhibitor() self._recordCmd = DVBDevice.getRecordCommander() self._lastJobId="0" self._recordPartIndex=0 self.isActive=True self._daemonPolicy = None
def createMaintenanceRecord(self): maintenanceDurance = 15*60; nextStart = OSTools.getDateTimeWithOffset(self.MAINT_DAY) maintMsg = "creating maintenance entry for %s" %(OSTools.dateTimeAsString(nextStart)) self._config.logInfo(maintMsg) print(maintMsg) maint = RecordingInfo(None); maint.setExecutionTime(nextStart) maint.setDurance(maintenanceDurance) return maint
def createMaintenanceRecord(self): maintenanceDurance = 15*60; nextStart = OSTools.getDateTimeWithOffset(self.MAINT_DAY) maintMsg = "creating maintenance entry for %s" %(OSTools.dateTimeAsString(nextStart)) self._config.logInfo(maintMsg) print maintMsg maint = RecordingInfo(None); maint.setExecutionTime(nextStart) maint.setDurance(maintenanceDurance) return maint
def _wasWakeupScheduled(self,startTime): now = datetime.now() secondsToWait = OSTools.getDifferenceInSeconds(startTime, now) duranceStr = OSTools.convertSecondsToString(secondsToWait) self._log("Delta durance to scheduled wakeup:"+duranceStr) if secondsToWait > self.PRERUN_SECONDS: self._log("Suspend interrupted by user-> going into Server mode!") return False if secondsToWait>0: self._log("Waiting until record starts:"+duranceStr) xtime.sleep(secondsToWait) return True
def _suspendDevice(self,seconds): coolDown=20 #mediaclient needs time to shutdown duranceStr = OSTools.convertSecondsToString(seconds) self._log("Going to sleep for %s" %(duranceStr)) logging.shutdown(); xtime.sleep(coolDown) mode = OSTools.RTC_SLEEP if Config.SUSPEND_MODE == Config.MODE_HIBERNATE: mode=OSTools.RTC_HIBERNATE result=OSTools.rtcWake(seconds-coolDown, mode) #back online self._daemon._setUpLogging() self._log(str(result[0].decode('utf8'))+":"+str(result[1].decode('utf8'))) self._log("Woke up")
def prepareFilmPage(self): style = '<style>body { float:left;} div {white-space: nowrap;padding:2px;margin:0px;font-family: Helvetica, Arial, sans-serif;font-size:0.85em;} .evenrow {background-color: #F8E0D7;} .oddrow {background-color: #F8EEEE;} .back {float:right}</style>' htmlStart = '<!DOCTYPE html><html><head><meta content="text/html; charset=UTF-8">' + style + '<title>Recorded Films</title><body>' htmlend = '--- End ---</body></html>' htmlBack = '<div class= back><a href="./Log.html">Back to Log</a></div>' srcFile = self._config.getLoggingPath() srcFile = OSTools.ensureFile(srcFile, "Filmlist.txt") destFile = self._config.getFilePath(self._config.getWebPath(), "Films.html") with codecs.open(srcFile, 'r', encoding="utf-8") as logFile: logLines = logFile.readlines() isEven = False with open(destFile, 'w+') as htmlFile: htmlFile.write(htmlStart) htmlFile.write("<b> The film list</b>") htmlFile.write(htmlBack) for line in logLines: if isEven: divid = "evenrow" else: divid = "oddrow" hack = self.utf8ToHTMLUmlauts(line) htmlFile.write('<div class="' + divid + '">' + hack + "</div>") isEven = not isEven htmlFile.write(htmlend)
def __linkLogging(self): # ../../../VideoRecorder/src/log/ # NO! That is where the command shell sits: currentPath=os.getcwd() destFile = self._config.getFilePath(self._config.getWebPath(), "Log.txt") srcFile = self._config.getLoggingPath(); srcFile = OSTools.ensureFile(srcFile, "dvb_suspend.log") self._config.logInfo("Linking file:" + srcFile) if not os.path.lexists(destFile): os.symlink(srcFile, destFile)
def _secondsUntilNextRun(self,startTime,prerunSeconds): now = datetime.now() secondsUntilStart = OSTools.getDifferenceInSeconds(startTime, now) secondsToSleep = secondsUntilStart - prerunSeconds #wake up a minute+ before if secondsToSleep < prerunSeconds: self._log("Next run in less than %s seconds"%(str(secondsUntilStart))) #sleep until time is ready.... no hibernate if secondsUntilStart > 0: self._log("Waiting to launch...."+str(secondsUntilStart)) xtime.sleep(secondsUntilStart) return 0 return secondsToSleep
def _getDaysSinceLastEPGUpdate(self): path = self._config.getEPGTimestampPath() if OSTools.fileExists(path): with open(path, 'r') as aFile: currentDate=aFile.read() try: checkDate = datetime.strptime(currentDate,self.EPG_TS_Template) delta = datetime.now()-checkDate return delta.days except ValueError: self._log("Error reading EPG Timestamp:"+str(currentDate)) return -1
def main(argv=None): if OSTools.checkIfInstanceRunning("DVBRecorder"): recorder = DVBRecorder() recorder.persistEPGData() ##TODO: Store config data # if recorder.configuration.STATE_USE_ENERGY_SAVER: # path = recorder.configuration.HomeDir+"/EnergySaver.py" # runEnergySaver(path,recorder) recorder.configuration.logInfo("Exit") recorder.configuration.logClose() print("Goodbye")
def checkEPGData(self): fileName = self.configuration.getCachedXMLTVFilePath() currentModificationtime = 0 try: currentModificationtime = OSTools.getLastModificationTime(fileName) except OSError as osError: msg = "CheckEpgData:" + osError.strerror self.configuration.logError(msg) self.storeLastMessage(msg) return # if self._lastEpgRead is None: # self._lastEpgRead= currentModificationtime-100 if currentModificationtime - self._lastEpgRead > 60: self._lastEpgRead = currentModificationtime self._readCachedEpgData()
def _monitorCurrentRecording(self,recProcess,recordingJob): done = False #this is testing: emergencyCount=0; jobID=recordingJob.getEPGInfo().getJobID() isRecurrentWriteError=False recPath = self._config.getRecordingPath() videoSize=OSTools.getDirectorySize(recPath) xtime.sleep(self.HEARTBEAT) self._log("Monitoring JOB "+jobID) while not done: result = recProcess.poll() isAlive = result is None if isAlive: currentSize = OSTools.getDirectorySize(recPath) delta = currentSize - videoSize print(("JOB "+jobID+" - bytes written:"+str(delta))) #live sign- not logging videoSize = currentSize if delta == 0: self._log("JOB "+jobID+" does not write any data") if isRecurrentWriteError: done=True self._log("Terminating Rec process, preventing reschedule.. ") recProcess.terminate() self.__handleProcessTermination(recProcess) isRecurrentWriteError=True #only on retry permitted else: self._log("Quit JOB "+jobID) self.__handleProcessTermination(recProcess) done=True if not done: #Ensure that an adjacent job can follow - decrease the wait time gludu=recordingJob.getGluedDurance() endtime = OSTools.addToDateTime(recordingJob.getExecutionTime(),gludu) delta = max(10,OSTools.getDifferenceInSeconds(endtime,datetime.now())) sleepTime = min(self.HEARTBEAT,delta) if sleepTime != self.HEARTBEAT: emergencyCount+=1; endTimeString=endtime.strftime("%H:%M.%S") startTimeString = recordingJob.getExecutionTime().strftime("%H:%M.%S") self._log("Stopping in seconds: %d (Info Start: %s expected end: %s with dur %d)"%(sleepTime,startTimeString,endTimeString,gludu))#log only the fragments if emergencyCount > 10: self._log("REC Q error- force process termination") recProcess.terminate() self.__handleProcessTermination(recProcess) done=True xtime.sleep(sleepTime) self._log("JOB "+jobID+" is done") OSTools.syncFiles()
def prepareLogFile(self, lineStart, lineCount): #read the log file, prepare it and put it into the log file text? self.log("Getting Log request") srcFile = self._config.getLoggingPath() srcFile = OSTools.ensureFile(srcFile, "dvb_suspend.log") destFile = self._config.getFilePath(self._config.getWebPath(), "Log.html") style = '<style>body { float:left;} div {white-space: nowrap;padding:2px;margin:0px;font-family: Helvetica, Arial, sans-serif;font-size:0.85em;} .evenrow {background-color: #F8E0D7;} .oddrow {background-color: #F8EEEE;}</style>' htmlStart = '<!DOCTYPE html><html><head><meta content="text/html; charset=UTF-8">' + style + '<title>Micro Recorder Log</title><body>' htmlend = '--- End ---</body></html>' htmlmore = '<a href="./Log.html?NXT">Log more?</a></body></html>' htmlFilms = '<a href="./Films.html">Show Films</a>' with codecs.open(srcFile, 'r', encoding='utf-8') as logFile: logLines = logFile.readlines() startIndex = len(logLines) reqLines = lineStart + lineCount reqEnd = max(0, startIndex - reqLines) print(("start:", startIndex, " to:", reqEnd)) #aRange=reversed(range(reqEnd,startIndex)) isEven = False with open(destFile, 'w+') as htmlFile: htmlFile.write(htmlStart) htmlFile.write("<b> The Logs (newest first) </b>") htmlFile.write(htmlFilms) #for line in logLines: lineIndex = startIndex while lineIndex > reqEnd: lineIndex -= 1 line = logLines[lineIndex] if isEven: divid = "evenrow" else: divid = "oddrow" htmlFile.write('<div class="' + divid + '">' + line + "</div>") isEven = not isEven if reqEnd == 0: htmlFile.write(htmlend) else: htmlFile.write(htmlmore)
def prepareLogFile(self,lineStart,lineCount): #read the log file, prepare it and put it into the log file text? self.log("Getting Log request") srcFile = self._config.getLoggingPath(); srcFile = OSTools.ensureFile(srcFile, "dvb_suspend.log") destFile = self._config.getFilePath(self._config.getWebPath(), "Log.html") style ='<style>body { float:left;} div {white-space: nowrap;padding:2px;margin:0px;font-family: Helvetica, Arial, sans-serif;font-size:0.85em;} .evenrow {background-color: #F8E0D7;} .oddrow {background-color: #F8EEEE;}</style>' htmlStart = '<!DOCTYPE html><html><head><meta content="text/html; charset=UTF-8">'+style+'<title>Micro Recorder Log</title><body>' htmlend = '--- End ---</body></html>' htmlmore = '<a href="./Log.html?NXT">Log more?</a></body></html>' with codecs.open(srcFile, 'r',"utf-8") as logFile: logLines = logFile.readlines() startIndex = len(logLines) reqLines = lineStart+lineCount reqEnd = max(0,startIndex-reqLines) print "start:",startIndex," to:",reqEnd #aRange=reversed(range(reqEnd,startIndex)) isEven=False with open(destFile, 'w+') as htmlFile: htmlFile.write(htmlStart) htmlFile.write("<b> The Logs (newest first) </b>") #for line in logLines: lineIndex = startIndex while lineIndex > reqEnd: lineIndex-=1; line=logLines[lineIndex] asccode = line.encode('ascii', 'xmlcharrefreplace') #makes utf8 readable! if isEven: divid="evenrow" else: divid="oddrow" htmlFile.write('<div class="'+divid+'">'+asccode+"</div>") isEven=not isEven if reqEnd==0: htmlFile.write(htmlend) else: htmlFile.write(htmlmore)
def adddirgui(self): self.addfile(OSTools.browse4dir(self, "Open dir to add"))
def handleNoJobs(self): if self._daemon.isServerPolicyChangeRequested(): return; self._daemon._stopQueue() #make sure in case that hibernation fails and logging is still active OSTools.saveEnergy(OSTools.RTC_HIBERNATE) self._daemon._exit()
def _isPolicyChangeRequested(self,markerFile): if OSTools.fileExists(markerFile): OSTools.removeFile(markerFile) return True return False
def addfilegui(self, path=None, prefonly=False): guiparam = {} guiparam['path'] = StringVar() guiparam['device'] = IntVar() guiparam['destchoice'] = IntVar() guiparam['dest'] = StringVar() guiparam['destfinal'] = StringVar() guiparam['returnval'] = BooleanVar(False) guiparam['taglan'] = StringVar() guiparam['sublan'] = StringVar() guiparam['movieset'] = StringVar() GP = self.getglobalparamcbk() if path != None: guiparam['path'].set(path) guiparam['destchoice'].set(1) if GP['DESTDIR'] != "": guiparam['dest'].set(GP['DESTDIR']) if GP['FINALDIR'] != "": guiparam['destfinal'].set(GP['FINALDIR']) guiparam['destchoice'].set(3) else: guiparam['destchoice'].set(2) guiparam['device'].set(GP['DEVICECONFS']) guiparam['taglan'].set(GP['TAGLAN']) guiparam['sublan'].set(GP['SUBLAN']) guiparam['movieset'].set(GP['MOVIESET']) filep = Toplevel(self, padx=10, pady=10) filep.protocol("WM_DELETE_WINDOW", "pass") if not prefonly: f = Frame(filep, border=1, relief=SUNKEN, padx=2, pady=2) f.pack(anchor=W, fill=BOTH) f.grid_columnconfigure(0, weight=1) Label(f, text="Select the file to transcode:").grid(row=0, column=0) Entry(f, textvariable=guiparam['path']).grid(row=1, column=0, sticky=W + E) Button(f, text="Browse", command=lambda: OSTools.browse4filename(filep, "Open file to transcode", [ ("Video files", ("*avi", "*.mkv", "*.mp4")), ("All files", "*.*")], guiparam['path'])).grid(row=1, column=1, sticky=W + E) Label(filep, text="Encoding paramaters").pack(anchor=W) f = Frame(filep, border=1, relief=SUNKEN, padx=2, pady=2) f.pack(anchor=W, fill=BOTH) Label(f, text="Select the device to transcode to:").pack(anchor=W) for i in range(len(self.devicelabels)): Radiobutton(f, text=self.devicelabels[i], variable=guiparam['device'], value=i).pack(anchor=W) f = Frame(filep, border=1, relief=SUNKEN, padx=2, pady=2) f.pack(anchor=W, fill=BOTH) f.grid_columnconfigure(1, weight=1) f.grid_columnconfigure(3, weight=1) Label(f, text="Select output dir (Please read the manual):").grid(row=0, column=0) Radiobutton(f, text="Same dir as source", variable=guiparam['destchoice'], value=1).grid(row=1, column=0, sticky=W) Radiobutton(f, text="To this dir", variable=guiparam['destchoice'], value=2).grid(row=2, column=0, sticky=W) Radiobutton(f, text="First to one dir and then to another", variable=guiparam['destchoice'], value=3).grid( row=3, column=0, sticky=W) Entry(f, textvariable=guiparam['dest']).grid(row=2, column=1, sticky=W + E) Entry(f, textvariable=guiparam['dest']).grid(row=3, column=1, sticky=W + E) Entry(f, textvariable=guiparam['destfinal']).grid(row=3, column=3, sticky=W + E) Button(f, text="Browse", command=lambda: OSTools.browse4dir(filep, "Select directory", guiparam['dest'])).grid( row=2, column=2, sticky=W + E) Button(f, text="Browse", command=lambda: OSTools.browse4dir(filep, "Select directory", guiparam['dest'])).grid( row=3, column=2, sticky=W + E) Button(f, text="Browse", command=lambda: OSTools.browse4dir(filep, "Select directory", guiparam['destfinal'])).grid(row=3, column=4, sticky=W + E) f = Frame(filep, border=1, relief=SUNKEN, padx=2, pady=2) f.pack(anchor=W, fill=BOTH) f.grid_columnconfigure(1, weight=1) f.grid_columnconfigure(3, weight=1) Label(f, text="Tag langugage ID (en for english, fr for french, etc...):").grid(row=0, column=0) Entry(f, textvariable=guiparam['taglan']).grid(row=0, column=1, sticky=W + E) f = Frame(filep, border=1, relief=SUNKEN, padx=2, pady=2) f.pack(anchor=W, fill=BOTH) f.grid_columnconfigure(1, weight=1) f.grid_columnconfigure(3, weight=1) Label(f, text="XBMC .nfo prefs").grid(row=1, column=0) Label(f, text="Subtitle download langugage ID (empty for no download, eng for english, fre for french, etc...):").grid( row=2, column=0) Entry(f, textvariable=guiparam['sublan']).grid(row=2, column=1, sticky=W + E) Label(f, text="Movie set (empty for None):").grid(row=3, column=0) Entry(f, textvariable=guiparam['movieset']).grid(row=3, column=1, sticky=W + E) f = Frame(filep, padx=2, pady=2) f.pack() Button(f, text="Go", command=lambda: guiparam['returnval'].set(True), width=20).grid(row=0, column=0, sticky=W) Button(f, text="Cancel", command=lambda: guiparam['returnval'].set(False), width=20).grid(row=0, column=1, sticky=E) self.wait_variable(guiparam['returnval']) filep.destroy() return guiparam
def addfilegui(self, path=None, prefonly=False): guiparam = {} guiparam['path'] = StringVar() guiparam['device'] = IntVar() guiparam['destchoice'] = IntVar() guiparam['dest'] = StringVar() guiparam['destfinal'] = StringVar() guiparam['returnval'] = BooleanVar(False) guiparam['taglan'] = StringVar() guiparam['sublan'] = StringVar() guiparam['movieset'] = StringVar() GP = self.getglobalparamcbk() if path != None: guiparam['path'].set(path) guiparam['destchoice'].set(1) if GP['DESTDIR'] != "": guiparam['dest'].set(GP['DESTDIR']) if GP['FINALDIR'] != "": guiparam['destfinal'].set(GP['FINALDIR']) guiparam['destchoice'].set(3) else: guiparam['destchoice'].set(2) guiparam['device'].set(GP['DEVICECONFS']) guiparam['taglan'].set(GP['TAGLAN']) guiparam['sublan'].set(GP['SUBLAN']) guiparam['movieset'].set(GP['MOVIESET']) filep = Toplevel(self, padx=10, pady=10) filep.protocol("WM_DELETE_WINDOW", "pass") if not prefonly: f = Frame(filep, border=1, relief=SUNKEN, padx=2, pady=2) f.pack(anchor=W, fill=BOTH) f.grid_columnconfigure(0, weight=1) Label(f, text="Select the file to transcode:").grid(row=0, column=0) Entry(f, textvariable=guiparam['path']).grid(row=1, column=0, sticky=W + E) Button(f, text="Browse", command=lambda: OSTools.browse4filename( filep, "Open file to transcode", [ ("Video files", ("*avi", "*.mkv", "*.mp4")), ("All files", "*.*") ], guiparam['path'])).grid(row=1, column=1, sticky=W + E) Label(filep, text="Encoding paramaters").pack(anchor=W) f = Frame(filep, border=1, relief=SUNKEN, padx=2, pady=2) f.pack(anchor=W, fill=BOTH) Label(f, text="Select the device to transcode to:").pack(anchor=W) for i in range(len(self.devicelabels)): Radiobutton(f, text=self.devicelabels[i], variable=guiparam['device'], value=i).pack(anchor=W) f = Frame(filep, border=1, relief=SUNKEN, padx=2, pady=2) f.pack(anchor=W, fill=BOTH) f.grid_columnconfigure(1, weight=1) f.grid_columnconfigure(3, weight=1) Label(f, text="Select output dir (Please read the manual):").grid( row=0, column=0) Radiobutton(f, text="Same dir as source", variable=guiparam['destchoice'], value=1).grid(row=1, column=0, sticky=W) Radiobutton(f, text="To this dir", variable=guiparam['destchoice'], value=2).grid(row=2, column=0, sticky=W) Radiobutton(f, text="First to one dir and then to another", variable=guiparam['destchoice'], value=3).grid(row=3, column=0, sticky=W) Entry(f, textvariable=guiparam['dest']).grid(row=2, column=1, sticky=W + E) Entry(f, textvariable=guiparam['dest']).grid(row=3, column=1, sticky=W + E) Entry(f, textvariable=guiparam['destfinal']).grid(row=3, column=3, sticky=W + E) Button(f, text="Browse", command=lambda: OSTools.browse4dir(filep, "Select directory", guiparam['dest'])).grid( row=2, column=2, sticky=W + E) Button(f, text="Browse", command=lambda: OSTools.browse4dir(filep, "Select directory", guiparam['dest'])).grid( row=3, column=2, sticky=W + E) Button(f, text="Browse", command=lambda: OSTools.browse4dir(filep, "Select directory", guiparam['destfinal'])).grid( row=3, column=4, sticky=W + E) f = Frame(filep, border=1, relief=SUNKEN, padx=2, pady=2) f.pack(anchor=W, fill=BOTH) f.grid_columnconfigure(1, weight=1) f.grid_columnconfigure(3, weight=1) Label(f, text="Tag langugage ID (en for english, fr for french, etc...):" ).grid(row=0, column=0) Entry(f, textvariable=guiparam['taglan']).grid(row=0, column=1, sticky=W + E) f = Frame(filep, border=1, relief=SUNKEN, padx=2, pady=2) f.pack(anchor=W, fill=BOTH) f.grid_columnconfigure(1, weight=1) f.grid_columnconfigure(3, weight=1) Label(f, text="XBMC .nfo prefs").grid(row=1, column=0) Label( f, text= "Subtitle download langugage ID (empty for no download, eng for english, fre for french, etc...):" ).grid(row=2, column=0) Entry(f, textvariable=guiparam['sublan']).grid(row=2, column=1, sticky=W + E) Label(f, text="Movie set (empty for None):").grid(row=3, column=0) Entry(f, textvariable=guiparam['movieset']).grid(row=3, column=1, sticky=W + E) f = Frame(filep, padx=2, pady=2) f.pack() Button(f, text="Go", command=lambda: guiparam['returnval'].set(True), width=20).grid(row=0, column=0, sticky=W) Button(f, text="Cancel", command=lambda: guiparam['returnval'].set(False), width=20).grid(row=0, column=1, sticky=E) self.wait_variable(guiparam['returnval']) filep.destroy() return guiparam
def getEndTime(self): return OSTools.addToDateTime(self._execTime, self._duranceInSeconds)
def __setupDirectories(self): OSTools.ensureDirectory(self.DataDir,self.LogPath) OSTools.ensureDirectory(self.DataDir,self.XMLPath)
def isMaintenanceNeeded(self,recInfo): maintenanceDurance = 15*60; nextStart = OSTools.getDateTimeWithOffset(self.MAINT_DAY) maintEnd = OSTools.addToDateTime(nextStart, maintenanceDurance) scheduledStartTime = recInfo.getEPGInfo().getStartTime() return maintEnd <= scheduledStartTime
def _isTimeLeftForEPGUpdate(self,nextStartTime): now = datetime.now() seconds = OSTools.getDifferenceInSeconds(nextStartTime, now) return seconds > self.HEARTBEAT*10
print(("dispatched command::"+cmdText)) self._config.logInfo("command sent: \n"+cmdText+" | scheduled at:"+timeString) #TODO: process still alive - even if done -- still syncing??? return process def main(): argv = sys.argv if len(argv)==1: RecorderDaemon().run() else: cmd = argv[1] if "epg" in cmd.lower(): RecorderDaemon().readEPGData() return 0; if "job" in cmd.lower(): job = RecorderDaemon()._getNextJob() if job is None: print("No jobs pending") else: print(("Next Job @"+str(job.getExecutionTime()))) return 0; print("start daemon with no args.. Use 'getEpg' to read EPG or 'showJobs' for pending jobs") return 1; if __name__ =="__main__": if OSTools.checkIfInstanceRunning("RecorderDaemon"): OSTools.changeWorkingDirectory(OSTools.getWorkingDirectory()) sys.exit(main()) else: print("Daemon already running...")
def readEPGData(self): path = self._config.getEPGTimestampPath() if OSTools.fileExists(path): OSTools.removeFile(path) self._updateEPGData()
def openPrefs(self): guiparam = {} guiparam['destdir'] = StringVar() guiparam['localroot'] = StringVar() guiparam['remoteroot'] = StringVar() guiparam['taglan'] = StringVar() guiparam['sublan'] = StringVar() guiparam['movieset'] = StringVar() guiparam['force'] = IntVar() guiparam['remoterelat'] = IntVar() guiparam['moviefilter'] = StringVar() guiparam['returnval'] = BooleanVar(False) GP = self.mediaPrez.GetGlobalParam() guiparam['destdir'].set(GP['DESTDIR']) guiparam['localroot'].set(GP['LOCALROOT']) guiparam['remoteroot'].set(GP['REMOTEROOT']) guiparam['taglan'].set(GP['TAGLAN']) guiparam['sublan'].set(GP['SUBLAN']) guiparam['movieset'].set(GP['MOVIESET']) guiparam['force'].set(GP['FORCERELOAD']) guiparam['remoterelat'].set(GP['REMOTERELAT']) guiparam['moviefilter'].set(GP['MOVIEFILTER']) filep = Toplevel(self, padx=10, pady=10) filep.protocol("WM_DELETE_WINDOW", "pass") Label(filep, text="Options").pack(anchor=W) f = Frame(filep, border=1, relief=SUNKEN, padx=2, pady=2) f.pack(anchor=W, fill=BOTH, expand=1) # f.grid_columnconfigure(0,weight=1) f.grid_columnconfigure(1, weight=1) # f.grid_columnconfigure(2,weight=1) rowi = 0 Label(f, text="Select output dir:").grid(row=rowi, column=0) Entry(f, textvariable=guiparam['destdir']).grid(row=rowi, column=1, sticky=W + E) Button(f, text="Browse", command=lambda: OSTools.browse4dir(filep, "Destination directory", guiparam['destdir'])).grid(row=rowi, column=2, sticky=W + E) rowi = rowi + 1 Label(f, text="Local root dir:").grid(row=rowi, column=0) Entry(f, textvariable=guiparam['localroot']).grid(row=rowi, column=1, sticky=W + E) Button(f, text="Browse", command=lambda: OSTools.browse4dir(filep, "Local root directory", guiparam['localroot'])).grid(row=rowi, column=2, sticky=W + E) rowi = rowi + 1 Label(f, text="Remote root dir:").grid(row=rowi, column=0) Entry(f, textvariable=guiparam['remoteroot']).grid(row=rowi, column=1, sticky=W + E) Button(f, text="Browse", command=lambda: OSTools.browse4dir(filep, "Remote root directory", guiparam['remoteroot'])).grid( row=rowi, column=2, sticky=W + E) rowi = rowi + 1 Checkbutton(f, text="Remote dir is relative", variable=guiparam['remoterelat']).grid(row=rowi, column=0, sticky=W + E) Button(f, text="Remote is PCH/Popcorn", command=lambda: guiparam['remoteroot'].set("file:///opt/sybhttpd/localhost.drives/HARD_DISK/")).grid( row=rowi, column=2, sticky=W + E) rowi = 0 f = Frame(filep, border=1, relief=SUNKEN, padx=2, pady=2) f.pack(anchor=W, fill=BOTH, expand=1) # f.grid_columnconfigure(0,weight=1) f.grid_columnconfigure(1, weight=1) Label(f, text="Filter for videos file (.avi,.mkv ...):").grid(row=rowi, column=0) Entry(f, textvariable=guiparam['moviefilter']).grid(row=rowi, column=1, sticky=W + E) rowi = rowi + 1 Label(f, text="Tag langugage ID (en for english, fr for french, etc...):").grid(row=rowi, column=0) Entry(f, textvariable=guiparam['taglan']).grid(row=rowi, column=1, sticky=W + E) rowi = rowi + 1 Checkbutton(f, text="Force reload from the web", variable=guiparam['force']).grid(row=rowi, column=1, sticky=W + E) f.pack(anchor=W, fill=BOTH, expand=1) rowi = 0 f = Frame(filep, border=1, relief=SUNKEN, padx=2, pady=2) f.pack(anchor=W, fill=BOTH, expand=1) # f.grid_columnconfigure(0,weight=1) f.grid_columnconfigure(1, weight=1) Label(f, text="XBMC .nfo prefs:").grid(row=rowi, column=0) rowi = rowi + 1 Label(f, text="Subtitles langugage ID (empty for none, fre for french, eng for english, etc...):").grid( row=rowi, column=0) Entry(f, textvariable=guiparam['sublan']).grid(row=rowi, column=1, sticky=W + E) rowi = rowi + 1 Label(f, text="Movie set (empty for None):").grid(row=rowi, column=0) Entry(f, textvariable=guiparam['movieset']).grid(row=rowi, column=1, sticky=W + E) f.pack(anchor=W, fill=BOTH, expand=1) f = Frame(filep, padx=2, pady=2) f.pack() Button(f, text="Go", command=lambda: guiparam['returnval'].set(True), width=20).grid(row=0, column=0, sticky=W) Button(f, text="Cancel", command=lambda: guiparam['returnval'].set(False), width=20).grid(row=0, column=1, sticky=E) self.wait_variable(guiparam['returnval']) filep.destroy() if guiparam['returnval'].get(): GP['DESTDIR'] = guiparam['destdir'].get() GP['LOCALROOT'] = guiparam['localroot'].get() GP['REMOTEROOT'] = guiparam['remoteroot'].get() GP['TAGLAN'] = guiparam['taglan'].get() GP['SUBLAN'] = guiparam['sublan'].get() GP['MOVIESET'] = guiparam['movieset'].get() GP['FORCERELOAD'] = guiparam['force'].get() GP['REMOTERELAT'] = guiparam['remoterelat'].get() GP['MOVIEFILTER'] = guiparam['moviefilter'].get() self.updateMovieFilter(GP['MOVIEFILTER']) self.mediaPrez.SetGlobalParam(GP)
def __setupDirectories(self): OSTools.ensureDirectory(self.LogDir, self.LogPath) OSTools.ensureDirectory(self.DataDir, self.XMLPath)
def addbtn(self): self.addfile(OSTools.browse4filename(self, "Open file to add", [("Video files", ("*avi", "*.mkv", "*.mp4")), ("All files", "*.*")])) return False