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)