示例#1
0
class SingleFileDownloaderWidget(Screen):
    sz_w = getDesktop(0).size().width() - 190
    sz_h = getDesktop(0).size().height() - 195
    if sz_h < 500:
        sz_h += 4
    skin = """
        <screen position="center,center" title="%s" size="%d,%d">
         <widget name="icon_red"    position="5,9"   zPosition="4" size="30,30" transparent="1" alphatest="on" />
         <widget name="icon_green"  position="355,9" zPosition="4" size="30,30" transparent="1" alphatest="on" />

         <widget name="label_red"     position="45,9"  size="175,27" zPosition="5" valign="center" halign="left" backgroundColor="black" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
         <widget name="label_green"   position="395,9" size="175,27" zPosition="5" valign="center" halign="left" backgroundColor="black" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />

         <widget name="title" position="5,47"  zPosition="1" size="%d,23" font="Regular;20"            transparent="1"  backgroundColor="#00000000"/>

         <widget name="console"      position="10,%d"   zPosition="2" size="%d,160" valign="center" halign="center"   font="Regular;24" transparent="0" foregroundColor="white" backgroundColor="black"/>
        </screen>""" % (
        _("Single file downloader"),
        sz_w,
        sz_h,  # size
        sz_w - 135,  # size title
        (sz_h - 160) / 2,
        sz_w - 20,  # console
    )

    def __init__(self, session, uri, outFile, title=''):
        self.session = session
        Screen.__init__(self, session)

        self.uri = uri
        self.outFile = outFile
        self.title = title

        self.onShown.append(self.onStart)
        self.onClose.append(self.__onClose)

        self["title"] = Label(" ")
        self["console"] = Label(" ")

        self["label_red"] = Label(_("Cancel"))
        self["label_green"] = Label(_("Apply"))

        self["icon_red"] = Cover3()
        self["icon_green"] = Cover3()

        self["actions"] = ActionMap([
            "ColorActions", "SetupActions", "WizardActions", "ListboxActions"
        ], {
            "cancel": self.keyExit,
            "red": self.keyRed,
            "green": self.keyGreen,
        }, -2)

        self.iconPixmap = {}
        for icon in ['red', 'green']:
            self.iconPixmap[icon] = LoadPixmap(GetIconDir(icon + '.png'))

        self.downloader = None
        self.cleanDownloader()

    def __onClose(self):
        self.cleanDownloader()

    def cleanDownloader(self):
        if self.downloader != None:
            self.downloader.unsubscribeFor_Finish(self.downloadFinished)
            self.downloader.terminate()
        self.downloader = None

    def startDownload(self):
        self.cleanDownloader()
        self["console"].setText(_("Downloading file:\n%r.") % self.uri)

        self.downloader = DownloaderCreator(self.uri)
        if self.downloader:
            self.downloader.isWorkingCorrectly(self._startDownloader)
        else:
            self["console"].setText(
                _("Download can not be started.\nIncorrect address \"%r\".") %
                self.uri)

    def _startDownloader(self, sts, reason):
        if sts:
            self.downloader.subscribeFor_Finish(self.downloadFinished)
            url, downloaderParams = DMHelper.getDownloaderParamFromUrl(
                self.uri)
            self.downloader.start(url, self.outFile, downloaderParams)
        else:
            error, desc = self.downloader.getLastError()
            self["console"].setText(
                _("Download can not be started.\nDownloader %s not working correctly.\nLast error \"%s (%s)\"."
                  ) % (self.downloader.getName(), desc, error))

    def downloadFinished(self, status):
        if status != DMHelper.STS.DOWNLOADED:
            error, desc = self.downloader.getLastError()
            self["console"].setText(
                _("Download failed.\nLast error \"%s (%s)\".") % (desc, error))
            rm(self.outFile)
        else:
            self.close(True)

    def loadIcons(self):
        try:
            for icon in self.iconPixmap:
                self['icon_' + icon].setPixmap(self.iconPixmap[icon])
        except Exception:
            printExc()

    def hideButtons(self, buttons=['green']):
        try:
            for button in buttons:
                self['icon_' + button].hide()
                self['label_' + button].hide()
        except Exception:
            printExc()

    def showButtons(self, buttons=['red', 'green']):
        try:
            for button in buttons:
                self['icon_' + button].show()
                self['label_' + button].show()
        except Exception:
            printExc()

    def onStart(self):
        self.onShown.remove(self.onStart)
        self.setTitle(self.title)
        self.loadIcons()
        self.hideButtons()
        self.startDownload()

    def keyExit(self):
        if self.downloader != None and self.downloader.isDownloading():
            self.downloader.terminate()
        else:
            self.close(None)

    def keyRed(self):
        self.keyExit()

    def keyGreen(self):
        pass
示例#2
0
class IPTVPicturePlayerWidget(Screen):
    NUM_OF_ICON_FRAMES = 8
    #######################
    #       SIZES
    #######################
    # screen size
    # we do not want borders, so make the screen lager than a desktop
    sz_w = getDesktop(0).size().width()
    sz_h = getDesktop(0).size().height()
    # percentage
    s_w = 120
    s_h = 120
    # icon
    i_w = 128
    i_h = 128
    # console
    c_w = sz_w
    c_h = 80
    # picture
    p_w = sz_w - 20
    p_h = sz_h - 20
    #######################
    #     POSITIONS
    #######################
    start_y = (sz_h - (i_h + c_h)) / 2
    # percentage
    s_x = (sz_w - s_w) / 2
    s_y = start_y + (i_h - s_h) / 2
    # icon
    i_x = (sz_w - i_w) / 2
    i_y = start_y
    # console
    c_x = 0
    c_y = i_y + i_h
    # picture
    p_x = 10
    p_y = 10

    printDBG("[IPTVPicturePlayerWidget] desktop size %dx%d" % (sz_w, sz_h))
    skin = """
        <screen name="IPTVPicturePlayerWidget"  position="center,center" size="%d,%d" title="IPTV Picture Player...">
         <widget name="status"     size="%d,%d"   position="%d,%d"  zPosition="5" valign="center" halign="center"  font="Regular;21" backgroundColor="black" transparent="1" /> #foregroundColor="white" shadowColor="black" shadowOffset="-1,-1"
         <widget name="console"    size="%d,%d"   position="%d,%d"  zPosition="5" valign="center" halign="center"  font="Regular;21" backgroundColor="black" transparent="1" />
         <widget name="icon"       size="%d,%d"   position="%d,%d"  zPosition="4" transparent="1" alphatest="on" />
         <widget name="picture"    size="%d,%d"   position="%d,%d"  zPosition="6" transparent="1" alphatest="on" />
        </screen>""" % (
        sz_w,
        sz_h,  # screen
        s_w,
        s_h,
        s_x,
        s_y,  # status
        c_w,
        c_h,
        c_x,
        c_y,  # console
        i_w,
        i_h,
        i_x,
        i_y,  # icon
        p_w,
        p_h,
        p_x,
        p_y  # picture
    )

    def __init__(self,
                 session,
                 url,
                 pathForRecordings,
                 pictureTitle,
                 addParams={}):
        self.session = session
        Screen.__init__(self, session)
        self.onStartCalled = False

        self.recordingPath = pathForRecordings
        try:
            self.filePath = os.path.join(pathForRecordings,
                                         '.iptv_buffering.jpg')
        except Exception:
            self.filePath = ''
            printExc()

        self.addParams = {'seq_mode': False}
        self.addParams.update(addParams)

        self.url = url
        self.pictureTitle = pictureTitle
        self.audioUrl = strwithmeta(url).meta.get("iptv_audio_url", '')

        self["actions"] = ActionMap(
            [
                'IPTVAlternateVideoPlayer', 'MoviePlayerActions',
                'MediaPlayerActions', 'WizardActions', 'DirectionActions'
            ], {
                'leavePlayer': self.key_exit,
                'play': self.key_play,
                'pause': self.key_pause,
                'exit': self.key_exit,
                'back': self.key_exit,
                'ok': self.key_ok,
            }, -1)

        self["status"] = Label()
        self["console"] = Label()
        self["icon"] = SimpleAnimatedCover()
        self["picture"] = Cover()

        # prepare icon frames path
        frames = []
        for idx in range(1, self.NUM_OF_ICON_FRAMES + 1):
            frames.append(GetIconDir('/buffering/buffering_%d.png' % idx))
        self["icon"].loadFrames(frames)

        #main Timer
        self.mainTimer = eTimer()
        self.mainTimerEnabled = False

        if self.addParams['seq_mode']:
            self.canAutoClose = True
            self.mainTimer_conn = eConnectCallback(self.mainTimer.timeout,
                                                   self.closeAfterTimeout)
            self.mainTimerInterval = 1000 * 10  #10s
        else:
            self.mainTimer_conn = eConnectCallback(self.mainTimer.timeout,
                                                   self.updateDisplay)
            self.mainTimerInterval = 100  # by default 0,1s
        # download
        self.downloader = DownloaderCreator(self.url)

        self.onClose.append(self.__onClose)
        self.onShow.append(self.doStart)
        #self.onLayoutFinish.append(self.doStart)

        self.autoRefresh = False
        self.refreshPostfixes = ['_0', '_1']
        self.refreshCount = 0
        self.refreshing = False

        if len(self.audioUrl) and len(
                config.plugins.iptvplayer.gstplayerpath.value):
            self.audioPlayer = IPTVSimpleAudioPlayer()
        else:
            self.audioPlayer = None

    #end def __init__(self, session):

    def __del__(self):
        printDBG(
            'IPTVPicturePlayerWidget.__del__ --------------------------------------'
        )

    def __onClose(self):
        printDBG(
            'IPTVPicturePlayerWidget.__onClose ------------------------------------'
        )
        if None != self.audioPlayer: self.audioPlayer.close()
        self.onEnd()
        if None != self.mainTimer:
            try:
                self.mainTimer.stop()
            except Exception:
                pass
        self.mainTimer_conn = None
        self.mainTimer = None

        self.onClose.remove(self.__onClose)
        #self.onLayoutFinish.remove(self.doStart)

    def _getDownloadFilePath(self):
        return self.filePath + self.refreshPostfixes[self.refreshCount % len(
            self.refreshPostfixes)]

    def closeAfterTimeout(self):
        if self.canAutoClose:
            self.close()

    def onStart(self):
        '''
            this method is called once like __init__ but in __init__ we cannot display MessageBox
        '''
        self["picture"].hide()
        self["console"].setText(self.pictureTitle)
        self["status"].setText(_("--"))
        self._cleanedUp()

        if self.url.startswith('file://'):
            self.filePath = self.url[7:]
            self["status"].setText(_("++"))
            if -1 == self["picture"].decodeCover(self.filePath,
                                                 self.decodePictureEnd, ' '):
                self.decodePictureEnd()
        else:
            if self.downloader:
                self.downloader.isWorkingCorrectly(self._startDownloader)
            else:
                self.session.openWithCallback(
                    self.close,
                    MessageBox,
                    _("Downloading cannot be started.\n Invalid URI[%s].") %
                    self.url,
                    type=MessageBox.TYPE_ERROR,
                    timeout=10)

    def _doStart(self, force=False):
        if self.addParams['seq_mode']:
            self.mainTimer.start(self.mainTimerInterval, True)  #single shot
            return
        if self.autoRefresh or force:
            self.refreshing = True
            self.downloader = DownloaderCreator(self.url)

            url, downloaderParams = DMHelper.getDownloaderParamFromUrl(
                self.url)
            self.downloader.subscribeFor_Finish(self.downloaderEnd)
            self.downloader.start(url, self._getDownloadFilePath(),
                                  downloaderParams)
            self.setMainTimerSts(True)
        else:
            self.refreshing = False

    def _startDownloader(self, sts, reason):
        if sts: self._doStart(True)
        else:
            self.session.openWithCallback(
                self.close,
                MessageBox,
                _("Downloading cannot be started.\n Downloader [%s] not working properly.\n Status[%s]"
                  ) % (self.downloader.getName(), reason.strip()),
                type=MessageBox.TYPE_ERROR,
                timeout=10)

    def onEnd(self, withCleanUp=True):
        self.setMainTimerSts(False)
        if self.downloader:
            self.downloader.unsubscribeFor_Finish(self.downloaderEnd)
            downloader = self.downloader
            self.downloader = None
            downloader.terminate()
            downloader = None
        if withCleanUp:
            self._cleanedUp()

    def key_exit(self):
        self.close('key_exit')

    def key_play(self):
        if self.addParams['seq_mode']:
            self.canAutoClose = False
            return

        if not self.autoRefresh and not self.url.startswith('file://'):
            if None != self.audioPlayer: self.audioPlayer.start(self.audioUrl)
            self.autoRefresh = True
            if not self.refreshing: self._doStart()

    def key_pause(self):
        if self.addParams['seq_mode']:
            self.canAutoClose = False
            return
        if self.autoRefresh:
            if None != self.audioPlayer: self.audioPlayer.stop()
            self.autoRefresh = False

    def key_ok(self):
        if self.addParams['seq_mode']:
            self.canAutoClose = False
            return
        if self.autoRefresh: self.key_pause()
        else: self.key_play()

    def downloaderEnd(self, status):
        if None != self.downloader:
            self.onEnd(False)
            if DMHelper.STS.DOWNLOADED == status:
                self["status"].setText(_("++"))
                if -1 == self["picture"].decodeCover(
                        self._getDownloadFilePath(), self.decodePictureEnd,
                        ' '):
                    self.decodePictureEnd()
            else:
                if 0 == self.refreshCount:
                    self.session.openWithCallback(
                        self.close,
                        MessageBox,
                        (_("Downloading file [%s] problem.") % self.url) +
                        (" sts[%r]" % status),
                        type=MessageBox.TYPE_ERROR,
                        timeout=10)
                self._doStart()

    def decodePictureEnd(self, ret={}):
        printDBG('IPTVPicturePlayerWidget.decodePictureEnd')
        if None == ret.get('Pixmap', None):
            if 0 == self.refreshCount:
                self.session.openWithCallback(self.close,
                                              MessageBox,
                                              _("Decode file [%s] problem.") %
                                              self.filePath,
                                              type=MessageBox.TYPE_ERROR,
                                              timeout=10)
        else:
            self.refreshCount += 1
            self["status"].hide()
            self["console"].hide()
            self["icon"].hide()
            self["picture"].updatePixmap(ret.get('Pixmap', None),
                                         ret.get('FileName', self.filePath))
            self["picture"].show()
        self.setMainTimerSts(False)
        self._doStart()

    def setMainTimerSts(self, start):
        try:
            if start:
                if not self.mainTimerEnabled:
                    self.mainTimer.start(self.mainTimerInterval)
                    self.mainTimerEnabled = True
                    self.updateDisplay()
            else:
                if self.mainTimerEnabled:
                    self.mainTimer.stop()
                    self.mainTimerEnabled = False
        except Exception:
            printExc(
                "IPTVPicturePlayerWidget.setMainTimerSts status[%r] EXCEPTION"
                % start)

    def updateDisplay(self):
        printDBG("updateDisplay")
        if not self.mainTimerEnabled:
            printDBG("updateDisplay aborted - timer stopped")
            return
        self["icon"].nextFrame()
        return

    def _cleanedUp(self):
        for item in self.refreshPostfixes:
            filePath = self.filePath + item
            if fileExists(filePath):
                try:
                    os.remove(filePath)
                except Exception:
                    printDBG('Problem with removing old buffering file')

    def doStart(self):
        self.onShow.remove(self.doStart)
        if not self.onStartCalled:
            self.onStartCalled = True
            self.onStart()
class IPTVPicturePlayerWidget(Screen):
    NUM_OF_ICON_FRAMES = 8
    #######################
    #       SIZES
    #######################
    # screen size
    # we do not want borders, so make the screen lager than a desktop
    sz_w = getDesktop(0).size().width() 
    sz_h = getDesktop(0).size().height()
    # percentage
    s_w = 120
    s_h = 120
    # icon
    i_w = 128
    i_h = 128
    # console
    c_w = sz_w
    c_h = 80
    # picture 
    p_w = sz_w-20
    p_h = sz_h-20
    #######################
    #     POSITIONS
    #######################  
    start_y = (sz_h - (i_h + c_h)) / 2 
    # percentage
    s_x = (sz_w - s_w) / 2
    s_y = start_y + (i_h - s_h) / 2
    # icon
    i_x = (sz_w - i_w) / 2
    i_y = start_y
    # console
    c_x = 0
    c_y = i_y + i_h
    # picture 
    p_x = 10
    p_y = 10
    
    printDBG("[IPTVPicturePlayerWidget] desktop size %dx%d" % (sz_w, sz_h) )
    skin = """
        <screen name="IPTVPicturePlayerWidget"  position="center,center" size="%d,%d" title="IPTV Picture Player...">
         <widget name="status"     size="%d,%d"   position="%d,%d"  zPosition="5" valign="center" halign="center"  font="Regular;21" backgroundColor="black" transparent="1" /> #foregroundColor="white" shadowColor="black" shadowOffset="-1,-1"
         <widget name="console"    size="%d,%d"   position="%d,%d"  zPosition="5" valign="center" halign="center"  font="Regular;21" backgroundColor="black" transparent="1" />
         <widget name="icon"       size="%d,%d"   position="%d,%d"  zPosition="4" transparent="1" alphatest="on" />
         <widget name="picture"    size="%d,%d"   position="%d,%d"  zPosition="6" transparent="1" alphatest="on" />
        </screen>""" %( sz_w, sz_h,         # screen
                        s_w, s_h, s_x, s_y, # status
                        c_w, c_h, c_x, c_y, # console
                        i_w, i_h, i_x, i_y, # icon
                        p_w, p_h, p_x, p_y  # picture
                      )
   
    def __init__(self, session, url, pathForRecordings, pictureTitle):
        self.session = session
        Screen.__init__(self, session)
        self.onStartCalled = False
        
        self.recordingPath = pathForRecordings
        try:
            self.filePath = os.path.join(pathForRecordings, '.iptv_buffering.jpg')
        except:
            self.filePath = ''
            printExc()
            
        self.url           = url
        self.pictureTitle  = pictureTitle
        self.audioUrl      = strwithmeta(url).meta.get("iptv_audio_url", '')
       
        self["actions"] = ActionMap(['IPTVAlternateVideoPlayer', 'MoviePlayerActions', 'MediaPlayerActions', 'WizardActions', 'DirectionActions'],
        {
            'leavePlayer'  : self.key_exit,
            'play'         : self.key_play,
            'pause'        : self.key_pause,
            'exit'         : self.key_exit,
            'back'         : self.key_exit,
            'ok'           : self.key_ok,
        }, -1)     

        self["status"]  = Label()
        self["console"] = Label()
        self["icon"]    = SimpleAnimatedCover()
        self["picture"] = Cover()

        # prepare icon frames path
        frames = []
        for idx in range(1,self.NUM_OF_ICON_FRAMES+1): frames.append( GetIconDir('/buffering/buffering_%d.png' % idx) )
        self["icon"].loadFrames(frames) 
        
        #main Timer
        self.mainTimer = eTimer()
        self.mainTimerEnabled = False
        self.mainTimer_conn = eConnectCallback(self.mainTimer.timeout, self.updateDisplay)
        self.mainTimerInterval = 100 # by default 0,1s
        # download
        self.downloader = DownloaderCreator(self.url)
        
        self.onClose.append(self.__onClose)
        self.onLayoutFinish.append(self.doStart)
        
        self.autoRefresh = False
        self.refreshPostfixes = ['_0', '_1']
        self.refreshCount = 0
        self.refreshing = False
        
        if len(self.audioUrl) and len(config.plugins.iptvplayer.gstplayerpath.value):
            self.audioPlayer = IPTVSimpleAudioPlayer()
        else: self.audioPlayer  = None
       
    #end def __init__(self, session):
    
    def __del__(self):
        printDBG('IPTVPicturePlayerWidget.__del__ --------------------------------------')
        
    def __onClose(self):
        printDBG('IPTVPicturePlayerWidget.__onClose ------------------------------------')
        if None != self.audioPlayer: self.audioPlayer.close()
        self.onEnd()
        self.mainTimer_conn = None
        self.mainTimer = None
        
        self.onClose.remove(self.__onClose)
        self.onLayoutFinish.remove(self.doStart)
        
    def _getDownloadFilePath(self):
        return self.filePath + self.refreshPostfixes[self.refreshCount % len(self.refreshPostfixes) ]
 
    def onStart(self):
        '''
            this method is called once like __init__ but in __init__ we cannot display MessageBox
        '''
        self["picture"].hide()
        self["console"].setText(self.pictureTitle)
        self["status"].setText(_("--"))
        self._cleanedUp()
        if self.downloader:
            self.downloader.isWorkingCorrectly(self._startDownloader)
        else:
            self.session.openWithCallback(self.close, MessageBox, _("Downloading cannot be started.\n Invalid URI[%s].") % self.url, type = MessageBox.TYPE_ERROR, timeout = 10)
            
    def _doStart(self, force=False):
        if self.autoRefresh or force:
            self.refreshing = True
            self.downloader = DownloaderCreator(self.url)
            
            url,downloaderParams = DMHelper.getDownloaderParamFromUrl(self.url)
            self.downloader.subscribeFor_Finish(self.downloaderEnd)
            self.downloader.start(url, self._getDownloadFilePath(), downloaderParams)
            self.setMainTimerSts(True)
        else: self.refreshing = False

    def _startDownloader(self, sts, reason):
        if sts: self._doStart(True)
        else: self.session.openWithCallback(self.close, MessageBox, _("Downloading cannot be started.\n Downloader [%s] not working properly.\n Status[%s]") % (self.downloader.getName(), reason.strip()), type = MessageBox.TYPE_ERROR, timeout = 10 )        
        
    def onEnd(self, withCleanUp=True):
        self.setMainTimerSts(False)
        if self.downloader:
            self.downloader.unsubscribeFor_Finish(self.downloaderEnd)
            downloader = self.downloader
            self.downloader = None
            downloader.terminate()
            downloader = None
        if withCleanUp:
            self._cleanedUp()

    def key_exit(self):
        self.close()
        
    def key_play(self):
        if not self.autoRefresh:
            if None != self.audioPlayer: self.audioPlayer.start(self.audioUrl)
            self.autoRefresh = True
            if not self.refreshing: self._doStart()

    def key_pause(self):
        if self.autoRefresh:
            if None != self.audioPlayer: self.audioPlayer.stop()
            self.autoRefresh = False
        
    def key_ok(self):
        if self.autoRefresh: self.key_pause()
        else: self.key_play()

    def downloaderEnd(self, status):
        if None != self.downloader:
            self.onEnd(False)
            if DMHelper.STS.DOWNLOADED == status:
                self["status"].setText(_("++"))
                self["picture"].decodeCover(self._getDownloadFilePath(), self.decodePictureEnd, ' ')
            else:
                if 0 == self.refreshCount: self.session.openWithCallback(self.close, MessageBox, (_("Downloading file [%s] problem.") % self.url) + (" sts[%r]" % status), type=MessageBox.TYPE_ERROR, timeout=10)
                self._doStart()

    def decodePictureEnd(self, ret={}):
        if None == ret.get('Pixmap', None):
            if 0 == self.refreshCount: self.session.openWithCallback(self.close, MessageBox, _("Downloading file [%s] problem.") % self.filePath, type=MessageBox.TYPE_ERROR, timeout=10)        
        else:
            self.refreshCount += 1
            self["status"].hide()
            self["console"].hide()
            self["icon"].hide()
            self["picture"].updatePixmap(ret.get('Pixmap', None), ret.get('FileName', self.filePath))
            self["picture"].show()
        self.setMainTimerSts(False)
        self._doStart()

    def setMainTimerSts(self, start):
        try:
            if start:
                if not self.mainTimerEnabled:
                    self.mainTimer.start(self.mainTimerInterval)
                    self.mainTimerEnabled = True
                    self.updateDisplay()
            else:
                if self.mainTimerEnabled:
                    self.mainTimer.stop()
                    self.mainTimerEnabled = False
        except:
            printExc("IPTVPicturePlayerWidget.setMainTimerSts status[%r] EXCEPTION" % start)
            
    def updateDisplay(self):
        printDBG("updateDisplay")
        if not self.mainTimerEnabled:
            printDBG("updateDisplay aborted - timer stopped")
            return
        self["icon"].nextFrame()
        return
        
    def _cleanedUp(self):
        for item in self.refreshPostfixes:
            filePath = self.filePath + item
            if fileExists(filePath):
                try: os.remove(filePath)
                except: printDBG('Problem with removing old buffering file')
            
    def doStart(self):
        if not self.onStartCalled:
            self.onStartCalled = True
            self.onStart()
            
class IPTVSubSimpleDownloaderWidget(Screen):
    _TMP_FILE_NAME = '.externaltmpsub'
    sz_w = getDesktop(0).size().width() - 190
    sz_h = getDesktop(0).size().height() - 195
    if sz_h < 500: sz_h += 4
    skin = """
        <screen name="IPTVSubSimpleDownloaderWidget" position="center,center" title="%s" size="%d,%d">
         <widget name="icon_red"    position="5,9"   zPosition="4" size="30,30" transparent="1" alphatest="on" />
         <widget name="icon_green"  position="355,9" zPosition="4" size="30,30" transparent="1" alphatest="on" />
         
         <widget name="label_red"     position="45,9"  size="175,27" zPosition="5" valign="center" halign="left" backgroundColor="black" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
         <widget name="label_green"   position="395,9" size="175,27" zPosition="5" valign="center" halign="left" backgroundColor="black" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
         
         <widget name="list"  position="5,80"  zPosition="2" size="%d,%d" scrollbarMode="showOnDemand" transparent="1"  backgroundColor="#00000000" enableWrapAround="1" />
         <widget name="title" position="5,47"  zPosition="1" size="%d,23" font="Regular;20"            transparent="1"  backgroundColor="#00000000"/>
         
         <widget name="console"      position="10,%d"   zPosition="2" size="%d,160" valign="center" halign="center"   font="Regular;24" transparent="0" foregroundColor="white" backgroundColor="black"/>
        </screen>""" % (
        _("Simple subtitles downloader"),
        sz_w,
        sz_h,  # size
        sz_w - 10,
        sz_h - 105,  # size list
        sz_w - 135,  # size title
        (sz_h - 160) / 2,
        sz_w - 20,  # console
    )

    def __init__(self, session, params={}):
        # params: movie_title, sub_list: [{'title':'', 'lang':'', 'url':''}]
        self.session = session
        Screen.__init__(self, session)

        self.params = params

        self.onShown.append(self.onStart)
        self.onClose.append(self.__onClose)

        self["title"] = Label(" ")
        self["console"] = Label(" ")

        self["label_red"] = Label(_("Cancel"))
        self["label_yellow"] = Label(_("Move group"))
        self["label_green"] = Label(_("Apply"))

        self["icon_red"] = Cover3()
        self["icon_green"] = Cover3()

        self["list"] = IPTVMainNavigatorList()
        self["list"].connectSelChanged(self.onSelectionChanged)

        self["actions"] = ActionMap(
            [
                "ColorActions", "SetupActions", "WizardActions",
                "ListboxActions"
            ], {
                "cancel": self.keyExit,
                "ok": self.keyOK,
                "red": self.keyRed,
                "green": self.keyGreen,
            }, -2)

        self.iconPixmap = {}
        for icon in ['red', 'green']:
            self.iconPixmap[icon] = LoadPixmap(GetIconDir(icon + '.png'))

        self.movieTitle = ''
        self.stackList = []
        self.stackItems = []

        self.defaultLanguage = GetDefaultLang()

        self.listMode = False
        self.downloadedSubFilePath = ""
        self.currItem = {}
        self.downloader = None
        self.cleanDownloader()
        self.workconsole = None

    def __onClose(self):
        self["list"].disconnectSelChanged(self.onSelectionChanged)
        if None != self.workconsole:
            self.workconsole.kill()
        self.workconsole = None
        self.cleanDownloader()

    def cleanDownloader(self):
        self.downloadedSubFilePath = ""
        self.currItem = {}
        if self.downloader != None:
            self.downloader.unsubscribeFor_Finish(self.downloadFinished)
            self.downloader.terminate()
        self.downloader = None

    def startDownload(self, item):
        self.setListMode(False)
        self.cleanDownloader()
        self.currItem = item
        self["console"].setText(
            _("Downloading subtitles.\n ('%r').") %
            self.currItem.get('url', ''))
        # create downloader
        self.downloader = DownloaderCreator(self.currItem.get('url', ''))
        if self.downloader:
            self.downloader.isWorkingCorrectly(self._startDownloader)
        else:
            self["console"].setText(
                _("Download can not be started.\n Incorrect address ('%r')."))

    def _startDownloader(self, sts, reason):
        if sts:
            self.downloader.subscribeFor_Finish(self.downloadFinished)
            url, downloaderParams = DMHelper.getDownloaderParamFromUrl(
                self.currItem.get('url', ''))
            self.downloader.start(url, GetTmpDir(self._TMP_FILE_NAME),
                                  downloaderParams)
        else:
            self["console"].setText(
                _("Download can not be started.\nDownloader %s not working correctly.\nStatus[%s]"
                  ))

    def downloadFinished(self, status):
        if status != DMHelper.STS.DOWNLOADED:
            self["console"].setText(_("Download failed.\nStatus[%s]") % status)
        else:
            self["console"].setText(
                _('Subtitles downloaded successfully. [%s], conversion to UTF-8.'
                  ) % self.downloader.getFullFileName())
            cmd = '%s "%s"' % (config.plugins.iptvplayer.uchardetpath.value,
                               self.downloader.getFullFileName())
            printDBG("cmd[%s]" % cmd)
            self.workconsole = iptv_system(cmd, self.convertSubtitles)

    def convertSubtitles(self, code=127, encoding=""):
        encoding = MapUcharEncoding(encoding)
        if 0 != code or 'unknown' in encoding:
            encoding = 'utf-8'
        else:
            encoding = encoding.strip()
        try:
            with codecs.open(self.downloader.getFullFileName(), 'r', encoding,
                             'replace') as fp:
                subText = fp.read().encode('utf-8').strip()

            ext = self.currItem.get('format', '')
            if ext == '':
                ext = self.currItem.get('url',
                                        '').split('?')[-1].split('.')[-1]
            filePath = '{0}_{1}_{2}'.format(self.params['movie_title'],
                                            self.currItem.get('title', ''),
                                            self.currItem.get('lang', ''))
            filePath = RemoveDisallowedFilenameChars(filePath)
            filePath += '.' + ext

            with open(GetSubtitlesDir(filePath), 'w') as fp:
                fp.write(subText)

            self.downloadedSubFilePath = GetSubtitlesDir(filePath)
            self.showButtons(['green'])
            tmpList = self.params.get('sub_list', [])
            if len(tmpList) == 1:
                self.acceptSub()
        except Exception:
            printExc()
            self["console"].setText(_('Subtitles conversion to UTF-8 failed.'))

    def loadIcons(self):
        try:
            for icon in self.iconPixmap:
                self['icon_' + icon].setPixmap(self.iconPixmap[icon])
        except Exception:
            printExc()

    def hideButtons(self, buttons=['red', 'green']):
        try:
            for button in buttons:
                self['icon_' + button].hide()
                self['label_' + button].hide()
        except Exception:
            printExc()

    def showButtons(self, buttons=['red', 'green']):
        try:
            for button in buttons:
                self['icon_' + button].show()
                self['label_' + button].show()
        except Exception:
            printExc()

    def onStart(self):
        self.onShown.remove(self.onStart)
        self.setTitle(
            _("Subtitles for: %s") % self.params.get('movie_title', ''))
        self.loadIcons()
        tmpList = self.params.get('sub_list', [])
        if len(tmpList) > 1:
            self.displayList()
        else:
            self.startDownload(tmpList[0])

    def setListMode(self, sts=False):
        if False == sts:
            self['list'].hide()
            self["title"].hide()
            self.hideButtons()
            self.showButtons(['red'])
            self["console"].show()
            self["console"].setText(" ")
        else:
            self.hideButtons(['green'])
            self["console"].hide()
            self["console"].setText(" ")

        self.listMode = sts

    def displayList(self):
        list = []
        self["title"].setText(_("Select subtitles to download"))
        self["title"].show()

        tmpList = self.params.get('sub_list', [])
        try:
            for item in tmpList:
                printDBG(item)
                dItem = CDisplayListItem(name=item['title'],
                                         type=CDisplayListItem.TYPE_ARTICLE)
                dItem.privateData = item
                list.append((dItem, ))
        except Exception:
            printExc()
        self["list"].setList(list)
        self["list"].show()
        self.setListMode(True)

    def onSelectionChanged(self):
        pass

    def keyExit(self):
        if False == self.listMode:
            if self.downloader != None and self.downloader.isDownloading():
                self.downloader.terminate()
            else:
                tmpList = self.params.get('sub_list', [])
                if len(tmpList) > 1:
                    self.displayList()
                else:
                    self.close(None)
        else:
            self.close(None)

    def keyOK(self):
        if False == self.listMode: return
        idx, item = self.getSelectedItem()
        if None != item:
            self.startDownload(item.privateData)

    def keyRed(self):
        self.close(None)

    def keyGreen(self):
        self.acceptSub()

    def acceptSub(self):
        try:
            if self["icon_green"].visible:
                track = {
                    'title': self.currItem.get('lang', _('default')),
                    'lang': self.currItem.get('lang', _('default')),
                    'path': self.downloadedSubFilePath
                }
                track['id'] = self.currItem.get('url', '')
                self.close(track)
        except Exception:
            printExc()

    def getSelectedItem(self):
        try:
            idx = self["list"].getCurrentIndex()
        except Exception:
            idx = 0
        sel = None
        try:
            if self["list"].visible:
                sel = self["list"].l.getCurrentSelection()[0]
                if None != sel:
                    return idx, sel
        except Exception:
            printExc()
            sel = None
        return -1, None
class IPTVSubSimpleDownloaderWidget(Screen):
    _TMP_FILE_NAME='.externaltmpsub'
    sz_w = getDesktop(0).size().width() - 190
    sz_h = getDesktop(0).size().height() - 195
    if sz_h < 500: sz_h += 4
    skin = """
        <screen name="IPTVSubSimpleDownloaderWidget" position="center,center" title="%s" size="%d,%d">
         <widget name="icon_red"    position="5,9"   zPosition="4" size="30,30" transparent="1" alphatest="on" />
         <widget name="icon_green"  position="355,9" zPosition="4" size="30,30" transparent="1" alphatest="on" />
         
         <widget name="label_red"     position="45,9"  size="175,27" zPosition="5" valign="center" halign="left" backgroundColor="black" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
         <widget name="label_green"   position="395,9" size="175,27" zPosition="5" valign="center" halign="left" backgroundColor="black" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
         
         <widget name="list"  position="5,80"  zPosition="2" size="%d,%d" scrollbarMode="showOnDemand" transparent="1"  backgroundColor="#00000000" enableWrapAround="1" />
         <widget name="title" position="5,47"  zPosition="1" size="%d,23" font="Regular;20"            transparent="1"  backgroundColor="#00000000"/>
         
         <widget name="console"      position="10,%d"   zPosition="2" size="%d,160" valign="center" halign="center"   font="Regular;24" transparent="0" foregroundColor="white" backgroundColor="black"/>
        </screen>""" %(
            _("Simple subtitles downloader"),
            sz_w, sz_h, # size
            sz_w - 10, sz_h - 105, # size list
            sz_w - 135, # size title
            (sz_h - 160)/2, sz_w - 20, # console
            )
    
    def __init__(self, session, params={}):
        # params: movie_title, sub_list: [{'title':'', 'lang':'', 'url':''}]
        self.session = session
        Screen.__init__(self, session)
        
        self.params = params
        
        self.onShown.append(self.onStart)
        self.onClose.append(self.__onClose)
        
        self["title"]         = Label(" ")
        self["console"]       = Label(" ")
        
        self["label_red"]     = Label(_("Cancel"))
        self["label_yellow"]  = Label(_("Move group"))
        self["label_green"]   = Label(_("Apply"))
        
        self["icon_red"]     = Cover3()
        self["icon_green"]   = Cover3()
        
        self["list"] = IPTVMainNavigatorList()
        self["list"].connectSelChanged(self.onSelectionChanged)
        
        self["actions"] = ActionMap(["ColorActions", "SetupActions", "WizardActions", "ListboxActions"],
            {
                "cancel": self.keyExit,
                "ok"    : self.keyOK,
                "red"   : self.keyRed,
                "green" : self.keyGreen,
            }, -2)
        
        self.iconPixmap = {}
        for icon in ['red', 'green']:
            self.iconPixmap[icon] = LoadPixmap(GetIconDir(icon+'.png'))
            
        self.movieTitle = ''
        self.stackList  = []
        self.stackItems = []
        
        self.defaultLanguage = GetDefaultLang()
    
        self.listMode = False
        self.downloadedSubFilePath = ""
        self.currItem = {}
        self.downloader = None
        self.cleanDownloader()
        self.workconsole = None
        
    def __onClose(self):
        self["list"].disconnectSelChanged(self.onSelectionChanged)
        if None != self.workconsole:
            self.workconsole.kill()
        self.workconsole = None
        self.cleanDownloader()
        
    def cleanDownloader(self):
        self.downloadedSubFilePath = ""
        self.currItem = {}
        if self.downloader != None:
            self.downloader.unsubscribeFor_Finish(self.downloadFinished)
            self.downloader.terminate()
        self.downloader = None
        
    def startDownload(self, item):
        self.setListMode(False)
        self.cleanDownloader()
        self.currItem = item
        self["console"].setText(_("Downloading subtitles.\n ('%r').") % self.currItem.get('url', ''))
        # create downloader
        self.downloader = DownloaderCreator(self.currItem.get('url', ''))
        if self.downloader:
            self.downloader.isWorkingCorrectly(self._startDownloader)
        else:
            self["console"].setText(_("Download can not be started.\n Incorrect address ('%r')."))

    def _startDownloader(self, sts, reason):
        if sts:
            self.downloader.subscribeFor_Finish(self.downloadFinished)
            url,downloaderParams = DMHelper.getDownloaderParamFromUrl(self.currItem.get('url', ''))
            self.downloader.start(url, GetTmpDir(self._TMP_FILE_NAME), downloaderParams)
        else:
            self["console"].setText(_("Download can not be started.\nDownloader %s not working correctly.\nStatus[%s]"))
        
    def downloadFinished(self, status):
        if status != DMHelper.STS.DOWNLOADED:
            self["console"].setText(_("Download failed.\nStatus[%s]") % status)
        else:
            self["console"].setText(_('Subtitles downloaded successfully. [%s], conversion to UTF-8.') % self.downloader.getFullFileName())
            cmd = '%s "%s"' % (config.plugins.iptvplayer.uchardetpath.value, self.downloader.getFullFileName()) 
            printDBG("cmd[%s]" % cmd)
            self.workconsole = iptv_system(cmd, self.convertSubtitles)
    
    def convertSubtitles(self, code=127, encoding=""):
        if 0 != code or 'unknown' in encoding:
            encoding = 'utf-8'
        else:
            encoding = encoding.strip()
        try:
            with codecs.open(self.downloader.getFullFileName(), 'r', encoding, 'replace') as fp:
                subText = fp.read().encode('utf-8')
            
            ext = self.currItem.get('format', '')
            if ext == '':
                ext = self.currItem.get('url', '').split('?')[-1].split('.')[-1]
            filePath = '{0}_{1}_{2}'.format(self.params['movie_title'], self.currItem.get('title', ''), self.currItem.get('lang', ''))
            filePath = RemoveDisallowedFilenameChars(filePath)
            filePath += '.' + ext
            
            with open(GetSubtitlesDir(filePath), 'w') as fp:
                fp.write(subText)

            self.downloadedSubFilePath = GetSubtitlesDir(filePath)
            self.showButtons(['green'])
            tmpList = self.params.get('sub_list', [])
            if len(tmpList) == 1:
                self.acceptSub()
        except:
            printExc()
            self["console"].setText(_('Subtitles conversion to UTF-8 failed.'))
    
    def loadIcons(self):
        try:
            for icon in self.iconPixmap:
                self['icon_'+icon].setPixmap(self.iconPixmap[icon])
        except: printExc()
        
    def hideButtons(self, buttons=['red', 'green']):
        try:
            for button in buttons:
                self['icon_'+button].hide()
                self['label_'+button].hide()
        except: printExc()
        
    def showButtons(self, buttons=['red', 'green']):
        try:
            for button in buttons:
                self['icon_'+button].show()
                self['label_'+button].show()
        except: printExc()
    
    def onStart(self):
        self.onShown.remove(self.onStart)
        self.setTitle( _("Subtitles for: %s") % self.params.get('movie_title', '') )
        self.loadIcons()
        tmpList = self.params.get('sub_list', [])
        if len(tmpList) > 1:
            self.displayList()
        else:   
            self.startDownload(tmpList[0])
    
    def setListMode(self, sts=False):
        if False == sts:
            self['list'].hide()
            self["title"].hide()
            self.hideButtons()
            self.showButtons(['red'])
            self["console"].show()
            self["console"].setText(" ")
        else:
            self.hideButtons(['green'])
            self["console"].hide()
            self["console"].setText(" ")
            
        self.listMode = sts
    
    def displayList(self):
        list = []
        self["title"].setText(_("Select subtitles to download"))
        self["title"].show()
        
        tmpList = self.params.get('sub_list', [])
        try:
            for item in tmpList:
                printDBG(item)
                dItem = CDisplayListItem(name = item['title'], type=CDisplayListItem.TYPE_ARTICLE)
                dItem.privateData = item
                list.append( (dItem,) )
        except: 
            printExc()
        self["list"].setList(list)
        self["list"].show()
        self.setListMode(True)
        
    def onSelectionChanged(self):
        pass
        
    def keyExit(self):
        if False == self.listMode:
            if self.downloader != None and self.downloader.isDownloading():
                self.downloader.terminate()
            else:
                tmpList = self.params.get('sub_list', [])
                if len(tmpList) > 1:
                    self.displayList()
                else:
                    self.close(None)
        else:
            self.close(None)
            
    def keyOK(self):
        if False == self.listMode: return
        idx, item = self.getSelectedItem()
        if None != item:
            self.startDownload(item.privateData)
            
    def keyRed(self):
        self.close(None)
        
    def keyGreen(self):
        self.acceptSub()
    
    def acceptSub(self):
        try: 
            if self["icon_green"].visible:
                track = {'title':self.currItem.get('lang', _('default')), 'lang':self.currItem.get('lang', _('default')), 'path':self.downloadedSubFilePath}
                track['id'] = self.currItem.get('url', '')
                self.close(track)
        except: printExc()
    
    def getSelectedItem(self):
        try: idx = self["list"].getCurrentIndex()
        except: idx = 0
        sel = None
        try: 
            if self["list"].visible:
                sel = self["list"].l.getCurrentSelection()[0]
                if None != sel:
                    return idx, sel
        except: 
            printExc()
            sel = None
        return -1, None