Beispiel #1
0
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