class CharJump(object): def __init__(self, session, char=u'ABCDEFGHIJKLMNOPQRSTUVWXYZ'): rcinput = eRCInput.getInstance() rcinput.setKeyboardMode(rcinput.kmAscii) self.numericalTextInput = NumericalTextInput() self.numericalTextInput.setUseableChars(char) self["NumberActions"] = NumberActionMap( ["NumberActions", "InputAsciiActions"], { "gotAsciiCode": self._keyAsciiCode, "1": self._keyNumberGlobal, "2": self._keyNumberGlobal, "3": self._keyNumberGlobal, "4": self._keyNumberGlobal, "5": self._keyNumberGlobal, "6": self._keyNumberGlobal, "7": self._keyNumberGlobal, "8": self._keyNumberGlobal, "9": self._keyNumberGlobal, "0": self._onKey0 }, -1) self.onClose.append(self.__onClose) def __onClose(self): rcinput = eRCInput.getInstance() rcinput.setKeyboardMode(rcinput.kmNone) def _onKey0(self, unused): Log.w() pass def _getFirstForChar(self): raise NotImplementedError def _keyAsciiCode(self): unichar = unichr(getPrevAsciiCode()) charstr = unichar.encode("utf-8") if len(charstr): if charstr[0] == "0": self.__KeyNull(0) else: self._getFirstForChar(charstr[0].upper()) def _keyNumberGlobal(self, number): unichar = self.numericalTextInput.getKey(number) if unichar is not None: charstr = unichar.encode("utf-8") if len(charstr): if charstr[0] == "0": self.__KeyNull(0) else: self._getFirstForChar(charstr[0])
class ChannelSelectionBase(Screen): def __init__(self, session): Screen.__init__(self, session) self["key_red"] = Button(_("All")) self["key_green"] = Button(_("Satellites")) self["key_yellow"] = Button(_("Provider")) self["key_blue"] = Button(_("Favourites")) #+++> TDT self["boquet"] = Label(_("Channel Selection")) #<+++ TDT self["list"] = ServiceList() self.servicelist = self["list"] self.numericalTextInput = NumericalTextInput() self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ') self.servicePathTV = [ ] self.servicePathRadio = [ ] self.servicePath = [ ] self.mode = MODE_TV self.pathChangeDisabled = False self.bouquetNumOffsetCache = { } self["ChannelSelectBaseActions"] = NumberActionMap(["ChannelSelectBaseActions", "NumberActions", "InputAsciiActions"], { "showFavourites": self.showFavourites, "showAllServices": self.showAllServices, "showProviders": self.showProviders, "showSatellites": self.showSatellites, "nextBouquet": self.nextBouquet, "prevBouquet": self.prevBouquet, "nextMarker": self.nextMarker, "prevMarker": self.prevMarker, "gotAsciiCode": self.keyAsciiCode, "1": self.keyNumberGlobal, "2": self.keyNumberGlobal, "3": self.keyNumberGlobal, "4": self.keyNumberGlobal, "5": self.keyNumberGlobal, "6": self.keyNumberGlobal, "7": self.keyNumberGlobal, "8": self.keyNumberGlobal, "9": self.keyNumberGlobal, "0": self.keyNumber0 }) self.recallBouquetMode() def getBouquetNumOffset(self, bouquet): if not config.usage.multibouquet.value: return 0 str = bouquet.toString() offsetCount = 0 if not self.bouquetNumOffsetCache.has_key(str): serviceHandler = eServiceCenter.getInstance() bouquetlist = serviceHandler.list(self.bouquet_root) if not bouquetlist is None: while True: bouquetIterator = bouquetlist.getNext() if not bouquetIterator.valid(): #end of list break self.bouquetNumOffsetCache[bouquetIterator.toString()]=offsetCount if not (bouquetIterator.flags & eServiceReference.isDirectory): continue servicelist = serviceHandler.list(bouquetIterator) if not servicelist is None: while True: serviceIterator = servicelist.getNext() if not serviceIterator.valid(): #check if end of list break playable = not (serviceIterator.flags & (eServiceReference.isDirectory|eServiceReference.isMarker)) if playable: offsetCount += 1 return self.bouquetNumOffsetCache.get(str, offsetCount) def recallBouquetMode(self): if self.mode == MODE_TV: self.service_types = service_types_tv if config.usage.multibouquet.value: self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.tv" ORDER BY bouquet' else: self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.tv" ORDER BY bouquet'%(self.service_types) else: self.service_types = service_types_radio if config.usage.multibouquet.value: self.bouquet_rootstr = '1:7:1:0:0:0:0:0:0:0:FROM BOUQUET "bouquets.radio" ORDER BY bouquet' else: self.bouquet_rootstr = '%s FROM BOUQUET "userbouquet.favourites.radio" ORDER BY bouquet'%(self.service_types) self.bouquet_root = eServiceReference(self.bouquet_rootstr) def setTvMode(self): self.mode = MODE_TV self.servicePath = self.servicePathTV self.recallBouquetMode() title = self.instance.getTitle() pos = title.find(" (") if pos != -1: title = title[:pos] title += " (TV)" self.setTitle(title) def setRadioMode(self): self.mode = MODE_RADIO self.servicePath = self.servicePathRadio self.recallBouquetMode() title = self.instance.getTitle() pos = title.find(" (") if pos != -1: title = title[:pos] title += " (Radio)" self.setTitle(title) def setRoot(self, root, justSet=False): path = root.getPath() inBouquetRootList = path.find('FROM BOUQUET "bouquets.') != -1 #FIXME HACK pos = path.find('FROM BOUQUET') isBouquet = (pos != -1) and (root.flags & eServiceReference.isDirectory) if not inBouquetRootList and isBouquet: self.servicelist.setMode(ServiceList.MODE_FAVOURITES) self.servicelist.setNumberOffset(self.getBouquetNumOffset(root)) else: self.servicelist.setMode(ServiceList.MODE_NORMAL) self.servicelist.setRoot(root, justSet) self.buildTitleString() def removeModeStr(self, str): if self.mode == MODE_TV: pos = str.find(' (TV)') else: pos = str.find(' (Radio)') if pos != -1: return str[:pos] return str def getServiceName(self, ref): str = self.removeModeStr(ServiceReference(ref).getServiceName()) if not str: pathstr = ref.getPath() if 'FROM PROVIDERS' in pathstr: return _("Provider") if 'FROM SATELLITES' in pathstr: return _("Satellites") if ') ORDER BY name' in pathstr: return _("All") return str def buildTitleString(self): titleStr = self.instance.getTitle() pos = titleStr.find(']') if pos == -1: pos = titleStr.find(')') if pos != -1: titleStr = titleStr[:pos+1] Len = len(self.servicePath) if Len > 0: base_ref = self.servicePath[0] if Len > 1: end_ref = self.servicePath[Len-1] else: end_ref = None nameStr = self.getServiceName(base_ref) titleStr += ' ' + nameStr #+++> TDT self["boquet"].setText("Channel Selection") #<+++ TDT if end_ref is not None: if Len > 2: titleStr += '/../' else: titleStr += '/' nameStr = self.getServiceName(end_ref) titleStr += nameStr #+++> TDT self["boquet"].setText(nameStr) #<+++ TDT self.setTitle(titleStr) def moveUp(self): self.servicelist.moveUp() def moveDown(self): self.servicelist.moveDown() def clearPath(self): del self.servicePath[:] def enterPath(self, ref, justSet=False): self.servicePath.append(ref) self.setRoot(ref, justSet) def pathUp(self, justSet=False): prev = self.servicePath.pop() if self.servicePath: current = self.servicePath[-1] self.setRoot(current, justSet) if not justSet: self.setCurrentSelection(prev) return prev def isBasePathEqual(self, ref): if len(self.servicePath) > 1 and self.servicePath[0] == ref: return True return False def isPrevPathEqual(self, ref): length = len(self.servicePath) if length > 1 and self.servicePath[length-2] == ref: return True return False def preEnterPath(self, refstr): return False def showAllServices(self): if not self.pathChangeDisabled: refstr = '%s ORDER BY name'%(self.service_types) if not self.preEnterPath(refstr): ref = eServiceReference(refstr) currentRoot = self.getRoot() if currentRoot is None or currentRoot != ref: self.clearPath() self.enterPath(ref) def showSatellites(self): if not self.pathChangeDisabled: refstr = '%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types) if not self.preEnterPath(refstr): ref = eServiceReference(refstr) justSet=False prev = None if self.isBasePathEqual(ref): if self.isPrevPathEqual(ref): justSet=True prev = self.pathUp(justSet) else: currentRoot = self.getRoot() if currentRoot is None or currentRoot != ref: justSet=True self.clearPath() self.enterPath(ref, True) if justSet: serviceHandler = eServiceCenter.getInstance() servicelist = serviceHandler.list(ref) if not servicelist is None: while True: service = servicelist.getNext() if not service.valid(): #check if end of list break unsigned_orbpos = service.getUnsignedData(4) >> 16 orbpos = service.getData(4) >> 16 if orbpos < 0: orbpos += 3600 if service.getPath().find("FROM PROVIDER") != -1: service_type = _("Providers") elif service.getPath().find("flags == %d" %(FLAG_SERVICE_NEW_FOUND)) != -1: service_type = _("New") else: service_type = _("Services") try: # why we need this cast? service_name = str(nimmanager.getSatDescription(orbpos)) except: if unsigned_orbpos == 0xFFFF: #Cable service_name = _("Cable") elif unsigned_orbpos == 0xEEEE: #Terrestrial service_name = _("Terrestrial") else: if orbpos > 1800: # west orbpos = 3600 - orbpos h = _("W") else: h = _("E") service_name = ("%d.%d" + h) % (orbpos / 10, orbpos % 10) service.setName("%s - %s" % (service_name, service_type)) self.servicelist.addService(service) cur_ref = self.session.nav.getCurrentlyPlayingServiceReference() if cur_ref: pos = self.service_types.rfind(':') refstr = '%s (channelID == %08x%04x%04x) && %s ORDER BY name' %(self.service_types[:pos+1], cur_ref.getUnsignedData(4), # NAMESPACE cur_ref.getUnsignedData(2), # TSID cur_ref.getUnsignedData(3), # ONID self.service_types[pos+1:]) ref = eServiceReference(refstr) ref.setName(_("Current Transponder")) self.servicelist.addService(ref) self.servicelist.finishFill() if prev is not None: self.setCurrentSelection(prev) def showProviders(self): if not self.pathChangeDisabled: refstr = '%s FROM PROVIDERS ORDER BY name'%(self.service_types) if not self.preEnterPath(refstr): ref = eServiceReference(refstr) if self.isBasePathEqual(ref): self.pathUp() else: currentRoot = self.getRoot() if currentRoot is None or currentRoot != ref: self.clearPath() self.enterPath(ref) def changeBouquet(self, direction): if not self.pathChangeDisabled: if len(self.servicePath) > 1: #when enter satellite root list we must do some magic stuff.. ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)) if self.isBasePathEqual(ref): self.showSatellites() else: self.pathUp() if direction < 0: self.moveUp() else: self.moveDown() ref = self.getCurrentSelection() self.enterPath(ref) def inBouquet(self): if self.servicePath and self.servicePath[0] == self.bouquet_root: return True return False def atBegin(self): return self.servicelist.atBegin() def atEnd(self): return self.servicelist.atEnd() def nextBouquet(self): self.changeBouquet(+1) def prevBouquet(self): self.changeBouquet(-1) def showFavourites(self): if not self.pathChangeDisabled: if not self.preEnterPath(self.bouquet_rootstr): if self.isBasePathEqual(self.bouquet_root): self.pathUp() else: currentRoot = self.getRoot() if currentRoot is None or currentRoot != self.bouquet_root: self.clearPath() self.enterPath(self.bouquet_root) def keyNumberGlobal(self, number): unichar = self.numericalTextInput.getKey(number) charstr = unichar.encode("utf-8") if len(charstr) == 1: self.servicelist.moveToChar(charstr[0]) def keyAsciiCode(self): unichar = unichr(getPrevAsciiCode()) charstr = unichar.encode("utf-8") if len(charstr) == 1: self.servicelist.moveToChar(charstr[0]) def getRoot(self): return self.servicelist.getRoot() def getCurrentSelection(self): return self.servicelist.getCurrent() def setCurrentSelection(self, service): self.servicelist.setCurrent(service) def getBouquetList(self): bouquets = [ ] serviceHandler = eServiceCenter.getInstance() if config.usage.multibouquet.value: list = serviceHandler.list(self.bouquet_root) if list: while True: s = list.getNext() if not s.valid(): break if s.flags & eServiceReference.isDirectory: info = serviceHandler.info(s) if info: bouquets.append((info.getName(s), s)) return bouquets else: info = serviceHandler.info(self.bouquet_root) if info: bouquets.append((info.getName(self.bouquet_root), self.bouquet_root)) return bouquets return None def keyNumber0(self, num): if len(self.servicePath) > 1: self.keyGoUp() else: self.keyNumberGlobal(num) def keyGoUp(self): if len(self.servicePath) > 1: if self.isBasePathEqual(self.bouquet_root): self.showFavourites() else: ref = eServiceReference('%s FROM SATELLITES ORDER BY satellitePosition'%(self.service_types)) if self.isBasePathEqual(ref): self.showSatellites() else: ref = eServiceReference('%s FROM PROVIDERS ORDER BY name'%(self.service_types)) if self.isBasePathEqual(ref): self.showProviders() else: self.showAllServices() def nextMarker(self): self.servicelist.moveToNextMarker() def prevMarker(self): self.servicelist.moveToPrevMarker()
class RadioScreen(Screen, ServiceStopScreen, InfoBarServiceErrorPopupSupport, InfoBarGstreamerErrorPopupSupport): def __init__(self, session): Screen.__init__(self, session, windowTitle=_("Radio")) self.skinName = "SimpleRadioScreen" ServiceStopScreen.__init__(self) self.stopService() self._list = List([], buildfunc=self._buildFunc) self._serviceLabel = Label("") InfoBarServiceErrorPopupSupport.__init__(self) InfoBarGstreamerErrorPopupSupport.__init__(self) self._service = None self.numericalTextInput = NumericalTextInput() self.numericalTextInput.setUseableChars(u'1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ') self["attribution"] = Label(_("powered by www.radio-browser.info")) self["country"] = StaticText("") self["list"] = self._list self["service"] = self._serviceLabel self["actions"] = NumberActionMap(["OkCancelActions", "NumberActions", "ColorActions"], { "ok": self._onOk , "cancel" : self.close, "blue" : self._onBlue, "1": self._onKeyChar, "2": self._onKeyChar, "3": self._onKeyChar, "4": self._onKeyChar, "5": self._onKeyChar, "6": self._onKeyChar, "7": self._onKeyChar, "8": self._onKeyChar, "9": self._onKeyChar, "0": self._onKeyChar }, -1) self._country = config.plugins.simpleradio.country.value self._browser = RadioBrowserClient() self._onLoadFinished({}) self._browser.stations(self._country.lower(), self._onLoadFinished) self["country"].setText(_(self._country.capitalize())) self._browser.countries(self._onCountriesReady) self._stateInfo = self.session.instantiateDialog(InfoBarStateInfo,zPosition=50) self._infoBarStateInfo = InfoBarServiceErrorPopupSupport._stateInfo InfoBarServiceErrorPopupSupport._stateInfo = self._stateInfo self.onClose.append(self.__onClose) def __onClose(self): InfoBarServiceErrorPopupSupport._stateInfo = self._infoBarStateInfo @property def list(self): return self._list.list def _buildFunc(self, station): return [station.name, station.country, station.clickcount, station.bitrate] def _onCountriesReady(self, countries): self._countries = countries def _onBlue(self): if self._countries: self._selectCountry() def _selectCountry(self): if not self._countries: return countries = [("{} ({})".format(_(c.name), c.stationCount), c) for c in self._countries] choices = sorted(countries, key=lambda x: x[0]) self.session.openWithCallback(self._onCountrySelected, ChoiceBox, list=choices, windowTitle=_("Select a country")) def _onCountrySelected(self, country): country = country and country[1] if country: config.plugins.simpleradio.country.value = country.name config.plugins.simpleradio.save() self._country = country.name self._onLoadFinished({}) self._browser.stations(country.name.lower(), self._onLoadFinished) self["country"].setText(_(country.name.capitalize())) def _onLoadFinished(self, stations): lst = [] keys = sorted(stations.keys(), key=lambda x: str(x).lower()) for key in keys: station = stations[key] lst.append((station,)) self._list.list = lst def _onOk(self): station = self._list.getCurrent() station = station and station[0] if station: ref = eServiceReference(eServiceReference.idGST, eServiceReference.isLive, station.urlsResolved[0]) ref.setName(station.name) self._play(ref) def _play(self, service): self._stop() self._service = service self.session.nav.playService(service) self._serviceLabel.setText(self._service.getName()) def _stop(self): self._serviceLabel.setText(_("Please pick a radio stream...")) self._service = None self.session.nav.stopService() def _onKeyChar(self, number): unichar = self.numericalTextInput.getKey(number) charstr = unichar.encode("utf-8") if len(charstr) != 1: return index = 0 for s in self.list: if s[0].name.upper().startswith(charstr): self._list.index = index break index += 1