import os from os import path from enigma import eTimer, getDesktop from Components.ActionMap import ActionMap from Components.FileList import FileList from Components.Sources.List import List from Components.Sources.StaticText import StaticText from Components.Task import Task, Job, job_manager from Screens.Screen import Screen from Tools.Directories import fileExists from Downloader import DownloadWithProgress, DownloadWithProgressFragmented,get_header def timer_callback(timer,callback): if "callback" in dir(timer): timer.callback.append(callback) else: timer_conn = timer.timeout.connect(callback) ########################################################################################### class DownloadJob(Job): def __init__(self, url, outputfile, title, downloadStop,headers=None,stream_type="http"): Job.__init__(self, title) DownloadTask(self, url, outputfile, title, downloadStop,headers,stream_type) class DownloadTask(Task): def __init__(self, job, url, outputfile, title, downloadStop,headers={},stream_type="http"): Task.__init__(self, job, _('Downloading')) self.job = job self.title = title self.url = url self.outputfile = outputfile self.headers = headers self.stream_type = stream_type self.downloadStop = downloadStop self.job.currentbytes = 0 self.job.totalbytes = -1 def run(self, callback): self.callback = callback if self.stream_type == "hls": self.download = DownloadWithProgressFragmented(self.url, self.outputfile,self.headers) else: self.download = DownloadWithProgress(self.url, self.outputfile, self.headers) self.download.addProgress(self.downloadProgress) self.download.start().addCallback(self.downloadFinished).addErrback(self.downloadFailed) def downloadProgress(self, currentbytes, totalbytes): self.job.currentbytes = currentbytes self.job.totalbytes = totalbytes progress = self.job.currentbytes/float(self.job.totalbytes) * 100 self.setProgress(progress) def downloadFinished(self, result): Task.processFinished(self, 0) self.setProgress(self.end) self.downloadStop("Success - " + self.title) def downloadFailed(self, failure_instance=None, error_message=''): print '[PlayStream] Video download failed' if error_message == '' and failure_instance is not None: error_message = failure_instance.getErrorMessage() print '[PlayStream]', str(error_message) Task.processFinished(self, 1) self.downloadStop("Failed - "+ self.title) class HLSDownloadJob(Job): def __init__(self, url, destfile, title,downloadStop,headers=None): Job.__init__(self, title) AddHLSProcessTask(self, url, destfile, title, downloadStop,headers) ###################################################################################################### class AddHLSProcessTask(Task): def __init__(self, job, url, destfile, title,downloadStop,headers=None): Task.__init__(self, job, title) self.job = job self.title = title cmdline = '/usr/bin/gst-launch-1.0 "%s" ! hlsdemux ! filesink location="%s"'%(url,destfile) self.setCmdline(cmdline) self.url = url self.destfile = destfile self.downloadStop = downloadStop self.job.currentbytes = 0 self.job.totalbytes = 0 #self.setProgress(100) self.ProgressTimer = eTimer() timer_callback(self.ProgressTimer, self.ProgressUpdate) def ProgressUpdate(self): if not fileExists(self.destfile, 'r'): return self.job.currentbytes = path.getsize(self.destfile) progress = self.job.currentbytes/float(self.job.totalbytes) * 100 if self.job.totalbytes else 0 self.setProgress(progress) #self.setProgress(int((path.getsize(self.destfile)/float(self.totalbytes))*100)) self.ProgressTimer.start(5000, True) def prepare(self): self.job.totalbytes = -1 # TODO getsize(self.url) self.ProgressTimer.start(5000, True) def afterRun(self): #self.setProgress(100) self.ProgressTimer.stop() self.downloadStop(self.title) class VideoDownloadList(Screen): screenWidth = getDesktop(0).size().width() if screenWidth and screenWidth == 1920: skin = """ {"template": [ MultiContentEntryText(pos=(15,1), size=(465,33), \ font=0, flags=RT_HALIGN_LEFT, text=1), # Title MultiContentEntryText(pos=(345,1), size=(225,33), \ font=0, flags=RT_HALIGN_RIGHT, text=2), # State MultiContentEntryProgress(pos=(585,6), size=(150,33), \ percent=-3), # Progress MultiContentEntryText(pos=(750,1), size=(120,33), \ font=0, flags=RT_HALIGN_LEFT, text=4), # Percentage ], "fonts": [gFont("Regular",30)], "itemHeight": 45} """ else: skin = """ {"template": [ MultiContentEntryText(pos=(10,1), size=(210,22), \ font=0, flags=RT_HALIGN_LEFT, text=1), # Title MultiContentEntryText(pos=(230,1), size=(150,22), \ font=0, flags=RT_HALIGN_RIGHT, text=2), # State MultiContentEntryProgress(pos=(390,4), size=(100,22), \ percent=-3), # Progress MultiContentEntryText(pos=(500,1), size=(80,22), \ font=0, flags=RT_HALIGN_LEFT, text=4), # Percentage ], "fonts": [gFont("Regular",20)], "itemHeight": 30} """ def __init__(self, session): Screen.__init__(self, session) self['key_red'] = StaticText(_('Exit')) self['list'] = List([]) self['actions'] = ActionMap(['SetupActions', 'ColorActions'], { 'cancel': self.close, 'ok': self.ok, 'red': self.close, 'blue': self.abort }, -2) self.onLayoutFinish.append(self.layoutFinished) self.onClose.append(self.cleanVariables) self.progressTimer = eTimer() timer_callback(self.progressTimer,self.updateDownloadList) def layoutFinished(self): self.setTitle(_('Active video downloads')) self.updateDownloadList() def cleanVariables(self): del self.progressTimer def updateDownloadList(self): self.progressTimer.stop() downloadList = [] for job in job_manager.getPendingJobs(): progress = job.progress / float(job.end) * 100 currentbytes = job.currentbytes if "currentbytes" in dir(job) else 0 downloadList.append((job, job.name, job.getStatustext(), int(progress), "%.1fM"%(currentbytes/1024.0/1024.0) )) self['list'].updateList(downloadList) if downloadList: self.progressTimer.startLongTimer(2) def ok(self): current = self['list'].getCurrent() if current: from Screens.TaskView import JobView self.session.open(JobView, current[0]) def abort(self): current = self['list'].getCurrent() job = current[0] if job.status == job.NOT_STARTED: job_manager.active_jobs.remove(job) self.close(False) elif job.status == job.IN_PROGRESS: job.cancel() else: self.close(False) class VideoDirBrowser(Screen): def __init__(self, session, downloadDir): Screen.__init__(self, session) self.skinName = ['VideoDirBrowser', 'FileBrowser'] self['key_red'] = StaticText(_('Cancel')) self['key_green'] = StaticText(_('Use')) if not os.path.exists(downloadDir): downloadDir = '/' self.filelist = FileList(downloadDir, showFiles = False) self['filelist'] = self.filelist self['FilelistActions'] = ActionMap(['SetupActions', 'ColorActions'], { 'cancel': self.cancel, 'red': self.cancel, 'ok': self.ok, 'green': self.use }, -2) self.onLayoutFinish.append(self.layoutFinished) def layoutFinished(self): self.setTitle(_('Please select the download directory')) def ok(self): if self.filelist.canDescent(): self.filelist.descent() def use(self): currentDir = self['filelist'].getCurrentDirectory() dirName = self['filelist'].getFilename() if currentDir is None or \ (self.filelist.canDescent() and dirName and len(dirName) > len(currentDir)): self.close(dirName) def cancel(self): self.close(False)