class AutomaticVolumeAdjustmentConfig(): def __init__(self): self.CONFIG_FILE = eEnv.resolve('${sysconfdir}/enigma2/ava_setup.cfg') # load config file self.loadConfigFile() # load config file and initialize def loadConfigFile(self): print("[AutomaticVolumeAdjustmentConfig] Loading config file...") self.config = Config() if not os_path.exists(self.CONFIG_FILE): try: fd = os_open(self.CONFIG_FILE, os_O_RDWR | os_O_CREAT) os_close(fd) except Exception as e: print("Error: ", e) try: self.config.loadFromFile(self.CONFIG_FILE) except Exception as e: print("Error: ", e) self.config.entriescount = ConfigInteger(0) self.config.Entries = ConfigSubList() self.config.enable = ConfigYesNo(default=False) self.config.modus = ConfigSelection(choices=[("0", _("Automatic volume adjust")), ("1", _("Remember service volume value"))], default="0") self.config.adustvalue = ConfigSelectionNumber(-50, 50, 5, default=25) self.config.mpeg_max_volume = ConfigSelectionNumber(10, 100, 5, default=100) self.config.show_volumebar = ConfigYesNo(default=False) self.config.type_audio = ConfigYesNo(default=True) self.initConfig() def initConfig(self): count = self.config.entriescount.value if count != 0: i = 0 while i < count: self.initEntryConfig() i += 1 print("[AutomaticVolumeAdjustmentConfig] Loaded %s entries from config file..." % count) def initEntryConfig(self): self.config.Entries.append(ConfigSubsection()) i = len(self.config.Entries) - 1 self.config.Entries[i].servicereference = ConfigText(default="") self.config.Entries[i].name = NoSave(ConfigDirectory(default=_("Press OK to select a service"))) self.config.Entries[i].adjustvalue = ConfigSelectionNumber(-50, 50, 5, default=25) return self.config.Entries[i] def remove(self, configItem): self.config.entriescount.value = self.config.entriescount.value - 1 self.config.entriescount.save() self.config.Entries.remove(configItem) self.config.Entries.save() self.save() def save(self): print("[AutomaticVolumeAdjustmentConfig] saving config file...") self.config.saveToFile(self.CONFIG_FILE)
class AutomaticVolumeAdjustmentConfig(): def __init__(self): self.CONFIG_FILE = '/usr/lib/enigma2/python/Plugins/SystemPlugins/AutomaticVolumeAdjustment/config' # load config file self.loadConfigFile() # load config file and initialize def loadConfigFile(self): print "[AutomaticVolumeAdjustmentConfig] Loading config file..." self.config = Config() if not os_path.exists(self.CONFIG_FILE): fd = os_open( self.CONFIG_FILE, os_O_RDWR|os_O_CREAT) os_close( fd ) self.config.loadFromFile(self.CONFIG_FILE) self.config.entriescount = ConfigInteger(0) self.config.Entries = ConfigSubList() self.config.enable = ConfigYesNo(default = False) self.config.modus = ConfigSelection(choices = [("0", _("Automatic volume adjust")), ("1", _("Remember service volume value"))], default = "0") self.config.adustvalue = ConfigSelectionNumber(-50, 50, 5, default = 25) self.config.mpeg_max_volume = ConfigSelectionNumber(10, 100, 5, default = 100) self.config.show_volumebar = ConfigYesNo(default = False) self.initConfig() def initConfig(self): count = self.config.entriescount.value if count != 0: i = 0 while i < count: self.initEntryConfig() i += 1 print "[AutomaticVolumeAdjustmentConfig] Loaded %s entries from config file..." % count def initEntryConfig(self): self.config.Entries.append(ConfigSubsection()) i = len(self.config.Entries) - 1 self.config.Entries[i].servicereference = ConfigText(default = "") self.config.Entries[i].name = NoSave(ConfigDirectory(default = _("Press OK to select a service"))) self.config.Entries[i].adjustvalue = ConfigSelectionNumber(-50, 50, 5, default = 25) return self.config.Entries[i] def remove(self, configItem): self.config.entriescount.value = self.config.entriescount.value - 1 self.config.entriescount.save() self.config.Entries.remove(configItem) self.config.Entries.save() self.save() def save(self): print "[AutomaticVolumeAdjustmentConfig] saving config file..." self.config.saveToFile(self.CONFIG_FILE)
class AutomaticVolumeAdjustmentConfig(): def __init__(self): self.CONFIG_FILE = '/usr/lib/enigma2/python/Plugins/Extensions/AutomaticVolumeAdjustment/config' # load config file self.loadConfigFile() # load config file and initialize def loadConfigFile(self): print "[AutomaticVolumeAdjustmentConfig] Loading config file..." self.config = Config() if not os_path.exists(self.CONFIG_FILE): fd = os_open( self.CONFIG_FILE, os_O_RDWR|os_O_CREAT) os_close( fd ) self.config.loadFromFile(self.CONFIG_FILE) self.config.entriescount = ConfigInteger(0) self.config.Entries = ConfigSubList() self.config.enable = ConfigYesNo(default = False) self.config.adustvalue = ConfigInteger(default=25, limits=(0,95)) self.initConfig() def initConfig(self): count = self.config.entriescount.value if count != 0: i = 0 while i < count: self.initEntryConfig() i += 1 print "[AutomaticVolumeAdjustmentConfig] Loaded %s entries from config file..." % count def initEntryConfig(self): self.config.Entries.append(ConfigSubsection()) i = len(self.config.Entries) - 1 self.config.Entries[i].servicereference = ConfigText(default = "") self.config.Entries[i].name = NoSave(ConfigDirectory(default = _("Press OK to select a service"))) self.config.Entries[i].adjustvalue = ConfigInteger(default=25, limits=(5,95)) return self.config.Entries[i] def remove(self, configItem): self.config.entriescount.value = self.config.entriescount.value - 1 self.config.entriescount.save() self.config.Entries.remove(configItem) self.config.Entries.save() self.save() def save(self): print "[AutomaticVolumeAdjustmentConfig] saving config file..." self.config.saveToFile(self.CONFIG_FILE)
class SHOUTcastWidget(Screen): GENRELIST = 0 STATIONLIST = 1 FAVORITELIST = 2 SEARCHLIST = 3 STREAMRIPPER_BIN = '/usr/bin/streamripper' SC = 'http://api.shoutcast.com' SCY = 'http://yp.shoutcast.com' FAVORITE_FILE_DEFAULT = '/usr/lib/enigma2/python/Plugins/Extensions/IniSHOUTcast/favorites' FAVORITE_FILE_OLD = '/usr/lib/enigma2/python/Plugins/Extensions/IniSHOUTcast/favorites.user' FAVORITE_FILE = '/etc/enigma2/SHOUTcast.favorites' sz_w = getDesktop(0).size().width() - 90 sz_h = getDesktop(0).size().height() - 95 print "[SHOUTcast] desktop size %dx%d\n" % (sz_w+90, sz_h+100) if sz_h < 500: sz_h += 4 skin = """ <screen name="SHOUTcastWidget" position="center,65" title="SHOUTcast" size="%d,%d"> <ePixmap position="5,0" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" /> <ePixmap position="150,0" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" /> <ePixmap position="295,0" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" /> <ePixmap position="440,0" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" /> <ePixmap pixmap="skin_default/buttons/key_menu.png" position="585,10" zPosition="0" size="35,25" alphatest="on" /> <widget render="Label" source="key_red" position="5,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_green" position="150,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_yellow" position="295,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_blue" position="440,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget name="headertext" position="5,47" zPosition="1" size="%d,23" font="Regular;20" transparent="1" backgroundColor="#00000000"/> <widget name="statustext" position="5,240" zPosition="1" size="%d,90" font="Regular;20" halign="center" valign="center" transparent="0" backgroundColor="#00000000"/> <widget name="list" position="5,80" zPosition="2" size="%d,%d" scrollbarMode="showOnDemand" transparent="0" backgroundColor="#00000000"/> <widget name="titel" position="115,%d" zPosition="1" size="%d,40" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="station" position="115,%d" zPosition="1" size="%d,40" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="console" position="115,%d" zPosition="1" size="%d,40" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="cover" zPosition="2" position="5,%d" size="102,110" alphatest="blend" /> <ePixmap position="%d,41" zPosition="4" size="120,35" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/IniSHOUTcast/shoutcast-logo1-fs8.png" transparent="1" alphatest="on" /> </screen>""" %( sz_w, sz_h, # size sz_w - 135, # size headertext sz_w - 100, # size statustext sz_w - 10, sz_h - 205, # size list sz_h - 105, # position titel sz_w - 125, # size titel sz_h - 70, # position station sz_w - 125, # size station sz_h - 25, # position console sz_w - 125, # size console sz_h - 105, # position cover sz_w - 125, # position logo ) def __init__(self, session): self.session = session Screen.__init__(self, session) self.oldtitle = None self.currentcoverfile = 0 self.currentGoogle = None self.nextGoogle = None self.currPlay = None self.CurrentService = self.session.nav.getCurrentlyPlayingServiceReference() self.session.nav.stopService() self.session.nav.event.append(self.__event) self["cover"] = Cover() self["key_red"] = StaticText(_("Record")) self["key_green"] = StaticText(_("Genres")) self["key_yellow"] = StaticText(_("Stations")) self["key_blue"] = StaticText(_("Favorites")) self.mode = self.FAVORITELIST self["list"] = SHOUTcastList() self["list"].connectSelChanged(self.onSelectionChanged) self["statustext"] = Label(_("Getting SHOUTcast genre list...")) self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions", "EPGSelectActions"], { "ok": self.ok_pressed, "back": self.close, "menu": self.menu_pressed, "red": self.red_pressed, "green": self.green_pressed, "yellow": self.yellow_pressed, "blue": self.blue_pressed, }, -1) self.stationList = [] self.stationListIndex = 0 self.genreList = [] self.genreListIndex = 0 self.favoriteList = [] self.favoriteListIndex = 0 self.favoriteConfig = Config() if os.path.exists(self.FAVORITE_FILE): self.favoriteConfig.loadFromFile(self.FAVORITE_FILE) elif os.path.exists(self.FAVORITE_FILE_OLD): self.favoriteConfig.loadFromFile(self.FAVORITE_FILE_OLD) else: self.favoriteConfig.loadFromFile(self.FAVORITE_FILE_DEFAULT) self.favoriteConfig.entriescount = ConfigInteger(0) self.favoriteConfig.Entries = ConfigSubList() self.initFavouriteConfig() self.stationListXML = "" self["titel"] = Label() self["station"] = Label() self["headertext"] = Label() self["console"] = Label() self.headerTextString = "" self.stationListHeader = "" self.tunein = "" self.searchSHOUTcastString = "" self.currentStreamingURL = "" self.currentStreamingStation = "" self.stationListURL = "" self.onClose.append(self.__onClose) self.onLayoutFinish.append(self.getFavoriteList) self.reloadStationListTimer = eTimer() self.reloadStationListTimer.timeout.get().append(self.reloadStationListTimerTimeout) self.reloadStationListTimerVar = int(config.plugins.shoutcast.reloadstationlist.value) self.visible = True global containerStreamripper if containerStreamripper is None: containerStreamripper = eConsoleAppContainer() containerStreamripper.dataAvail.append(self.streamripperDataAvail) containerStreamripper.appClosed.append(self.streamripperClosed) if containerStreamripper.running(): self["key_red"].setText(_("Stop record")) # just to hear to recording music when starting the plugin... self.currentStreamingStation = _("Recording stream station") self.playServiceStream("http://localhost:9191") def streamripperClosed(self, retval): if retval == 0: self["console"].setText("") self["key_red"].setText(_("Record")) def streamripperDataAvail(self, data): sData = data.replace('\n','') self["console"].setText(sData) def stopReloadStationListTimer(self): if self.reloadStationListTimer.isActive(): self.reloadStationListTimer.stop() def reloadStationListTimerTimeout(self): self.stopReloadStationListTimer() if self.mode == self.STATIONLIST: # print "[SHOUTcast] reloadStationList: %s " % self.stationListURL sendUrlCommand(self.stationListURL, None,10).addCallback(self.callbackStationList).addErrback(self.callbackStationListError) def InputBoxStartRecordingCallback(self, returnValue = None): if returnValue: recordingLength = int(returnValue) * 60 if not os.path.exists(config.plugins.shoutcast.dirname.value): os.mkdir(config.plugins.shoutcast.dirname.value) args = [] args.append(self.currentStreamingURL) args.append('-d') args.append(config.plugins.shoutcast.dirname.value) args.append('-r') args.append('9191') if recordingLength != 0: args.append('-l') args.append("%d" % int(recordingLength)) if config.plugins.shoutcast.riptosinglefile.value: args.append('-a') args.append('-A') if not config.plugins.shoutcast.createdirforeachstream.value: args.append('-s') if config.plugins.shoutcast.addsequenceoutputfile.value: args.append('-q') cmd = [self.STREAMRIPPER_BIN, self.STREAMRIPPER_BIN] + args containerStreamripper.execute(*cmd) self["key_red"].setText(_("Stop record")) def deleteRecordingConfirmed(self,val): if val: containerStreamripper.sendCtrlC() def red_pressed(self): if containerStreamripper.running(): self.session.openWithCallback(self.deleteRecordingConfirmed, MessageBox, _("Do you really want to stop the recording?")) else: if len(self.currentStreamingURL) != 0: self.session.openWithCallback(self.InputBoxStartRecordingCallback, InputBox, windowTitle = _("Recording length"), title=_("Enter in minutes (0 means unlimited)"), text="0", type=Input.NUMBER) else: self.session.open(MessageBox, _("Only running streamings can be recorded!"), type = MessageBox.TYPE_INFO,timeout = 20 ) def green_pressed(self): if self.mode != self.GENRELIST: self.stopReloadStationListTimer() self.mode = self.GENRELIST if not self.genreList: self.getGenreList() else: self.showGenreList() def yellow_pressed(self): if self.mode != self.STATIONLIST: if len(self.stationList): self.mode = self.STATIONLIST self.headerTextString = _("SHOUTcast station list for %s") % self.stationListHeader self["headertext"].setText(self.headerTextString) self["list"].setMode(self.mode) self["list"].setList([ (x,) for x in self.stationList]) self["list"].moveToIndex(self.stationListIndex) if self.reloadStationListTimerVar != 0: self.reloadStationListTimer.start(60000 * self.reloadStationListTimerVar) def blue_pressed(self): if self.mode != self.FAVORITELIST: self.stopReloadStationListTimer() self.getFavoriteList(self.favoriteListIndex) def getFavoriteList(self, favoriteListIndex = 0): self["statustext"].setText("") self.headerTextString = _("Favorite list") self["headertext"].setText(self.headerTextString) self.mode = self.FAVORITELIST self["list"].setMode(self.mode) favoriteList = [] for item in self.favoriteConfig.Entries: favoriteList.append(Favorite(configItem=item)) self["list"].setList([ (x,) for x in favoriteList]) if len(favoriteList): self["list"].moveToIndex(favoriteListIndex) self["list"].show() def getGenreList(self, genre = "all" , id = 0): self["headertext"].setText("") self["statustext"].setText(_("Getting SHOUTcast genre list for %s..." % genre)) self["list"].hide() if len(devid) > 8: url = self.SC + "/genre/secondary?parentid=%s&k=%s&f=xml" % (id, devid) else: url = "http://207.200.98.1/sbin/newxml.phtml" sendUrlCommand(url, None,10).addCallback(self.callbackGenreList).addErrback(self.callbackGenreListError) def callbackGenreList(self, xmlstring): self["headertext"].setText(_("SHOUTcast genre list")) self.genreListIndex = 0 self.mode = self.GENRELIST self.genreList = self.fillGenreList(xmlstring) self["statustext"].setText("") if not len(self.genreList): self["statustext"].setText(_("Got 0 genres. Could be a network problem.\nPlease try again...")) else: self.showGenreList() def callbackGenreListError(self, error = None): if error is not None: try: self["list"].hide() self["statustext"].setText(_("%s\nPress green-button to try again...") % str(error.getErrorMessage())) except: pass def fillGenreList(self, xmlstring): genreList = [] # print "[SHOUTcast] fillGenreList\n%s" % xmlstring try: root = xml.etree.cElementTree.fromstring(xmlstring) except: return [] data = root.find("data") if data == None: print "[SHOUTcast] could not find data tag, assume flat listing\n" return [SHOUTcastGenre(name=childs.get("name")) for childs in root.findall("genre")] for glist in data.findall("genrelist"): for childs in glist.findall("genre"): gn = childs.get("name") gid = childs.get("id") gparentid = childs.get("parentid") ghaschilds = childs.get("haschildren") #print "[SHOUTcast] Genre %s id=%s parent=%s haschilds=%s\n" % (gn, gid, gparentid, ghaschilds) genreList.append(SHOUTcastGenre(name = gn, id = gid, parentid = gparentid, haschilds = ghaschilds)) if ghaschilds == "true": for childlist in childs.findall("genrelist"): for genre in childlist.findall("genre"): gn = genre.get("name") gid = genre.get("id") gparentid = genre.get("parentid") ghaschilds = genre.get("haschildren") # print "[SHOUTcast] Genre %s id=%s parent=%s haschilds=%s\n" % (gn, gid, gparentid, ghaschilds) genreList.append(SHOUTcastGenre(name = gn, id = gid, parentid = gparentid, haschilds = ghaschilds)) return genreList def showGenreList(self): self["headertext"].setText(_("SHOUTcast genre list")) self["list"].setMode(self.mode) self["list"].setList([ (x,) for x in self.genreList]) self["list"].moveToIndex(self.genreListIndex) self["list"].show() def onSelectionChanged(self): pass # till I find a better solution # if self.mode == self.STATIONLIST: # self.stationListIndex = self["list"].getCurrentIndex() # elif self.mode == self.FAVORITELIST: # self.favoriteListIndex = self["list"].getCurrentIndex() # elif self.mode == self.GENRELIST: # self.genreListIndex = self["list"].getCurrentIndex() def ok_pressed(self): if self.visible: sel = None try: sel = self["list"].l.getCurrentSelection()[0] except:return if sel is None: return else: if self.mode == self.GENRELIST: self.genreListIndex = self["list"].getCurrentIndex() self.getStationList(sel.name) elif self.mode == self.STATIONLIST: self.stationListIndex = self["list"].getCurrentIndex() self.stopPlaying() if len(devid) > 8: url = self.SCY + "/sbin/tunein-station.pls?id=%s" % (sel.id) self["list"].hide() self["statustext"].setText(_("Getting streaming data from\n%s") % sel.name) self.currentStreamingStation = sel.name sendUrlCommand(url, None, 10).addCallback(self.callbackPLS).addErrback(self.callbackStationListError) elif self.mode == self.FAVORITELIST: self.favoriteListIndex = self["list"].getCurrentIndex() if sel.configItem.type.value == "url": self.stopPlaying() self["headertext"].setText(self.headerTextString) self.currentStreamingStation = sel.configItem.name.value self.playServiceStream(sel.configItem.text.value) elif sel.configItem.type.value == "pls": self.stopPlaying() url = sel.configItem.text.value self["list"].hide() self["statustext"].setText(_("Getting streaming data from\n%s") % sel.configItem.name.value) self.currentStreamingStation = sel.configItem.name.value sendUrlCommand(url, None,10).addCallback(self.callbackPLS).addErrback(self.callbackStationListError) elif sel.configItem.type.value == "genre": self.getStationList(sel.configItem.name.value) elif self.mode == self.SEARCHLIST and self.searchSHOUTcastString != "": self.searchSHOUTcast(self.searchSHOUTcastString) else: self.showWindow() def stopPlaying(self): self.currentStreamingURL = "" self.currentStreamingStation = "" self["headertext"].setText("") self["titel"].setText("") self["station"].setText("") self.summaries.setText("") if config.plugins.shoutcast.showcover.value: self["cover"].doHide() self.session.nav.stopService() def callbackPLS(self, result): self["headertext"].setText(self.headerTextString) found = False parts = string.split(result,"\n") for lines in parts: if lines.find("File1=") != -1: line = string.split(lines,"File1=") found = True self.playServiceStream(line[-1].rstrip().strip()) if found: self["statustext"].setText("") self["list"].show() else: self.currentStreamingStation = "" self["statustext"].setText(_("No streaming data found...")) self["list"].show() def getStationList(self,genre): self.stationListHeader = _("genre %s") % genre self.headerTextString = _("SHOUTcast station list for %s") % self.stationListHeader self["headertext"].setText("") self["statustext"].setText(_("Getting %s") % self.headerTextString) self["list"].hide() if len(devid) > 8: self.stationListURL = self.SC + "/station/advancedsearch&f=xml&k=%s&search=%s" % (devid, genre) else: self.stationListURL = "http://207.200.98.1/sbin/newxml.phtml?genre=%s" % genre self.stationListIndex = 0 sendUrlCommand(self.stationListURL, None, 10).addCallback(self.callbackStationList).addErrback(self.callbackStationListError) def callbackStationList(self, xmlstring): self.searchSHOUTcastString = "" self.stationListXML = xmlstring self["headertext"].setText(self.headerTextString) self.mode = self.STATIONLIST self["list"].setMode(self.mode) self.stationList = self.fillStationList(xmlstring) self["statustext"].setText("") self["list"].setList([ (x,) for x in self.stationList]) if len(self.stationList): self["list"].moveToIndex(self.stationListIndex) self["list"].show() if self.reloadStationListTimerVar != 0: self.reloadStationListTimer.start(1000 * 60) def fillStationList(self,xmlstring): stationList = [] try: root = xml.etree.cElementTree.fromstring(xmlstring) except: return [] config_bitrate = int(config.plugins.shoutcast.streamingrate.value) data = root.find("data") if data == None: print "[SHOUTcast] could not find data tag\n" return [] for slist in data.findall("stationlist"): for childs in slist.findall("tunein"): self.tunein = childs.get("base") for childs in slist.findall("station"): try: bitrate = int(childs.get("br")) except: bitrate = 0 if bitrate >= config_bitrate: stationList.append(SHOUTcastStation(name = childs.get("name"), mt = childs.get("mt"), id = childs.get("id"), br = childs.get("br"), genre = childs.get("genre"), ct = childs.get("ct"), lc = childs.get("lc"), ml = childs.get("ml"), nsc = childs.get("nsc"), cst = childs.get("cst"))) return stationList def menu_pressed(self): if not self.visible: self.showWindow() options = [(_("Config"), self.config),(_("Search"), self.search),] if self.mode == self.FAVORITELIST and self.getSelectedItem() is not None: options.extend(((_("rename current selected favorite"), self.renameFavorite),)) options.extend(((_("remove current selected favorite"), self.removeFavorite),)) elif self.mode == self.GENRELIST and self.getSelectedItem() is not None: options.extend(((_("Add current selected genre to favorite"), self.addGenreToFavorite),)) elif self.mode == self.STATIONLIST and self.getSelectedItem() is not None: options.extend(((_("Add current selected station to favorite"), self.addStationToFavorite),)) if len(self.currentStreamingURL) != 0: options.extend(((_("Add current playing stream to favorite"), self.addCurrentStreamToFavorite),)) options.extend(((_("Hide"), self.hideWindow),)) self.session.openWithCallback(self.menuCallback, ChoiceBox,list = options) def menuCallback(self, ret): ret and ret[1]() def hideWindow(self): self.visible = False self.hide() def showWindow(self): self.visible = True self.show() def addGenreToFavorite(self): sel = self.getSelectedItem() if sel is not None: self.addFavorite(name = sel.name, text = sel.name, favoritetype = "genre") def addStationToFavorite(self): sel = self.getSelectedItem() if sel is not None: self.addFavorite(name = sel.name, text = self.SCY + "/sbin/tunein-station.pls?id=%s" % (sel.id), favoritetype = "pls", audio = sel.mt, bitrate = sel.br) def addCurrentStreamToFavorite(self): self.addFavorite(name = self.currentStreamingStation, text = self.currentStreamingURL, favoritetype = "url") def addFavorite(self, name = "", text = "", favoritetype = "", audio = "", bitrate = ""): self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value + 1 self.favoriteConfig.entriescount.save() newFavorite = self.initFavouriteEntryConfig() newFavorite.name.value = name newFavorite.text.value = text newFavorite.type.value = favoritetype newFavorite.audio.value = audio newFavorite.bitrate.value = bitrate newFavorite.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) def renameFavorite(self): sel = self.getSelectedItem() if sel is not None: self.session.openWithCallback(self.renameFavoriteFinished, VirtualKeyBoard, title = _("Enter new name for favorite item"), text = sel.configItem.name.value) def renameFavoriteFinished(self, text = None): if text: sel = self.getSelectedItem() sel.configItem.name.value = text sel.configItem.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) self.favoriteListIndex = 0 self.getFavoriteList() def removeFavorite(self): sel = self.getSelectedItem() if sel is not None: self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value - 1 self.favoriteConfig.entriescount.save() self.favoriteConfig.Entries.remove(sel.configItem) self.favoriteConfig.Entries.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) self.favoriteListIndex = 0 self.getFavoriteList() def search(self): self.session.openWithCallback(self.searchSHOUTcast, VirtualKeyBoard, title = _("Enter text to search for")) def searchSHOUTcast(self, searchstring = None): if searchstring: self.stopReloadStationListTimer() self.stationListHeader = _("search-criteria %s") % searchstring self.headerTextString = _("SHOUTcast station list for %s") % self.stationListHeader self["headertext"].setText("") self["statustext"].setText(_("Searching SHOUTcast for %s...") % searchstring) self["list"].hide() if len(devid) > 8: self.stationListURL = self.SC + "/station/advancedsearch&f=xml&k=%s&search=%s" % (devid, searchstring) else: self.stationListURL = "http://207.200.98.1/sbin/newxml.phtml?search=%s" % searchstring self.mode = self.SEARCHLIST self.searchSHOUTcastString = searchstring self.stationListIndex = 0 sendUrlCommand(self.stationListURL, None, 10).addCallback(self.callbackStationList).addErrback(self.callbackStationListError) def config(self): self.stopReloadStationListTimer() self.session.openWithCallback(self.setupFinished, SHOUTcastSetup) def setupFinished(self, result): if result: if config.plugins.shoutcast.showcover.value: self["cover"].doShow() else: self["cover"].doHide() if self.mode == self.STATIONLIST: self.reloadStationListTimerVar = int(config.plugins.shoutcast.reloadstationlist.value) self.stationListIndex = 0 self.callbackStationList(self.stationListXML) def callbackStationListError(self, error = None): if error is not None: try: self["list"].hide() self["statustext"].setText(_("%s\nPress OK to try again...") % str(error.getErrorMessage())) except: pass def Error(self, error = None): if error is not None: # print "[SHOUTcast] Error: %s\n" % error try: self["list"].hide() self["statustext"].setText(str(error.getErrorMessage())) except: pass if self.nextGoogle: self.currentGoogle = self.nextGoogle self.nextGoogle = None sendUrlCommand(self.currentGoogle, None, 10).addCallback(self.GoogleImageCallback).addErrback(self.Error) else: self.currentGoogle = None def __onClose(self): global coverfiles for f in coverfiles: try: os.unlink(f) except: pass self.stopReloadStationListTimer() self.session.nav.playService(self.CurrentService) self.session.nav.event.remove(self.__event) self.currPlay = None containerStreamripper.dataAvail.remove(self.streamripperDataAvail) containerStreamripper.appClosed.remove(self.streamripperClosed) def GoogleImageCallback(self, result): global coverfiles if self.nextGoogle: self.currentGoogle = self.nextGoogle self.nextGoogle = None sendUrlCommand(self.currentGoogle, None, 10).addCallback(self.GoogleImageCallback).addErrback(self.Error) return self.currentGoogle = None foundPos = result.find("unescapedUrl\":\"") foundPos2 = result.find("\",\"url\":\"") if foundPos != -1 and foundPos2 != -1: url=result[foundPos+15:foundPos2] if len(url)>15: url= url.replace(" ", "%20") print "download url: %s " % url validurl = True else: validurl = False print "[SHOUTcast] invalid cover url or pictureformat!" if config.plugins.shoutcast.showcover.value: self["cover"].doHide() if validurl: self.currentcoverfile = (self.currentcoverfile + 1) % len(coverfiles) try: os.unlink(coverfiles[self.currentcoverfile-1]) except: pass coverfile = coverfiles[self.currentcoverfile] print "[SHOUTcast] downloading cover from %s to %s" % (url, coverfile) downloadPage(url, coverfile).addCallback(self.coverDownloadFinished, coverfile).addErrback(self.coverDownloadFailed) def coverDownloadFailed(self,result): print "[SHOUTcast] cover download failed:", result if config.plugins.shoutcast.showcover.value: self["statustext"].setText(_("Error downloading cover...")) self["cover"].doHide() def coverDownloadFinished(self, result, coverfile): if config.plugins.shoutcast.showcover.value: print "[SHOUTcast] cover download finished:", coverfile self["statustext"].setText("") self["cover"].updateIcon(coverfile) self["cover"].doShow() def __event(self, ev): if ev != 17: print "[SHOUTcast] EVENT ==>", ev if ev == 1 or ev == 4: print "[SHOUTcast] Tuned in, playing now!" if ev == 3 or ev == 7: self["statustext"].setText(_("Stream stopped playing, playback of stream stopped!")) print "[SHOUTcast] Stream stopped playing, playback of stream stopped!" self.session.nav.stopService() if ev == 5: if not self.currPlay: return sTitle = self.currPlay.info().getInfoString(iServiceInformation.sTagTitle) if self.oldtitle != sTitle: self.oldtitle=sTitle sTitle = sTitle.replace("Title:", "")[:55] if config.plugins.shoutcast.showcover.value: searchpara="album cover " if sTitle: url = "http://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=%s%s&biw=%s&bih=%s&ift=jpg&ift=gif&ift=png" % (quote(searchpara), quote(sTitle), config.plugins.shoutcast.coverwidth.value, config.plugins.shoutcast.coverheight.value) else: url = "http://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=no+cover+pic&biw=%s&bih=%s&ift=jpg&ift=gif&ift=png" % (config.plugins.shoutcast.coverwidth.value, config.plugins.shoutcast.coverheight.value) print "[SHOUTcast] coverurl = %s " % url if self.currentGoogle: self.nextGoogle = url else: self.currentGoogle = url sendUrlCommand(url, None, 10).addCallback(self.GoogleImageCallback).addErrback(self.Error) if len(sTitle) == 0: sTitle = "n/a" title = _("Title: %s") % sTitle print "[SHOUTcast] Title: %s " % title self["titel"].setText(title) self.summaries.setText(title) else: print "[SHOUTcast] Ignoring useless updated info provided by streamengine!" #if ev == 6 or (ev > 8 and ev != 17): # print "[SHOUTcast] Abnormal event %s from stream, so stop playing!" % ev # self["statustext"].setText(_("Abnormal event from stream, aborting!")) # self.session.nav.stopService() def playServiceStream(self, url): self.currPlay = None self.session.nav.stopService() if config.plugins.shoutcast.showcover.value: self["cover"].doHide() sref = eServiceReference("4097:0:0:0:0:0:0:0:0:0:%s" % url.replace(':', '%3a')) try: self.session.nav.playService(sref) except: print "[SHOUTcast] Could not play %s" % sref self.currPlay = self.session.nav.getCurrentService() self.currentStreamingURL = url self["titel"].setText(_("Title: n/a")) self["station"].setText(_("Station: %s") % self.currentStreamingStation) def createSummary(self): return SHOUTcastLCDScreen def initFavouriteEntryConfig(self): self.favoriteConfig.Entries.append(ConfigSubsection()) i = len(self.favoriteConfig.Entries) -1 self.favoriteConfig.Entries[i].name = ConfigText(default = "") self.favoriteConfig.Entries[i].text = ConfigText(default = "") self.favoriteConfig.Entries[i].type = ConfigText(default = "") self.favoriteConfig.Entries[i].audio = ConfigText(default = "") self.favoriteConfig.Entries[i].bitrate = ConfigText(default = "") return self.favoriteConfig.Entries[i] def initFavouriteConfig(self): count = self.favoriteConfig.entriescount.value if count != 0: i = 0 while i < count: self.initFavouriteEntryConfig() i += 1 def getSelectedItem(self): sel = None try: sel = self["list"].l.getCurrentSelection()[0] except:return None return sel
class InternetRadioFavoriteConfig(object): FAVORITE_FILE_DEFAULT = eEnv.resolve('${libdir}/enigma2/python/Plugins/Extensions/InternetRadio/internetradio_favorites') #'/usr/lib/enigma2/python/Plugins/Extensions/InternetRadio/internetradio_favorites' FAVORITE_FILE = eEnv.resolve("${sysconfdir}/enigma2/internetradio_favorites.user") #'/etc/enigma2/internetradio_favorites.user' def __init__(self): self.loadFavoriteConfig() def loadFavoriteConfig(self): self.favoriteConfig = Config() if os.path.exists(self.FAVORITE_FILE): self.favoriteConfig.loadFromFile(self.FAVORITE_FILE) else: self.favoriteConfig.loadFromFile(self.FAVORITE_FILE_DEFAULT) self.favoriteConfig.entriescount = ConfigInteger(0) self.favoriteConfig.Entries = ConfigSubList() self.initFavouriteConfig() def initFavouriteEntryConfig(self): self.favoriteConfig.Entries.append(ConfigSubsection()) i = len(self.favoriteConfig.Entries) -1 self.favoriteConfig.Entries[i].name = ConfigText(default = "") self.favoriteConfig.Entries[i].text = ConfigText(default = "") self.favoriteConfig.Entries[i].type = ConfigInteger(0) self.favoriteConfig.Entries[i].tags = ConfigText(default = "") self.favoriteConfig.Entries[i].country = ConfigText(default = "") self.favoriteConfig.Entries[i].homepage = ConfigText(default = "") return self.favoriteConfig.Entries[i] def initFavouriteConfig(self): count = self.favoriteConfig.entriescount.value if count != 0: i = 0 while i < count: self.initFavouriteEntryConfig() i += 1 def addFavorite(self, name = "", text = "", favoritetype = "", tags = "", country = "", homepage = ""): self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value + 1 self.favoriteConfig.entriescount.save() newFavorite = self.initFavouriteEntryConfig() newFavorite.name.value = name newFavorite.text.value = text newFavorite.type.value = favoritetype newFavorite.tags.value = tags newFavorite.country.value = country newFavorite.homepage.value = homepage newFavorite.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) def renameFavorite(self, configItem, name, text=None): configItem.name.value = name if text is not None: configItem.text.value = text configItem.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) def removeFavorite(self, configItem): if configItem is not None: self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value - 1 self.favoriteConfig.entriescount.save() self.favoriteConfig.Entries.remove(configItem) self.favoriteConfig.Entries.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) def removeFavoriteHTML(self, name, text, favoritetype): result = 0 for item in self.favoriteConfig.Entries: if item.name.value == name and item.text.value == text and item.type.value == favoritetype: result = 1 self.removeFavorite(item) break return result def renameFavoriteHTML(self, name, text, favoritetype, newname, newtext=None): result = 0 for item in self.favoriteConfig.Entries: if item.name.value == name and item.text.value == text and item.type.value == favoritetype: result = 1 self.renameFavorite(item, newname, newtext) break return result def getFavoriteList(self, html = False): favoriteList = [] for item in self.favoriteConfig.Entries: if html == True: favoriteList.append((item.name.value, item.text.value, item.type.value, item.tags.value, item.country.value, item.homepage.value)) else: favoriteList.append(((Favorite(item)),)) return favoriteList
class tuneinGenresThumb(StreamsThumbCommon): def __init__(self, session, action, value, url): self.defaultImg = 'Extensions/OnDemand/icons/FolderIcon.png' self.showWMA = str(config.ondemand.ShowiRadioWMA.value) self.showDefault = str(config.ondemand.ShowTuneinDefault.value) self.showIcon = str(config.ondemand.ShowTuneinLogos.value) if self.showIcon == 'True': if self.showDefault == 'False': self.defaultImg = '' self.favoriteConfig = Config() if os_path.exists(FAVORITE_FILE): self.favoriteConfig.loadFromFile(FAVORITE_FILE) self.favoriteConfig.entriescount = ConfigInteger(0) self.favoriteConfig.Entries = ConfigSubList() self.initFavoriteConfig() self.genreList = [] self.getGenreList(self.genreList) StreamsThumbCommon.__init__(self, session, action, value, url) self.skin = """ <screen position="0,0" size="e,e" flags="wfNoBorder" > <widget name="lab1" position="0,0" size="e,e" font="Regular;24" halign="center" valign="center" transparent="0" zPosition="5" /> <widget source="Title" render="Label" position="20,0" size="e,50" font="Regular;32" /> <widget name="list" position="0,50" size="e,e-50" scrollbarMode="showOnDemand" transparent="1" /> <ePixmap pixmap="skin_default/buttons/green.png" position="800,10" size="40,40" transparent="1" alphatest="on" /> <widget source="key_green" render="Label" position="810,0" zPosition="1" size="200,40" font="Regular;20" valign="center" halign="center" transparent="1" /> </screen>""" self["key_green"] = StaticText(_("Add to Favorites")) self["genreActions"] = ActionMap(["ColorActions"], { "red": self.red_pressed, "green": self.green_pressed, "yellow": self.yellow_pressed, "blue": self.blue_pressed, }, -1) def layoutFinished(self): self.setTitle("Tunein Radio Player: Listings for " +self.title) #----------------------------------------------------------------------------------------------------------------------------------------# def red_pressed(self): pass def green_pressed(self): date1 = self["list"].l.getCurrentSelection()[0] name = self["list"].l.getCurrentSelection()[1] short = self["list"].l.getCurrentSelection()[2] channel = self["list"].l.getCurrentSelection()[3] stream = self["list"].l.getCurrentSelection()[4] icon = self["list"].l.getCurrentSelection()[5] duration = self["list"].l.getCurrentSelection()[6] exists = 'False' if (stream != 'None') and (channel != 'link'): for item in self.favoriteConfig.Entries: if str(item.text.value) == str(stream): exists = 'True' if exists == 'False': result = self.addFavorite(name=name, text=stream, favoritetype='tunein', audio=duration, bitrate=date1, icon=icon) if result == 0: self.session.open(MessageBox, _('Station saved to Favorites!'), type=MessageBox.TYPE_INFO, timeout=3) else: self.session.open(MessageBox, _('Station save failed, please check the Debug logs!'), type=MessageBox.TYPE_INFO, timeout=3) else: self.session.open(MessageBox, _('Station Already Saved in Favorites!'), type=MessageBox.TYPE_INFO, timeout=3) pass else: self.session.open(MessageBox, _('Selection does not contain a stream!'), type=MessageBox.TYPE_INFO, timeout=3) pass def yellow_pressed(self): pass def blue_pressed(self): pass #----------------------------------------------------------------------------------------------------------------------------------------# def addFavorite(self, name = '', text = '', favoritetype = '', audio = '', bitrate = '', icon = ''): try: self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value + 1 self.favoriteConfig.entriescount.save() newFavorite = self.initFavoriteEntryConfig() newFavorite.name.value = name newFavorite.text.value = text newFavorite.type.value = favoritetype newFavorite.audio.value = audio newFavorite.bitrate.value = bitrate newFavorite.icon.value = icon newFavorite.save() self.favoriteConfig.saveToFile(FAVORITE_FILE) return 0 except (Exception) as exception: print 'addFavorite: Error saving to Favorites: ', exception return -1 def initFavoriteEntryConfig(self): self.favoriteConfig.Entries.append(ConfigSubsection()) i = len(self.favoriteConfig.Entries) - 1 self.favoriteConfig.Entries[i].name = ConfigText(default='') self.favoriteConfig.Entries[i].text = ConfigText(default='') self.favoriteConfig.Entries[i].type = ConfigText(default='') self.favoriteConfig.Entries[i].audio = ConfigText(default='') self.favoriteConfig.Entries[i].bitrate = ConfigText(default='') self.favoriteConfig.Entries[i].icon = ConfigText(default='') return self.favoriteConfig.Entries[i] def initFavoriteConfig(self): count = self.favoriteConfig.entriescount.value if count != 0: i = 0 while i < count: self.initFavoriteEntryConfig() i += 1 #----------------------------------------------------------------------------------------------------------------------------------------# def setupCallback(self, retval = None): if retval == 'cancel' or retval is None: return elif retval == 'search': self.timerCmd = self.TIMER_CMD_VKEY self.cbTimer.start(10) else: self.getTuneinMediaData(self.mediaList, self.url) if len(self.mediaList) == 0: self.session.open(MessageBox, _('Sorry, No Stations Found!'), type=MessageBox.TYPE_INFO, timeout=5) self.updateMenu() def keyboardCallback(self, callback = None): if callback is not None and len(callback): self.setTitle("Tunein Radio Player: Search Listings for " +callback) stationsearch = callback.replace(' ', '+') searchurl = 'http://opml.radiotime.com/Search.ashx?query=%s' % (stationsearch) self.getTuneinMediaData(self.mediaList, searchurl) self.updateMenu() if len(self.mediaList) == 0: self.session.openWithCallback(self.close, MessageBox, _("No items matching your search criteria were found"), MessageBox.TYPE_INFO, timeout=5) else: self.close() #----------------------------------------------------------------------------------------------------------------------------------------# def go(self): showID = self["list"].l.getCurrentSelection()[4] showName = self["list"].l.getCurrentSelection()[1] children = self["list"].l.getCurrentSelection()[3] if children == "link": self.session.open(tuneinGenresThumb, showID, showName, showID) elif showID != 'None': fileUrl = findPlayUrl(showID, 'tunein', self.showWMA) if fileUrl: fileRef = eServiceReference(4097,0,fileUrl) fileRef.setName (showName) # lastservice = self.session.nav.getCurrentlyPlayingServiceOrGroup() self.session.open(MoviePlayer, fileRef, None) # TODO: Find out how to use this! #NavigationInstance.instance.playService(fileRef) else: self.session.open(MessageBox, _('Sorry, unable to find playable stream!'), type=MessageBox.TYPE_INFO, timeout=5) #----------------------------------------------------------------------------------------------------------------------------------------# def getTuneinMediaData(self, weekList, url): short = '' name = '' date1 = '' stream = '' channel = '' icon = '' duration = '' try: # Read the URL for the selected genre on the Main Menu. xml = wgetUrl(url) # Parse the XML with elementTree tree = ET.fromstring(xml) # Find the first element <outline> for elem in tree.iter('outline'): # Iterate through the elements name_tmp = str(elem.get('text')) name_split = name_tmp.rsplit('(',1) name = tidyString(name_split[0]) avail = str(elem.get('key')) if (avail != 'unavailable') and (name != 'This program is not available'): genreID = str(elem.get('genre_id')) genre = self.getGenreName(genreID) stream = str(elem.get('URL')) channel = str(elem.get('type')) formats = str(elem.get('formats')) if channel == 'link': date1 = 'More --->' short = '\nPress OK for sub items of '+name duration = '' else: bitrate = str(elem.get('bitrate')) if bitrate == 'None': date1 = _("Bitrate: Unknown") else: date1 = _("Bitrate: ")+bitrate+" kbps" short_tmp = str(elem.get('subtext')) if genre != 'None': short = _("Recently Played: ")+checkUnicode(short_tmp)+_("\n\nGenre: ")+genre else: short = _("Recently Played: ")+checkUnicode(short_tmp) if formats == 'None': duration = _("Audio: Unknown") else: duration = _("Audio: ")+formats if self.showIcon == 'True': icon = str(elem.get('image')) if icon == 'None': icon = '' else: icon = '' if (channel != 'None'): if (self.showWMA == 'False' and formats =='wma'): print 'getTuneinMediaData: Not showing WMA: showWMA: ', self.showWMA pass else: weekList.append((date1, name, short, channel, stream, icon, duration, False)) except (Exception) as exception: print 'getTuneinMediaData: Error getting Media info: ', exception #----------------------------------------------------------------------------------------------------------------------------------------# def getGenreList(self, genreList): url = 'http://opml.radiotime.com/Describe.ashx?c=genres' # Read the URL for the selected category on the Main Menu. try: # Read the Genre List from Shoutcast. xml = wgetUrl(url) # Make sure data is returned before attempting to parse. if xml: # Parse the XML with elementTree tree = ET.fromstring(xml) # Find the first element <outline> for elem in tree.iter('outline'): # Iterate through the elements genre = str(elem.get('text')) id = str(elem.get('guide_id')) genreList.append((id, genre)) except (Exception) as exception: print 'getGenreList: Error parsing genres: ', exception def getGenreName(self, genreID): try: genreName = 'None' for genre in self.genreList: if genre[0] == genreID: genreName = genre[1] break return genreName except (Exception) as exception: print 'getGenreName: Error Searching genres: ', exception return 'None'
class FavoritesThumb(StreamsThumbCommon): def __init__(self, session, action, value, url): self.defaultImg = 'Extensions/OnDemand/icons/favorite.png' self.showWMA = str(config.ondemand.ShowiRadioWMA.value) self.showDefault = str(config.ondemand.ShowFavoriteDefault.value) self.showIcon = str(config.ondemand.ShowFavoriteLogos.value) if self.showIcon == 'True': if self.showDefault == 'False': self.defaultImg = '' self.favoriteConfig = Config() if os_path.exists(FAVORITE_FILE): self.favoriteConfig.loadFromFile(FAVORITE_FILE) self.favoriteConfig.entriescount = ConfigInteger(0) self.favoriteConfig.Entries = ConfigSubList() self.initFavoriteConfig() StreamsThumbCommon.__init__(self, session, action, value, url) self.skin = """ <screen position="0,0" size="e,e" flags="wfNoBorder" > <widget name="lab1" position="0,0" size="e,e" font="Regular;24" halign="center" valign="center" transparent="0" zPosition="5" /> <widget source="Title" render="Label" position="20,0" size="e,50" font="Regular;32" /> <widget name="list" position="0,50" size="e,e-50" scrollbarMode="showOnDemand" transparent="1" /> <ePixmap pixmap="skin_default/buttons/yellow.png" position="800,10" size="40,40" transparent="1" alphatest="on" /> <widget source="key_yellow" render="Label" position="810,0" zPosition="1" size="250,40" font="Regular;20" valign="center" halign="center" transparent="1" /> </screen>""" self["key_yellow"] = StaticText(_("Delete from Favorites")) self["favActions"] = ActionMap(["ColorActions"], { "red": self.red_pressed, "green": self.green_pressed, "yellow": self.yellow_pressed, "blue": self.blue_pressed, }, -1) def layoutFinished(self): self.setTitle("iRadio Player: Favorite Listings") #----------------------------------------------------------------------------------------------------------------------------------------# def red_pressed(self): pass def green_pressed(self): pass def yellow_pressed(self): result = self.removeFavorite() if result == 0: self.session.open(MessageBox, _('Station deleted from Favorites!'), type=MessageBox.TYPE_INFO, timeout=3) else: self.session.open(MessageBox, _('Station delete failed, please check the Debug logs!'), type=MessageBox.TYPE_INFO, timeout=3) def blue_pressed(self): pass #----------------------------------------------------------------------------------------------------------------------------------------# def removeFavorite(self): try: selFav = self["list"].l.getCurrentSelection()[4] if selFav is not None: self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value - 1 self.favoriteConfig.entriescount.save() for item in self.favoriteConfig.Entries: if str(item.text.value) == str(selFav): self.favoriteConfig.Entries.remove(item) self.favoriteConfig.Entries.save() self.favoriteConfig.saveToFile(FAVORITE_FILE) self.favoriteListIndex = 0 self.mediaList = [] self.getFavoriteList() return 0 except (Exception) as exception: print 'removeFavorite: Error deleting Favorite: ', exception return -1 def getFavoriteList(self): self.getFavMediaData(self.mediaList, self.url) if len(self.mediaList) == 0: self.mediaProblemPopup("No Stations Found!") self.updateMenu() def initFavoriteEntryConfig(self): self.favoriteConfig.Entries.append(ConfigSubsection()) i = len(self.favoriteConfig.Entries) - 1 self.favoriteConfig.Entries[i].name = ConfigText(default='') self.favoriteConfig.Entries[i].text = ConfigText(default='') self.favoriteConfig.Entries[i].type = ConfigText(default='') self.favoriteConfig.Entries[i].audio = ConfigText(default='') self.favoriteConfig.Entries[i].bitrate = ConfigText(default='') self.favoriteConfig.Entries[i].icon = ConfigText(default='') return self.favoriteConfig.Entries[i] def initFavoriteConfig(self): count = self.favoriteConfig.entriescount.value if count != 0: i = 0 while i < count: self.initFavoriteEntryConfig() i += 1 #----------------------------------------------------------------------------------------------------------------------------------------# def setupCallback(self, retval = None): if retval == 'cancel' or retval is None: return else: self.getFavoriteList() def go(self): stationID = self["list"].l.getCurrentSelection()[4] stationName = self["list"].l.getCurrentSelection()[1] favType = self["list"].l.getCurrentSelection()[3] if stationID: if favType == 'manual': fileUrl = stationID elif favType == 'tunein': fileUrl = findPlayUrl(stationID, 'tunein', self.showWMA) else: fileUrl = findPlayUrl(stationID, 'favourite', self.showWMA) if fileUrl: fileRef = eServiceReference(4097,0,fileUrl) fileRef.setName (stationName) # lastservice = self.session.nav.getCurrentlyPlayingServiceOrGroup() self.session.open(MoviePlayer, fileRef, None) else: self.session.open(MessageBox, _('Sorry, unable to find playable stream!'), type=MessageBox.TYPE_INFO, timeout=5) #----------------------------------------------------------------------------------------------------------------------------------------# def getFavMediaData(self, weekList, genre): shoutIcon = 'http://977music.com/images/uploads/pages/SHOUTcast_yellow.jpg' tuneIcon = 'http://www.ipadmaniac.com/wp-content/uploads/2011/06/TuneIn-Radio-Logo.png' short = '' name = '' date1 = '' stream = '' channel = '' icon = '' duration = '' try: for item in self.favoriteConfig.Entries: # Iterate through the elements date1 = str(item.bitrate.value) name_tmp = str(item.name.value) name = checkUnicode(name_tmp) short = str(item.text.value) channel = str(item.type.value) stream = str(item.text.value) duration = str(item.audio.value) # Show the logo for the Favorite source. if self.showIcon == 'True': icon = str(item.icon.value) if icon == '': if channel == 'shoutcast': icon = shoutIcon elif channel == 'tunein': icon = tuneIcon else: icon = '' weekList.append((date1, name, short, channel, stream, icon, duration, False)) except (Exception) as exception: print 'getFavMediaData: Error getting Media info: ', exception
class shoutGenresThumb(StreamsThumbCommon): def __init__(self, session, action, value, url): self.defaultImg = 'Extensions/OnDemand/icons/SHOUTcast.png' self.showWMA = str(config.ondemand.ShowiRadioWMA.value) self.showDefault = str(config.ondemand.ShowShoutcastDefault.value) self.showIcon = str(config.ondemand.ShowShoutcastLogos.value) if self.showIcon == 'True': if self.showDefault == 'False': self.defaultImg = '' self.favoriteConfig = Config() if os_path.exists(FAVORITE_FILE): self.favoriteConfig.loadFromFile(FAVORITE_FILE) self.favoriteConfig.entriescount = ConfigInteger(0) self.favoriteConfig.Entries = ConfigSubList() self.initFavoriteConfig() StreamsThumbCommon.__init__(self, session, action, value, url) self.skin = """ <screen position="0,0" size="e,e" flags="wfNoBorder" > <widget name="lab1" position="0,0" size="e,e" font="Regular;24" halign="center" valign="center" transparent="0" zPosition="5" /> <widget source="Title" render="Label" position="20,0" size="e,50" font="Regular;32" /> <widget name="list" position="0,50" size="e,e-50" scrollbarMode="showOnDemand" transparent="1" /> <ePixmap pixmap="skin_default/buttons/green.png" position="800,10" size="40,40" transparent="1" alphatest="on" /> <widget source="key_green" render="Label" position="810,0" zPosition="1" size="200,40" font="Regular;20" valign="center" halign="center" transparent="1" /> </screen>""" self["key_green"] = StaticText(_("Add to Favorites")) self["genreActions"] = ActionMap(["ColorActions"], { "red": self.red_pressed, "green": self.green_pressed, "yellow": self.yellow_pressed, "blue": self.blue_pressed, }, -1) def layoutFinished(self): self.setTitle("SHOUTcast Radio Player: Listings for " +self.title) #----------------------------------------------------------------------------------------------------------------------------------------# def red_pressed(self): pass def green_pressed(self): date1 = self["list"].l.getCurrentSelection()[0] name = self["list"].l.getCurrentSelection()[1] short = self["list"].l.getCurrentSelection()[2] channel = self["list"].l.getCurrentSelection()[3] stream = self["list"].l.getCurrentSelection()[4] icon = self["list"].l.getCurrentSelection()[5] duration = self["list"].l.getCurrentSelection()[6] exists = 'False' if stream is not None: for item in self.favoriteConfig.Entries: if str(item.text.value) == str(stream): exists = 'True' if exists == 'False': result = self.addFavorite(name=name, text=stream, favoritetype='shoutcast', audio=duration, bitrate=date1, icon=icon) if result == 0: self.session.open(MessageBox, _('Station saved to Favorites!'), type=MessageBox.TYPE_INFO, timeout=3) else: self.session.open(MessageBox, _('Station save failed, please check the Debug logs!'), type=MessageBox.TYPE_INFO, timeout=3) else: self.session.open(MessageBox, _('Station Already Saved in Favorites!'), type=MessageBox.TYPE_INFO, timeout=3) pass else: self.session.open(MessageBox, _('Selection does not contain a stream!'), type=MessageBox.TYPE_INFO, timeout=3) pass def yellow_pressed(self): pass def blue_pressed(self): pass #----------------------------------------------------------------------------------------------------------------------------------------# def addFavorite(self, name = '', text = '', favoritetype = '', audio = '', bitrate = '', icon = ''): try: self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value + 1 self.favoriteConfig.entriescount.save() newFavorite = self.initFavoriteEntryConfig() newFavorite.name.value = name newFavorite.text.value = text newFavorite.type.value = favoritetype newFavorite.audio.value = audio newFavorite.bitrate.value = bitrate newFavorite.icon.value = icon newFavorite.save() self.favoriteConfig.saveToFile(FAVORITE_FILE) return 0 except (Exception) as exception: print 'addFavorite: Error saving to Favorites: ', exception return -1 def getFavoriteList(self): self.getFavMediaData(self.mediaList, self.url) if len(self.mediaList) == 0: self.mediaProblemPopup("No Stations Found!") self.updateMenu() def initFavoriteEntryConfig(self): self.favoriteConfig.Entries.append(ConfigSubsection()) i = len(self.favoriteConfig.Entries) - 1 self.favoriteConfig.Entries[i].name = ConfigText(default='') self.favoriteConfig.Entries[i].text = ConfigText(default='') self.favoriteConfig.Entries[i].type = ConfigText(default='') self.favoriteConfig.Entries[i].audio = ConfigText(default='') self.favoriteConfig.Entries[i].bitrate = ConfigText(default='') self.favoriteConfig.Entries[i].icon = ConfigText(default='') return self.favoriteConfig.Entries[i] def initFavoriteConfig(self): count = self.favoriteConfig.entriescount.value if count != 0: i = 0 while i < count: self.initFavoriteEntryConfig() i += 1 #----------------------------------------------------------------------------------------------------------------------------------------# def setupCallback(self, retval = None): if retval == 'cancel' or retval is None: return elif retval == 'search': self.timerCmd = self.TIMER_CMD_VKEY self.cbTimer.start(10) else: genresearch = self.url.replace(' All', '') genresearch = genresearch.replace(' ', '+') stationurl = 'http://api.shoutcast.com/legacy/genresearch?k=%s&genre=%s' % (devid, genresearch) self.getShoutcastMediaData(self.mediaList, stationurl) if len(self.mediaList) == 0: self.mediaProblemPopup("No Stations Found!") self.updateMenu() def keyboardCallback(self, callback = None): if callback is not None and len(callback): self.setTitle("SHOUTcast Radio Player: Search Listings for " +callback) genresearch = callback.replace(' ', '+') searchurl = 'http://api.shoutcast.com/legacy/stationsearch?k=%s&search=%s' % (devid, str(genresearch)) self.getShoutcastMediaData(self.mediaList, searchurl) self.updateMenu() if len(self.mediaList) == 0: self.session.openWithCallback(self.close, MessageBox, _("No items matching your search criteria were found"), MessageBox.TYPE_INFO, timeout=5) else: self.close() def go(self): showID = self["list"].l.getCurrentSelection()[4] showName = self["list"].l.getCurrentSelection()[1] if showID: fileUrl = findPlayUrl(showID, 'shoutcast', self.showWMA) if fileUrl: fileRef = eServiceReference(4097,0,fileUrl) fileRef.setName (showName) # lastservice = self.session.nav.getCurrentlyPlayingServiceOrGroup() self.session.open(MoviePlayer, fileRef, None) else: self.session.open(MessageBox, _('Sorry, unable to find playable stream!'), type=MessageBox.TYPE_INFO, timeout=5) #----------------------------------------------------------------------------------------------------------------------------------------# def getShoutcastMediaData(self, weekList, url): plsurl = 'http://yp.shoutcast.com/sbin/tunein-station.pls?id=' short = '' name = '' date1 = '' stream = '' channel = '' icon = '' duration = '' try: # Read the URL for the selected genre on the Main Menu. xml = wgetUrl(url) # Make sure reading the URL returned data. if xml: # Parse the XML with elementTree tree = ET.fromstring(xml) # Find the first element <station> for elem in tree.iter('station'): # Iterate through the elements name_tmp = str(elem.get('name')) name = checkUnicode(name_tmp) id = str(elem.get('id')) stream = plsurl+id short_tmp = str(elem.get('ct')) genre = str(elem.get('genre')) bitrate = str(elem.get('br')) audio = str(elem.get('mt')) if genre != 'None': short = _("Recently Played: ")+checkUnicode(short_tmp)+_("\n\nGenre: ")+genre else: short = _("Recently Played: ")+checkUnicode(short_tmp) if bitrate != 'None': date1 = _("Bitrate: ")+bitrate+" kbps" else: date1 = _("Bitrate: Unknown") if audio != 'None': duration = _("Audio: ")+audio else: duration = _("Audio: Unknown") weekList.append((date1, name, short, channel, stream, icon, duration, False)) except (Exception) as exception: print 'getShoutcastMediaData: Error getting Media info: ', exception
class tuneinGenresThumb(StreamsThumbCommon): def __init__(self, session, action, value, url): self.defaultImg = 'Extensions/OnDemand/icons/FolderIcon.png' self.showWMA = str(config.ondemand.ShowiRadioWMA.value) self.showDefault = str(config.ondemand.ShowTuneinDefault.value) self.showIcon = str(config.ondemand.ShowTuneinLogos.value) if self.showIcon == 'True': if self.showDefault == 'False': self.defaultImg = '' self.favoriteConfig = Config() if os_path.exists(FAVORITE_FILE): self.favoriteConfig.loadFromFile(FAVORITE_FILE) self.favoriteConfig.entriescount = ConfigInteger(0) self.favoriteConfig.Entries = ConfigSubList() self.initFavoriteConfig() self.genreList = [] self.getGenreList(self.genreList) StreamsThumbCommon.__init__(self, session, action, value, url) self.skin = """ <screen position="0,0" size="e,e" flags="wfNoBorder" > <widget name="lab1" position="0,0" size="e,e" font="Regular;24" halign="center" valign="center" transparent="0" zPosition="5" /> <widget source="Title" render="Label" position="20,0" size="e,50" font="Regular;32" /> <widget name="list" position="0,50" size="e,e-50" scrollbarMode="showOnDemand" transparent="1" /> <ePixmap pixmap="ViX-Common/buttons/green.png" position="800,10" size="40,40" transparent="1" alphatest="on" /> <widget source="key_green" render="Label" position="810,0" zPosition="1" size="200,40" font="Regular;20" valign="center" halign="center" transparent="1" /> </screen>""" self["key_green"] = StaticText(_("Add to Favorites")) self["genreActions"] = ActionMap(["ColorActions"], { "red": self.red_pressed, "green": self.green_pressed, "yellow": self.yellow_pressed, "blue": self.blue_pressed, }, -1) def layoutFinished(self): self.setTitle("Tunein Radio Player: Listings for " +self.title) #----------------------------------------------------------------------------------------------------------------------------------------# def red_pressed(self): pass def green_pressed(self): date1 = self["list"].l.getCurrentSelection()[0] name = self["list"].l.getCurrentSelection()[1] short = self["list"].l.getCurrentSelection()[2] channel = self["list"].l.getCurrentSelection()[3] stream = self["list"].l.getCurrentSelection()[4] icon = self["list"].l.getCurrentSelection()[5] duration = self["list"].l.getCurrentSelection()[6] exists = 'False' if (stream != 'None') and (channel != 'link'): for item in self.favoriteConfig.Entries: if str(item.text.value) == str(stream): exists = 'True' if exists == 'False': result = self.addFavorite(name=name, text=stream, favoritetype='tunein', audio=duration, bitrate=date1, icon=icon) if result == 0: self.session.open(MessageBox, _('Station saved to Favorites!'), type=MessageBox.TYPE_INFO, timeout=3) else: self.session.open(MessageBox, _('Station save failed, please check the Debug logs!'), type=MessageBox.TYPE_INFO, timeout=3) else: self.session.open(MessageBox, _('Station Already Saved in Favorites!'), type=MessageBox.TYPE_INFO, timeout=3) pass else: self.session.open(MessageBox, _('Selection does not contain a stream!'), type=MessageBox.TYPE_INFO, timeout=3) pass def yellow_pressed(self): pass def blue_pressed(self): pass #----------------------------------------------------------------------------------------------------------------------------------------# def addFavorite(self, name = '', text = '', favoritetype = '', audio = '', bitrate = '', icon = ''): try: self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value + 1 self.favoriteConfig.entriescount.save() newFavorite = self.initFavoriteEntryConfig() newFavorite.name.value = name newFavorite.text.value = text newFavorite.type.value = favoritetype newFavorite.audio.value = audio newFavorite.bitrate.value = bitrate newFavorite.icon.value = icon newFavorite.save() self.favoriteConfig.saveToFile(FAVORITE_FILE) return 0 except (Exception) as exception: print 'addFavorite: Error saving to Favorites: ', exception return -1 def initFavoriteEntryConfig(self): self.favoriteConfig.Entries.append(ConfigSubsection()) i = len(self.favoriteConfig.Entries) - 1 self.favoriteConfig.Entries[i].name = ConfigText(default='') self.favoriteConfig.Entries[i].text = ConfigText(default='') self.favoriteConfig.Entries[i].type = ConfigText(default='') self.favoriteConfig.Entries[i].audio = ConfigText(default='') self.favoriteConfig.Entries[i].bitrate = ConfigText(default='') self.favoriteConfig.Entries[i].icon = ConfigText(default='') return self.favoriteConfig.Entries[i] def initFavoriteConfig(self): count = self.favoriteConfig.entriescount.value if count != 0: i = 0 while i < count: self.initFavoriteEntryConfig() i += 1 #----------------------------------------------------------------------------------------------------------------------------------------# def setupCallback(self, retval = None): if retval == 'cancel' or retval is None: return elif retval == 'search': self.timerCmd = self.TIMER_CMD_VKEY self.cbTimer.start(10) else: self.getTuneinMediaData(self.mediaList, self.url) if len(self.mediaList) == 0: self.session.open(MessageBox, _('Sorry, No Stations Found!'), type=MessageBox.TYPE_INFO, timeout=5) self.updateMenu() def keyboardCallback(self, callback = None): if callback is not None and len(callback): self.setTitle("Tunein Radio Player: Search Listings for " +callback) stationsearch = callback.replace(' ', '+') searchurl = 'http://opml.radiotime.com/Search.ashx?query=%s' % (stationsearch) self.getTuneinMediaData(self.mediaList, searchurl) self.updateMenu() if len(self.mediaList) == 0: self.session.openWithCallback(self.close, MessageBox, _("No items matching your search criteria were found"), MessageBox.TYPE_INFO, timeout=5, simple = True) else: self.close() #----------------------------------------------------------------------------------------------------------------------------------------# def go(self): showID = self["list"].l.getCurrentSelection()[4] showName = self["list"].l.getCurrentSelection()[1] children = self["list"].l.getCurrentSelection()[3] if children == "link": self.session.open(tuneinGenresThumb, showID, showName, showID) elif showID != 'None': fileUrl = findPlayUrl(showID, 'tunein', self.showWMA) if fileUrl: fileRef = eServiceReference(4097,0,fileUrl) fileRef.setName (showName) lastservice = self.session.nav.getCurrentlyPlayingServiceOrGroup() self.session.open(MoviePlayer, fileRef, None, lastservice) # TODO: Find out how to use this! #NavigationInstance.instance.playService(fileRef) else: self.session.open(MessageBox, _('Sorry, unable to find playable stream!'), type=MessageBox.TYPE_INFO, timeout=5) #----------------------------------------------------------------------------------------------------------------------------------------# def getTuneinMediaData(self, weekList, url): short = '' name = '' date1 = '' stream = '' channel = '' icon = '' duration = '' try: # Read the URL for the selected genre on the Main Menu. xml = wgetUrl(url) # Parse the XML with elementTree tree = ET.fromstring(xml) # Find the first element <outline> for elem in tree.iter('outline'): # Iterate through the elements name_tmp = str(elem.get('text')) name_split = name_tmp.rsplit('(',1) name = tidyString(name_split[0]) avail = str(elem.get('key')) if (avail != 'unavailable') and (name != 'This program is not available'): genreID = str(elem.get('genre_id')) genre = self.getGenreName(genreID) stream = str(elem.get('URL')) channel = str(elem.get('type')) formats = str(elem.get('formats')) if channel == 'link': date1 = 'More --->' short = '\nPress OK for sub items of '+name duration = '' else: bitrate = str(elem.get('bitrate')) if bitrate == 'None': date1 = _("Bitrate: Unknown") else: date1 = _("Bitrate: ")+bitrate+" kbps" short_tmp = str(elem.get('subtext')) if genre != 'None': short = _("Recently Played: ")+checkUnicode(short_tmp)+_("\n\nGenre: ")+genre else: short = _("Recently Played: ")+checkUnicode(short_tmp) if formats == 'None': duration = _("Audio: Unknown") else: duration = _("Audio: ")+formats if self.showIcon == 'True': icon = str(elem.get('image')) if icon == 'None': icon = '' else: icon = '' if (channel != 'None'): if (self.showWMA == 'False' and formats =='wma'): print 'getTuneinMediaData: Not showing WMA: showWMA: ', self.showWMA pass else: weekList.append((date1, name, short, channel, stream, icon, duration, False)) except (Exception) as exception: print 'getTuneinMediaData: Error getting Media info: ', exception #----------------------------------------------------------------------------------------------------------------------------------------# def getGenreList(self, genreList): url = 'http://opml.radiotime.com/Describe.ashx?c=genres' # Read the URL for the selected category on the Main Menu. try: # Read the Genre List from Shoutcast. xml = wgetUrl(url) # Make sure data is returned before attempting to parse. if xml: # Parse the XML with elementTree tree = ET.fromstring(xml) # Find the first element <outline> for elem in tree.iter('outline'): # Iterate through the elements genre = str(elem.get('text')) id = str(elem.get('guide_id')) genreList.append((id, genre)) except (Exception) as exception: print 'getGenreList: Error parsing genres: ', exception def getGenreName(self, genreID): try: genreName = 'None' for genre in self.genreList: if genre[0] == genreID: genreName = genre[1] break return genreName except (Exception) as exception: print 'getGenreName: Error Searching genres: ', exception return 'None'
class FavoritesThumb(StreamsThumbCommon): def __init__(self, session, action, value, url): self.defaultImg = 'Extensions/OnDemand/icons/favorite.png' self.showWMA = str(config.ondemand.ShowiRadioWMA.value) self.showDefault = str(config.ondemand.ShowFavoriteDefault.value) self.showIcon = str(config.ondemand.ShowFavoriteLogos.value) if self.showIcon == 'True': if self.showDefault == 'False': self.defaultImg = '' self.favoriteConfig = Config() if os_path.exists(FAVORITE_FILE): self.favoriteConfig.loadFromFile(FAVORITE_FILE) self.favoriteConfig.entriescount = ConfigInteger(0) self.favoriteConfig.Entries = ConfigSubList() self.initFavoriteConfig() StreamsThumbCommon.__init__(self, session, action, value, url) self.skin = """ <screen position="0,0" size="e,e" flags="wfNoBorder" > <widget name="lab1" position="0,0" size="e,e" font="Regular;24" halign="center" valign="center" transparent="0" zPosition="5" /> <widget source="Title" render="Label" position="20,0" size="e,50" font="Regular;32" /> <widget name="list" position="0,50" size="e,e-50" scrollbarMode="showOnDemand" transparent="1" /> <ePixmap pixmap="ViX-Common/buttons/yellow.png" position="800,10" size="40,40" transparent="1" alphatest="on" /> <widget source="key_yellow" render="Label" position="810,0" zPosition="1" size="250,40" font="Regular;20" valign="center" halign="center" transparent="1" /> </screen>""" self["key_yellow"] = StaticText(_("Delete from Favorites")) self["favActions"] = ActionMap(["ColorActions"], { "red": self.red_pressed, "green": self.green_pressed, "yellow": self.yellow_pressed, "blue": self.blue_pressed, }, -1) def layoutFinished(self): self.setTitle("iRadio Player: Favorite Listings") #----------------------------------------------------------------------------------------------------------------------------------------# def red_pressed(self): pass def green_pressed(self): pass def yellow_pressed(self): result = self.removeFavorite() if result == 0: self.session.open(MessageBox, _('Station deleted from Favorites!'), type=MessageBox.TYPE_INFO, timeout=3) else: self.session.open(MessageBox, _('Station delete failed, please check the Debug logs!'), type=MessageBox.TYPE_INFO, timeout=3) def blue_pressed(self): pass #----------------------------------------------------------------------------------------------------------------------------------------# def removeFavorite(self): try: selFav = self["list"].l.getCurrentSelection()[4] if selFav is not None: self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value - 1 self.favoriteConfig.entriescount.save() for item in self.favoriteConfig.Entries: if str(item.text.value) == str(selFav): self.favoriteConfig.Entries.remove(item) self.favoriteConfig.Entries.save() self.favoriteConfig.saveToFile(FAVORITE_FILE) self.favoriteListIndex = 0 self.mediaList = [] self.getFavoriteList() return 0 except (Exception) as exception: print 'removeFavorite: Error deleting Favorite: ', exception return -1 def getFavoriteList(self): self.getFavMediaData(self.mediaList, self.url) if len(self.mediaList) == 0: self.mediaProblemPopup("No Stations Found!") self.updateMenu() def initFavoriteEntryConfig(self): self.favoriteConfig.Entries.append(ConfigSubsection()) i = len(self.favoriteConfig.Entries) - 1 self.favoriteConfig.Entries[i].name = ConfigText(default='') self.favoriteConfig.Entries[i].text = ConfigText(default='') self.favoriteConfig.Entries[i].type = ConfigText(default='') self.favoriteConfig.Entries[i].audio = ConfigText(default='') self.favoriteConfig.Entries[i].bitrate = ConfigText(default='') self.favoriteConfig.Entries[i].icon = ConfigText(default='') return self.favoriteConfig.Entries[i] def initFavoriteConfig(self): count = self.favoriteConfig.entriescount.value if count != 0: i = 0 while i < count: self.initFavoriteEntryConfig() i += 1 #----------------------------------------------------------------------------------------------------------------------------------------# def setupCallback(self, retval = None): if retval == 'cancel' or retval is None: return else: self.getFavoriteList() def go(self): stationID = self["list"].l.getCurrentSelection()[4] stationName = self["list"].l.getCurrentSelection()[1] favType = self["list"].l.getCurrentSelection()[3] if stationID: if favType == 'manual': fileUrl = stationID elif favType == 'tunein': fileUrl = findPlayUrl(stationID, 'tunein', self.showWMA) else: fileUrl = findPlayUrl(stationID, 'favourite', self.showWMA) if fileUrl: fileRef = eServiceReference(4097,0,fileUrl) fileRef.setName (stationName) lastservice = self.session.nav.getCurrentlyPlayingServiceOrGroup() self.session.open(MoviePlayer, fileRef, None, lastservice) else: self.session.open(MessageBox, _('Sorry, unable to find playable stream!'), type=MessageBox.TYPE_INFO, timeout=5) #----------------------------------------------------------------------------------------------------------------------------------------# def getFavMediaData(self, weekList, genre): shoutIcon = 'http://977music.com/images/uploads/pages/SHOUTcast_yellow.jpg' tuneIcon = 'http://www.ipadmaniac.com/wp-content/uploads/2011/06/TuneIn-Radio-Logo.png' short = '' name = '' date1 = '' stream = '' channel = '' icon = '' duration = '' try: for item in self.favoriteConfig.Entries: # Iterate through the elements date1 = str(item.bitrate.value) name_tmp = str(item.name.value) name = checkUnicode(name_tmp) short = str(item.text.value) channel = str(item.type.value) stream = str(item.text.value) duration = str(item.audio.value) # Show the logo for the Favorite source. if self.showIcon == 'True': icon = str(item.icon.value) if icon == '': if channel == 'shoutcast': icon = shoutIcon elif channel == 'tunein': icon = tuneIcon else: icon = '' weekList.append((date1, name, short, channel, stream, icon, duration, False)) except (Exception) as exception: print 'getFavMediaData: Error getting Media info: ', exception
class shoutGenresThumb(StreamsThumbCommon): def __init__(self, session, action, value, url): self.defaultImg = 'Extensions/OnDemand/icons/SHOUTcast.png' self.showWMA = str(config.ondemand.ShowiRadioWMA.value) self.showDefault = str(config.ondemand.ShowShoutcastDefault.value) self.showIcon = str(config.ondemand.ShowShoutcastLogos.value) if self.showIcon == 'True': if self.showDefault == 'False': self.defaultImg = '' self.favoriteConfig = Config() if os_path.exists(FAVORITE_FILE): self.favoriteConfig.loadFromFile(FAVORITE_FILE) self.favoriteConfig.entriescount = ConfigInteger(0) self.favoriteConfig.Entries = ConfigSubList() self.initFavoriteConfig() StreamsThumbCommon.__init__(self, session, action, value, url) self.skin = """ <screen position="0,0" size="e,e" flags="wfNoBorder" > <widget name="lab1" position="0,0" size="e,e" font="Regular;24" halign="center" valign="center" transparent="0" zPosition="5" /> <widget source="Title" render="Label" position="20,0" size="e,50" font="Regular;32" /> <widget name="list" position="0,50" size="e,e-50" scrollbarMode="showOnDemand" transparent="1" /> <ePixmap pixmap="ViX-Common/buttons/green.png" position="800,10" size="40,40" transparent="1" alphatest="on" /> <widget source="key_green" render="Label" position="810,0" zPosition="1" size="200,40" font="Regular;20" valign="center" halign="center" transparent="1" /> </screen>""" self["key_green"] = StaticText(_("Add to Favorites")) self["genreActions"] = ActionMap(["ColorActions"], { "red": self.red_pressed, "green": self.green_pressed, "yellow": self.yellow_pressed, "blue": self.blue_pressed, }, -1) def layoutFinished(self): self.setTitle("SHOUTcast Radio Player: Listings for " +self.title) #----------------------------------------------------------------------------------------------------------------------------------------# def red_pressed(self): pass def green_pressed(self): date1 = self["list"].l.getCurrentSelection()[0] name = self["list"].l.getCurrentSelection()[1] short = self["list"].l.getCurrentSelection()[2] channel = self["list"].l.getCurrentSelection()[3] stream = self["list"].l.getCurrentSelection()[4] icon = self["list"].l.getCurrentSelection()[5] duration = self["list"].l.getCurrentSelection()[6] exists = 'False' if stream is not None: for item in self.favoriteConfig.Entries: if str(item.text.value) == str(stream): exists = 'True' if exists == 'False': result = self.addFavorite(name=name, text=stream, favoritetype='shoutcast', audio=duration, bitrate=date1, icon=icon) if result == 0: self.session.open(MessageBox, _('Station saved to Favorites!'), type=MessageBox.TYPE_INFO, timeout=3) else: self.session.open(MessageBox, _('Station save failed, please check the Debug logs!'), type=MessageBox.TYPE_INFO, timeout=3) else: self.session.open(MessageBox, _('Station Already Saved in Favorites!'), type=MessageBox.TYPE_INFO, timeout=3) pass else: self.session.open(MessageBox, _('Selection does not contain a stream!'), type=MessageBox.TYPE_INFO, timeout=3) pass def yellow_pressed(self): pass def blue_pressed(self): pass #----------------------------------------------------------------------------------------------------------------------------------------# def addFavorite(self, name = '', text = '', favoritetype = '', audio = '', bitrate = '', icon = ''): try: self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value + 1 self.favoriteConfig.entriescount.save() newFavorite = self.initFavoriteEntryConfig() newFavorite.name.value = name newFavorite.text.value = text newFavorite.type.value = favoritetype newFavorite.audio.value = audio newFavorite.bitrate.value = bitrate newFavorite.icon.value = icon newFavorite.save() self.favoriteConfig.saveToFile(FAVORITE_FILE) return 0 except (Exception) as exception: print 'addFavorite: Error saving to Favorites: ', exception return -1 def getFavoriteList(self): self.getFavMediaData(self.mediaList, self.url) if len(self.mediaList) == 0: self.mediaProblemPopup("No Stations Found!") self.updateMenu() def initFavoriteEntryConfig(self): self.favoriteConfig.Entries.append(ConfigSubsection()) i = len(self.favoriteConfig.Entries) - 1 self.favoriteConfig.Entries[i].name = ConfigText(default='') self.favoriteConfig.Entries[i].text = ConfigText(default='') self.favoriteConfig.Entries[i].type = ConfigText(default='') self.favoriteConfig.Entries[i].audio = ConfigText(default='') self.favoriteConfig.Entries[i].bitrate = ConfigText(default='') self.favoriteConfig.Entries[i].icon = ConfigText(default='') return self.favoriteConfig.Entries[i] def initFavoriteConfig(self): count = self.favoriteConfig.entriescount.value if count != 0: i = 0 while i < count: self.initFavoriteEntryConfig() i += 1 #----------------------------------------------------------------------------------------------------------------------------------------# def setupCallback(self, retval = None): if retval == 'cancel' or retval is None: return elif retval == 'search': self.timerCmd = self.TIMER_CMD_VKEY self.cbTimer.start(10) else: genresearch = self.url.replace(' All', '') genresearch = genresearch.replace(' ', '+') stationurl = 'http://api.shoutcast.com/legacy/genresearch?k=%s&genre=%s' % (devid, genresearch) self.getShoutcastMediaData(self.mediaList, stationurl) if len(self.mediaList) == 0: self.mediaProblemPopup("No Stations Found!") self.updateMenu() def keyboardCallback(self, callback = None): if callback is not None and len(callback): self.setTitle("SHOUTcast Radio Player: Search Listings for " +callback) genresearch = callback.replace(' ', '+') searchurl = 'http://api.shoutcast.com/legacy/stationsearch?k=%s&search=%s' % (devid, str(genresearch)) self.getShoutcastMediaData(self.mediaList, searchurl) self.updateMenu() if len(self.mediaList) == 0: self.session.openWithCallback(self.close, MessageBox, _("No items matching your search criteria were found"), MessageBox.TYPE_INFO, timeout=5, simple = True) else: self.close() def go(self): showID = self["list"].l.getCurrentSelection()[4] showName = self["list"].l.getCurrentSelection()[1] if showID: fileUrl = findPlayUrl(showID, 'shoutcast', self.showWMA) if fileUrl: fileRef = eServiceReference(4097,0,fileUrl) fileRef.setName (showName) lastservice = self.session.nav.getCurrentlyPlayingServiceOrGroup() self.session.open(MoviePlayer, fileRef, None, lastservice) else: self.session.open(MessageBox, _('Sorry, unable to find playable stream!'), type=MessageBox.TYPE_INFO, timeout=5) #----------------------------------------------------------------------------------------------------------------------------------------# def getShoutcastMediaData(self, weekList, url): plsurl = 'http://yp.shoutcast.com/sbin/tunein-station.pls?id=' short = '' name = '' date1 = '' stream = '' channel = '' icon = '' duration = '' try: # Read the URL for the selected genre on the Main Menu. xml = wgetUrl(url) # Make sure reading the URL returned data. if xml: # Parse the XML with elementTree tree = ET.fromstring(xml) # Find the first element <station> for elem in tree.iter('station'): # Iterate through the elements name_tmp = str(elem.get('name')) name = checkUnicode(name_tmp) id = str(elem.get('id')) stream = plsurl+id short_tmp = str(elem.get('ct')) genre = str(elem.get('genre')) bitrate = str(elem.get('br')) audio = str(elem.get('mt')) if genre != 'None': short = _("Recently Played: ")+checkUnicode(short_tmp)+_("\n\nGenre: ")+genre else: short = _("Recently Played: ")+checkUnicode(short_tmp) if bitrate != 'None': date1 = _("Bitrate: ")+bitrate+" kbps" else: date1 = _("Bitrate: Unknown") if audio != 'None': duration = _("Audio: ")+audio else: duration = _("Audio: Unknown") weekList.append((date1, name, short, channel, stream, icon, duration, False)) except (Exception) as exception: print 'getShoutcastMediaData: Error getting Media info: ', exception
class SHOUTcastWidget(Screen, InfoBarSeek): GENRELIST = 0 STATIONLIST = 1 FAVORITELIST = 2 SEARCHLIST = 3 STREAMRIPPER_BIN = '/usr/bin/streamripper' FAVORITE_FILE_DEFAULT = '/usr/lib/enigma2/python/Plugins/Extensions/SHOUTcast/favorites' FAVORITE_FILE = '/usr/lib/enigma2/python/Plugins/Extensions/SHOUTcast/favorites.user' sz_w = getDesktop(0).size().width() if sz_w == 1280: skin = """ <screen name="SHOUTcastWidget" position="0,0" size="1280,720" flags="wfNoBorder" backgroundColor="#00000000" title="SHOUTcast"> <ePixmap position="50,30" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" /> <ePixmap position="200,30" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" /> <ePixmap position="350,30" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" /> <ePixmap position="500,30" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" /> <widget render="Label" source="key_red" position="50,30" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_green" position="200,30" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_yellow" position="350,30" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_blue" position="500,30" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget name="headertext" position="50,77" zPosition="1" size="1180,23" font="Regular;20" transparent="1" backgroundColor="#00000000"/> <widget name="statustext" position="20,270" zPosition="1" size="1240,90" font="Regular;20" halign="center" valign="center" transparent="0" backgroundColor="#00000000"/> <widget name="list" position="50,110" zPosition="2" size="1180,445" scrollbarMode="showOnDemand" transparent="0" backgroundColor="#00000000"/> <widget name="titel" position="160,580" zPosition="1" size="900,20" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="station" position="160,600" zPosition="1" size="900,40" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="console" position="160,650" zPosition="1" size="900,50" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="cover" zPosition="2" position="50,580" size="102,110" alphatest="blend" /> <ePixmap position="1100,35" zPosition="4" size="120,35" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/SHOUTcast/shoutcast-logo1-fs8.png" transparent="1" alphatest="on" /> </screen>""" elif sz_w == 1024: skin = """ <screen name="SHOUTcastWidget" position="0,0" size="1024,576" flags="wfNoBorder" backgroundColor="#00000000" title="SHOUTcast"> <ePixmap position="50,30" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" /> <ePixmap position="200,30" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" /> <ePixmap position="350,30" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" /> <ePixmap position="500,30" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" /> <widget render="Label" source="key_red" position="50,30" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_green" position="200,30" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_yellow" position="350,30" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_blue" position="500,30" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget name="headertext" position="50,77" zPosition="1" size="900,23" font="Regular;20" transparent="1" backgroundColor="#00000000"/> <widget name="statustext" position="20,270" zPosition="1" size="1004,90" font="Regular;20" halign="center" valign="center" transparent="0" backgroundColor="#00000000"/> <widget name="list" position="50,110" zPosition="2" size="940,313" scrollbarMode="showOnDemand" transparent="0" backgroundColor="#00000000"/> <widget name="titel" position="160,450" zPosition="1" size="800,20" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="station" position="160,470" zPosition="1" size="800,40" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="console" position="160,520" zPosition="1" size="800,50" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="cover" zPosition="2" position="50,450" size="102,110" alphatest="blend" /> <ePixmap position="870,35" zPosition="4" size="120,35" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/SHOUTcast/shoutcast-logo1-fs8.png" transparent="1" alphatest="on" /> </screen>""" else: skin = """ <screen name="SHOUTcastWidget" position="0,0" size="720,576" flags="wfNoBorder" backgroundColor="#00000000" title="SHOUTcast"> <ePixmap position="50,30" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" /> <ePixmap position="210,30" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" /> <ePixmap position="370,30" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" /> <ePixmap position="530,30" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" /> <widget render="Label" source="key_red" position="50,30" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_green" position="210,30" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_yellow" position="370,30" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_blue" position="530,30" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget name="headertext" position="50,77" zPosition="1" size="620,23" font="Regular;20" transparent="1" backgroundColor="#00000000"/> <widget name="statustext" position="50,270" zPosition="1" size="620,90" font="Regular;20" halign="center" valign="center" transparent="0" backgroundColor="#00000000"/> <widget name="list" position="50,120" zPosition="2" size="620,249" scrollbarMode="showOnDemand" transparent="0" backgroundColor="#00000000"/> <widget name="titel" position="155,400" zPosition="1" size="525,40" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="station" position="155,445" zPosition="1" size="525,40" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="console" position="155,490" zPosition="1" size="525,50" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="cover" zPosition="2" position="50,400" size="102,110" alphatest="blend" /> <ePixmap position="550,77" zPosition="4" size="120,35" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/SHOUTcast/shoutcast-logo1-fs8.png" transparent="1" alphatest="on" /> </screen>""" def __init__(self, session): self.session = session Screen.__init__(self, session) self.CurrentService = self.session.nav.getCurrentlyPlayingServiceReference() self.session.nav.stopService() self["cover"] = Cover() self["key_red"] = StaticText(_("Record")) self["key_green"] = StaticText(_("Genres")) self["key_yellow"] = StaticText(_("Stations")) self["key_blue"] = StaticText(_("Favorites")) self.__event_tracker = ServiceEventTracker(screen=self, eventmap= { iPlayableService.evUpdatedInfo: self.__evUpdatedInfo, iPlayableService.evUser+10: self.__evAudioDecodeError, iPlayableService.evUser+12: self.__evPluginError }) InfoBarSeek.__init__(self, actionmap = "MediaPlayerSeekActions") self.mode = self.FAVORITELIST self["list"] = SHOUTcastList() self["list"].connectSelChanged(self.onSelectionChanged) self["statustext"] = Label(_("Getting SHOUTcast genre list...")) self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions", "EPGSelectActions"], { "ok": self.ok_pressed, "back": self.close, "input_date_time": self.menu_pressed, "red": self.red_pressed, "green": self.green_pressed, "yellow": self.yellow_pressed, "blue": self.blue_pressed, }, -1) self.stationList = [] self.stationListIndex = 0 self.genreList = [] self.genreListIndex = 0 self.favoriteList = [] self.favoriteListIndex = 0 self.favoriteConfig = Config() if os.path.exists(self.FAVORITE_FILE): self.favoriteConfig.loadFromFile(self.FAVORITE_FILE) else: self.favoriteConfig.loadFromFile(self.FAVORITE_FILE_DEFAULT) self.favoriteConfig.entriescount = ConfigInteger(0) self.favoriteConfig.Entries = ConfigSubList() self.initFavouriteConfig() self.stationListXML = "" self["titel"] = Label() self["station"] = Label() self["headertext"] = Label() self["console"] = Label() self.headerTextString = "" self.stationListHeader = "" self.tunein = "" self.searchSHOUTcastString = "" self.currentStreamingURL = "" self.currentStreamingStation = "" self.stationListURL = "" self.onClose.append(self.__onClose) self.onLayoutFinish.append(self.getFavoriteList) self.reloadStationListTimer = eTimer() self.reloadStationListTimer.timeout.get().append(self.reloadStationListTimerTimeout) self.reloadStationListTimerVar = int(config.plugins.shoutcast.reloadstationlist.value) self.visible = True global containerStreamripper if containerStreamripper is None: containerStreamripper = eConsoleAppContainer() containerStreamripper.dataAvail.append(self.streamripperDataAvail) containerStreamripper.appClosed.append(self.streamripperClosed) if containerStreamripper.running(): self["key_red"].setText(_("Stop record")) # just to hear to recording music when starting the plugin... self.currentStreamingStation = _("Recording stream station") self.playServiceStream("http://localhost:9191") def streamripperClosed(self, retval): if retval == 0: self["console"].setText("") self["key_red"].setText(_("Record")) def streamripperDataAvail(self, data): sData = data.replace('\n','') self["console"].setText(sData) def stopReloadStationListTimer(self): if self.reloadStationListTimer.isActive(): self.reloadStationListTimer.stop() def reloadStationListTimerTimeout(self): self.stopReloadStationListTimer() if self.mode == self.STATIONLIST: print "[SHOUTcast] reloadStationList: %s " % self.stationListURL sendUrlCommand(self.stationListURL, None,10).addCallback(self.callbackStationList).addErrback(self.callbackStationListError) def InputBoxStartRecordingCallback(self, returnValue = None): if returnValue: recordingLength = int(returnValue) * 60 if not os.path.exists(config.plugins.shoutcast.dirname.value): os.mkdir(config.plugins.shoutcast.dirname.value) args = [] args.append(self.currentStreamingURL) args.append('-d') args.append(config.plugins.shoutcast.dirname.value) args.append('-r') args.append('9191') if recordingLength != 0: args.append('-l') args.append("%d" % int(recordingLength)) if config.plugins.shoutcast.riptosinglefile.value: args.append('-a') args.append('-A') if not config.plugins.shoutcast.createdirforeachstream.value: args.append('-s') if config.plugins.shoutcast.addsequenceoutputfile.value: args.append('-q') cmd = [self.STREAMRIPPER_BIN, self.STREAMRIPPER_BIN] + args containerStreamripper.execute(*cmd) self["key_red"].setText(_("Stop record")) def deleteRecordingConfirmed(self,val): if val: containerStreamripper.sendCtrlC() def red_pressed(self): if containerStreamripper.running(): self.session.openWithCallback(self.deleteRecordingConfirmed, MessageBox, _("Do you really want to stop the recording?")) else: if len(self.currentStreamingURL) != 0: self.session.openWithCallback(self.InputBoxStartRecordingCallback, InputBox, windowTitle = _("Recording length"), title=_("Enter in minutes (0 means unlimited)"), text="0", type=Input.NUMBER) else: self.session.open(MessageBox, _("Only running streamings can be recorded!"), type = MessageBox.TYPE_INFO,timeout = 20 ) def green_pressed(self): if self.mode != self.GENRELIST: self.stopReloadStationListTimer() self.mode = self.GENRELIST if len(self.genreList): self["headertext"].setText(_("SHOUTcast genre list")) self["list"].setMode(self.mode) self["list"].setList([ (x,) for x in self.genreList]) self["list"].moveToIndex(self.genreListIndex) else: self.getGenreList() else: self.getGenreList() def yellow_pressed(self): if self.mode != self.STATIONLIST: if len(self.stationList): self.mode = self.STATIONLIST self.headerTextString = _("SHOUTcast station list for %s") % self.stationListHeader self["headertext"].setText(self.headerTextString) self["list"].setMode(self.mode) self["list"].setList([ (x,) for x in self.stationList]) self["list"].moveToIndex(self.stationListIndex) if self.reloadStationListTimerVar != 0: self.reloadStationListTimer.start(60000 * self.reloadStationListTimerVar) def blue_pressed(self): if self.mode != self.FAVORITELIST: self.stopReloadStationListTimer() self.getFavoriteList(self.favoriteListIndex) def getFavoriteList(self, favoriteListIndex = 0): self["statustext"].setText("") self.headerTextString = _("Favorite list") self["headertext"].setText(self.headerTextString) self.mode = self.FAVORITELIST self["list"].setMode(self.mode) favoriteList = [] for item in self.favoriteConfig.Entries: favoriteList.append(Favorite(configItem=item)) self["list"].setList([ (x,) for x in favoriteList]) if len(favoriteList): self["list"].moveToIndex(favoriteListIndex) self["list"].show() def getGenreList(self): self["headertext"].setText("") self["statustext"].setText(_("Getting SHOUTcast genre list...")) self["list"].hide() url = "http://yp.shoutcast.com/sbin/newxml.phtml" sendUrlCommand(url, None,10).addCallback(self.callbackGenreList).addErrback(self.callbackGenreListError) def callbackGenreList(self, xmlstring): self["headertext"].setText(_("SHOUTcast genre list")) self.genreListIndex = 0 self.mode = self.GENRELIST self["list"].setMode(self.mode) self.genreList = self.fillGenreList(xmlstring) self["statustext"].setText("") self["list"].setList([ (x,) for x in self.genreList]) if len(self.genreList): self["list"].moveToIndex(self.genreListIndex) self["list"].show() def callbackGenreListError(self, error = None): if error is not None: try: self["list"].hide() self["statustext"].setText(_("%s\nPress green-button to try again...") % str(error.getErrorMessage())) except: pass def fillGenreList(self,xmlstring): genreList = [] try: root = xml.etree.cElementTree.fromstring(xmlstring) except: return [] for childs in root.findall("genre"): genreList.append(SHOUTcastGenre(name = childs.get("name"))) return genreList def onSelectionChanged(self): pass # till I find a better solution # if self.mode == self.STATIONLIST: # self.stationListIndex = self["list"].getCurrentIndex() # elif self.mode == self.FAVORITELIST: # self.favoriteListIndex = self["list"].getCurrentIndex() # elif self.mode == self.GENRELIST: # self.genreListIndex = self["list"].getCurrentIndex() def ok_pressed(self): if self.visible: sel = None try: sel = self["list"].l.getCurrentSelection()[0] except:return if sel is None: return else: if self.mode == self.GENRELIST: self.genreListIndex = self["list"].getCurrentIndex() self.getStationList(sel.name) elif self.mode == self.STATIONLIST: self.stationListIndex = self["list"].getCurrentIndex() self.stopPlaying() url = "http://yp.shoutcast.com%s?id=%s" % (self.tunein, sel.id) self["list"].hide() self["statustext"].setText(_("Getting streaming data from\n%s") % sel.name) self.currentStreamingStation = sel.name sendUrlCommand(url, None,10).addCallback(self.callbackPLS).addErrback(self.callbackStationListError) elif self.mode == self.FAVORITELIST: self.favoriteListIndex = self["list"].getCurrentIndex() if sel.configItem.type.value == "url": self.stopPlaying() self["headertext"].setText(self.headerTextString) self.currentStreamingStation = sel.configItem.name.value self.playServiceStream(sel.configItem.text.value) elif sel.configItem.type.value == "pls": self.stopPlaying() url = sel.configItem.text.value self["list"].hide() self["statustext"].setText(_("Getting streaming data from\n%s") % sel.configItem.name.value) self.currentStreamingStation = sel.configItem.name.value sendUrlCommand(url, None,10).addCallback(self.callbackPLS).addErrback(self.callbackStationListError) elif sel.configItem.type.value == "genre": self.getStationList(sel.configItem.name.value) elif self.mode == self.SEARCHLIST and self.searchSHOUTcastString != "": self.searchSHOUTcast(self.searchSHOUTcastString) else: self.showWindow() def stopPlaying(self): self.currentStreamingURL = "" self.currentStreamingStation = "" self["headertext"].setText("") self["titel"].setText("") self["station"].setText("") self.summaries.setText("") self["cover"].hide() self.session.nav.stopService() def callbackPLS(self, result): self["headertext"].setText(self.headerTextString) found = False parts = string.split(result,"\n") for lines in parts: if lines.find("File1=") != -1: line = string.split(lines,"File1=") found = True self.playServiceStream(line[-1].rstrip().strip()) if found: self["statustext"].setText("") self["list"].show() else: self.currentStreamingStation = "" self["statustext"].setText(_("No streaming data found...")) def getStationList(self,genre): self.stationListHeader = _("genre %s") % genre self.headerTextString = _("SHOUTcast station list for %s") % self.stationListHeader self["headertext"].setText("") self["statustext"].setText(_("Getting %s") % self.headerTextString) self["list"].hide() self.stationListURL = "http://yp.shoutcast.com/sbin/newxml.phtml?genre=%s" % genre self.stationListIndex = 0 sendUrlCommand(self.stationListURL, None,10).addCallback(self.callbackStationList).addErrback(self.callbackStationListError) def callbackStationList(self, xmlstring): self.searchSHOUTcastString = "" self.stationListXML = xmlstring self["headertext"].setText(self.headerTextString) self.mode = self.STATIONLIST self["list"].setMode(self.mode) self.stationList = self.fillStationList(xmlstring) self["statustext"].setText("") self["list"].setList([ (x,) for x in self.stationList]) if len(self.stationList): self["list"].moveToIndex(self.stationListIndex) self["list"].show() if self.reloadStationListTimerVar != 0: self.reloadStationListTimer.start(1000 * 60) def fillStationList(self,xmlstring): stationList = [] try: root = xml.etree.cElementTree.fromstring(xmlstring) except: return [] config_bitrate = int(config.plugins.shoutcast.streamingrate.value) for childs in root.findall("tunein"): self.tunein = childs.get("base") for childs in root.findall("station"): try: bitrate = int(childs.get("br")) except: bitrate = 0 if bitrate >= config_bitrate: stationList.append(SHOUTcastStation(name = childs.get("name"), mt = childs.get("mt"), id = childs.get("id"), br = childs.get("br"), genre = childs.get("genre"), ct = childs.get("ct"), lc = childs.get("lc"))) return stationList def menu_pressed(self): if not self.visible: self.showWindow() options = [(_("Config"), self.config),(_("Search"), self.search),] if self.mode == self.FAVORITELIST and self.getSelectedItem() is not None: options.extend(((_("rename current selected favorite"), self.renameFavorite),)) options.extend(((_("remove current selected favorite"), self.removeFavorite),)) elif self.mode == self.GENRELIST and self.getSelectedItem() is not None: options.extend(((_("Add current selected genre to favorite"), self.addGenreToFavorite),)) elif self.mode == self.STATIONLIST and self.getSelectedItem() is not None: options.extend(((_("Add current selected station to favorite"), self.addStationToFavorite),)) if len(self.currentStreamingURL) != 0: options.extend(((_("Add current playing stream to favorite"), self.addCurrentStreamToFavorite),)) options.extend(((_("Hide"), self.hideWindow),)) self.session.openWithCallback(self.menuCallback, ChoiceBox,list = options) def menuCallback(self, ret): ret and ret[1]() def hideWindow(self): self.visible = False self.hide() def showWindow(self): self.visible = True self.show() def addGenreToFavorite(self): sel = self.getSelectedItem() if sel is not None: self.addFavorite(name = sel.name, text = sel.name, favoritetype = "genre") def addStationToFavorite(self): sel = self.getSelectedItem() if sel is not None: self.addFavorite(name = sel.name, text = "http://yp.shoutcast.com%s?id=%s" % (self.tunein, sel.id), favoritetype = "pls", audio = sel.mt, bitrate = sel.br) def addCurrentStreamToFavorite(self): self.addFavorite(name = self.currentStreamingStation, text = self.currentStreamingURL, favoritetype = "url") def addFavorite(self, name = "", text = "", favoritetype = "", audio = "", bitrate = ""): self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value + 1 self.favoriteConfig.entriescount.save() newFavorite = self.initFavouriteEntryConfig() newFavorite.name.value = name newFavorite.text.value = text newFavorite.type.value = favoritetype newFavorite.audio.value = audio newFavorite.bitrate.value = bitrate newFavorite.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) def renameFavorite(self): sel = self.getSelectedItem() if sel is not None: self.session.openWithCallback(self.renameFavoriteFinished, VirtualKeyBoard, title = _("Enter new name for favorite item"), text = sel.configItem.name.value) def renameFavoriteFinished(self, text = None): if text: sel = self.getSelectedItem() sel.configItem.name.value = text sel.configItem.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) self.favoriteListIndex = 0 self.getFavoriteList() def removeFavorite(self): sel = self.getSelectedItem() if sel is not None: self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value - 1 self.favoriteConfig.entriescount.save() self.favoriteConfig.Entries.remove(sel.configItem) self.favoriteConfig.Entries.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) self.favoriteListIndex = 0 self.getFavoriteList() def search(self): self.session.openWithCallback(self.searchSHOUTcast, VirtualKeyBoard, title = _("Enter text to search for")) def searchSHOUTcast(self, searchstring = None): if searchstring: self.stopReloadStationListTimer() self.stationListHeader = _("search-criteria %s") % searchstring self.headerTextString = _("SHOUTcast station list for %s") % self.stationListHeader self["headertext"].setText("") self["statustext"].setText(_("Searching SHOUTcast for %s...") % searchstring) self["list"].hide() self.stationListURL = "http://yp.shoutcast.com/sbin/newxml.phtml?search=%s" % searchstring self.mode = self.SEARCHLIST self.searchSHOUTcastString = searchstring self.stationListIndex = 0 sendUrlCommand(self.stationListURL, None,10).addCallback(self.callbackStationList).addErrback(self.callbackStationListError) def config(self): self.stopReloadStationListTimer() self.session.openWithCallback(self.setupFinished, SHOUTcastSetup) def setupFinished(self, result): if result: if self.mode == self.STATIONLIST: self.reloadStationListTimerVar = int(config.plugins.shoutcast.reloadstationlist.value) self.stationListIndex = 0 self.callbackStationList(self.stationListXML) def callbackStationListError(self, error = None): if error is not None: try: self["list"].hide() self["statustext"].setText(_("%s\nPress OK to try again...") % str(error.getErrorMessage())) except: pass def Error(self, error = None): if error is not None: try: self["list"].hide() self["statustext"].setText(str(error.getErrorMessage())) except: pass def __onClose(self): self.stopReloadStationListTimer() self.session.nav.playService(self.CurrentService) containerStreamripper.dataAvail.remove(self.streamripperDataAvail) containerStreamripper.appClosed.remove(self.streamripperClosed) def GoogleImageCallback(self, result): foundPos = result.find("imgres?imgurl=") foundPos2 = result.find("&imgrefurl=") if foundPos != -1 and foundPos2 != -1: print "[SHOUTcast] downloading cover from %s " % result[foundPos+14:foundPos2] downloadPage(result[foundPos+14:foundPos2] ,"/tmp/.cover").addCallback(self.coverDownloadFinished).addErrback(self.coverDownloadFailed) def coverDownloadFailed(self,result): print "[SHOUTcast] cover download failed: %s " % result self["cover"].hide() def coverDownloadFinished(self,result): print "[SHOUTcast] cover download finished" self["cover"].updateIcon("/tmp/.cover") self["cover"].show() def __evUpdatedInfo(self): sTitle = "" currPlay = self.session.nav.getCurrentService() if currPlay is not None: sTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle) if (len(sTitle) !=0): url = "http://images.google.de/images?q=%s&btnG=Bilder-Suche" % quote(sTitle) sendUrlCommand(url, None,10).addCallback(self.GoogleImageCallback).addErrback(self.Error) if len(sTitle) == 0: sTitle = "n/a" title = _("Title: %s") % sTitle self["titel"].setText(title) self.summaries.setText(title) def __evAudioDecodeError(self): currPlay = self.session.nav.getCurrentService() sAudioType = currPlay.info().getInfoString(iServiceInformation.sUser+10) print "[SHOUTcast __evAudioDecodeError] audio-codec %s can't be decoded by hardware" % (sAudioType) self.session.open(MessageBox, _("This Dreambox can't decode %s streams!") % sAudioType, type = MessageBox.TYPE_INFO,timeout = 20 ) def __evPluginError(self): currPlay = self.session.nav.getCurrentService() message = currPlay.info().getInfoString(iServiceInformation.sUser+12) print "[SHOUTcast __evPluginError]" , message self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 ) def doEofInternal(self, playing): self.stopPlaying() def checkSkipShowHideLock(self): # nothing to do here pass def playServiceStream(self, url): self.session.nav.stopService() sref = eServiceReference(4097, 0, url) self.session.nav.playService(sref) self.currentStreamingURL = url self["titel"].setText(_("Title: n/a")) self["station"].setText(_("Station: %s") % self.currentStreamingStation) def createSummary(self): return SHOUTcastLCDScreen def initFavouriteEntryConfig(self): self.favoriteConfig.Entries.append(ConfigSubsection()) i = len(self.favoriteConfig.Entries) -1 self.favoriteConfig.Entries[i].name = ConfigText(default = "") self.favoriteConfig.Entries[i].text = ConfigText(default = "") self.favoriteConfig.Entries[i].type = ConfigText(default = "") self.favoriteConfig.Entries[i].audio = ConfigText(default = "") self.favoriteConfig.Entries[i].bitrate = ConfigText(default = "") return self.favoriteConfig.Entries[i] def initFavouriteConfig(self): count = self.favoriteConfig.entriescount.value if count != 0: i = 0 while i < count: self.initFavouriteEntryConfig() i += 1 def getSelectedItem(self): sel = None try: sel = self["list"].l.getCurrentSelection()[0] except:return None return sel
class SHOUTcastWidget(Screen, InfoBarSeek): GENRELIST = 0 STATIONLIST = 1 FAVORITELIST = 2 SEARCHLIST = 3 STREAMRIPPER_BIN = '/usr/bin/streamripper' FAVORITE_FILE_DEFAULT = '/usr/lib/enigma2/python/Plugins/Extensions/SHOUTcast/favorites' FAVORITE_FILE = '/usr/lib/enigma2/python/Plugins/Extensions/SHOUTcast/favorites.user' sz_w = getDesktop(0).size().width() - 90 sz_h = getDesktop(0).size().height() - 100 skin = """ <screen name="SHOUTcastWidget" position="center,65" title="%s" size="%d,%d"> <ePixmap position="5,0" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" /> <ePixmap position="150,0" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" /> <ePixmap position="295,0" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" /> <ePixmap position="440,0" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" /> <ePixmap pixmap="skin_default/buttons/key_menu.png" position="585,10" zPosition="0" size="35,25" alphatest="on" /> <widget render="Label" source="key_red" position="5,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_green" position="150,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_yellow" position="295,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_blue" position="440,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget name="headertext" position="5,47" zPosition="1" size="%d,23" font="Regular;20" transparent="1" backgroundColor="#00000000"/> <widget name="statustext" position="5,240" zPosition="1" size="%d,90" font="Regular;20" halign="center" valign="center" transparent="0" backgroundColor="#00000000"/> <widget name="list" position="5,80" zPosition="2" size="%d,%d" scrollbarMode="showOnDemand" transparent="0" backgroundColor="#00000000"/> <widget name="titel" position="115,%d" zPosition="1" size="%d,40" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="station" position="115,%d" zPosition="1" size="%d,40" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="console" position="115,%d" zPosition="1" size="%d,40" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="cover" zPosition="2" position="5,%d" size="102,110" alphatest="blend" /> <ePixmap position="%d,41" zPosition="4" size="120,35" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/SHOUTcast/shoutcast-logo1-fs8.png" transparent="1" alphatest="on" /> </screen>""" %( config.plugins.shoutcast.name.value + " " + _("Ver.") + " " + shoutcast_pluginversion, # title sz_w, sz_h, # size sz_w - 135, # size headertext sz_w - 100, # size statustext sz_w - 10, sz_h - 205, # size list sz_h - 105, # position titel sz_w - 125, # size titel sz_h - 70, # position station sz_w - 125, # size station sz_h - 25, # position console sz_w - 125, # size console sz_h - 105, # position cover sz_w - 125, # position logo ) def __init__(self, session): self.session = session Screen.__init__(self, session) self.CurrentService = self.session.nav.getCurrentlyPlayingServiceReference() self.session.nav.stopService() self["cover"] = Cover() self["key_red"] = StaticText(_("Record")) self["key_green"] = StaticText(_("Genres")) self["key_yellow"] = StaticText(_("Stations")) self["key_blue"] = StaticText(_("Favorites")) self.__event_tracker = ServiceEventTracker(screen=self, eventmap= { iPlayableService.evUpdatedInfo: self.__evUpdatedInfo, iPlayableService.evUser+10: self.__evAudioDecodeError, iPlayableService.evUser+12: self.__evPluginError }) InfoBarSeek.__init__(self, actionmap = "MediaPlayerSeekActions") self.mode = self.FAVORITELIST self["list"] = SHOUTcastList() self["list"].connectSelChanged(self.onSelectionChanged) self["statustext"] = Label(_("Getting SHOUTcast genre list...")) self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions", "EPGSelectActions"], { "ok": self.ok_pressed, "back": self.close, "input_date_time": self.menu_pressed, "red": self.red_pressed, "green": self.green_pressed, "yellow": self.yellow_pressed, "blue": self.blue_pressed, }, -1) self.stationList = [] self.stationListIndex = 0 self.genreList = [] self.genreListIndex = 0 self.favoriteList = [] self.favoriteListIndex = 0 self.favoriteConfig = Config() if os.path.exists(self.FAVORITE_FILE): self.favoriteConfig.loadFromFile(self.FAVORITE_FILE) else: self.favoriteConfig.loadFromFile(self.FAVORITE_FILE_DEFAULT) self.favoriteConfig.entriescount = ConfigInteger(0) self.favoriteConfig.Entries = ConfigSubList() self.initFavouriteConfig() self.stationListXML = "" self["titel"] = Label() self["station"] = Label() self["headertext"] = Label() self["console"] = Label() self.headerTextString = "" self.stationListHeader = "" self.tunein = "" self.searchSHOUTcastString = "" self.currentStreamingURL = "" self.currentStreamingStation = "" self.stationListURL = "" self.onClose.append(self.__onClose) self.onLayoutFinish.append(self.getFavoriteList) self.reloadStationListTimer = eTimer() self.reloadStationListTimer.timeout.get().append(self.reloadStationListTimerTimeout) self.reloadStationListTimerVar = int(config.plugins.shoutcast.reloadstationlist.value) self.visible = True global containerStreamripper if containerStreamripper is None: containerStreamripper = eConsoleAppContainer() containerStreamripper.dataAvail.append(self.streamripperDataAvail) containerStreamripper.appClosed.append(self.streamripperClosed) if containerStreamripper.running(): self["key_red"].setText(_("Stop record")) # just to hear to recording music when starting the plugin... self.currentStreamingStation = _("Recording stream station") self.playServiceStream("http://localhost:9191") def streamripperClosed(self, retval): if retval == 0: self["console"].setText("") self["key_red"].setText(_("Record")) def streamripperDataAvail(self, data): sData = data.replace('\n','') self["console"].setText(sData) def stopReloadStationListTimer(self): if self.reloadStationListTimer.isActive(): self.reloadStationListTimer.stop() def reloadStationListTimerTimeout(self): self.stopReloadStationListTimer() if self.mode == self.STATIONLIST: print "[SHOUTcast] reloadStationList: %s " % self.stationListURL sendUrlCommand(self.stationListURL, None,10).addCallback(self.callbackStationList).addErrback(self.callbackStationListError) def InputBoxStartRecordingCallback(self, returnValue = None): if returnValue: recordingLength = int(returnValue) * 60 if not os.path.exists(config.plugins.shoutcast.dirname.value): os.mkdir(config.plugins.shoutcast.dirname.value) args = [] args.append(self.currentStreamingURL) args.append('-d') args.append(config.plugins.shoutcast.dirname.value) args.append('-r') args.append('9191') if recordingLength != 0: args.append('-l') args.append("%d" % int(recordingLength)) if config.plugins.shoutcast.riptosinglefile.value: args.append('-a') args.append('-A') if not config.plugins.shoutcast.createdirforeachstream.value: args.append('-s') if config.plugins.shoutcast.addsequenceoutputfile.value: args.append('-q') cmd = [self.STREAMRIPPER_BIN, self.STREAMRIPPER_BIN] + args containerStreamripper.execute(*cmd) self["key_red"].setText(_("Stop record")) def deleteRecordingConfirmed(self,val): if val: containerStreamripper.sendCtrlC() def red_pressed(self): if containerStreamripper.running(): self.session.openWithCallback(self.deleteRecordingConfirmed, MessageBox, _("Do you really want to stop the recording?")) else: if len(self.currentStreamingURL) != 0: self.session.openWithCallback(self.InputBoxStartRecordingCallback, InputBox, windowTitle = _("Recording length"), title=_("Enter in minutes (0 means unlimited)"), text="0", type=Input.NUMBER) else: self.session.open(MessageBox, _("Only running streamings can be recorded!"), type = MessageBox.TYPE_INFO,timeout = 20 ) def green_pressed(self): if self.mode != self.GENRELIST: self.stopReloadStationListTimer() self.mode = self.GENRELIST if len(self.genreList): self["headertext"].setText(_("SHOUTcast genre list")) self["list"].setMode(self.mode) self["list"].setList([ (x,) for x in self.genreList]) self["list"].moveToIndex(self.genreListIndex) else: self.getGenreList() else: self.getGenreList() def yellow_pressed(self): if self.mode != self.STATIONLIST: if len(self.stationList): self.mode = self.STATIONLIST self.headerTextString = _("SHOUTcast station list for %s") % self.stationListHeader self["headertext"].setText(self.headerTextString) self["list"].setMode(self.mode) self["list"].setList([ (x,) for x in self.stationList]) self["list"].moveToIndex(self.stationListIndex) if self.reloadStationListTimerVar != 0: self.reloadStationListTimer.start(60000 * self.reloadStationListTimerVar) def blue_pressed(self): if self.mode != self.FAVORITELIST: self.stopReloadStationListTimer() self.getFavoriteList(self.favoriteListIndex) def getFavoriteList(self, favoriteListIndex = 0): self["statustext"].setText("") self.headerTextString = _("Favorite list") self["headertext"].setText(self.headerTextString) self.mode = self.FAVORITELIST self["list"].setMode(self.mode) favoriteList = [] for item in self.favoriteConfig.Entries: favoriteList.append(Favorite(configItem=item)) self["list"].setList([ (x,) for x in favoriteList]) if len(favoriteList): self["list"].moveToIndex(favoriteListIndex) self["list"].show() def getGenreList(self): self["headertext"].setText("") self["statustext"].setText(_("Getting SHOUTcast genre list...")) self["list"].hide() url = "http://yp.shoutcast.com/sbin/newxml.phtml" sendUrlCommand(url, None,10).addCallback(self.callbackGenreList).addErrback(self.callbackGenreListError) def callbackGenreList(self, xmlstring): self["headertext"].setText(_("SHOUTcast genre list")) self.genreListIndex = 0 self.mode = self.GENRELIST self["list"].setMode(self.mode) self.genreList = self.fillGenreList(xmlstring) self["statustext"].setText("") self["list"].setList([ (x,) for x in self.genreList]) if len(self.genreList): self["list"].moveToIndex(self.genreListIndex) self["list"].show() def callbackGenreListError(self, error = None): if error is not None: try: self["list"].hide() self["statustext"].setText(_("%s\nPress green-button to try again...") % str(error.getErrorMessage())) except: pass def fillGenreList(self,xmlstring): genreList = [] try: root = xml.etree.cElementTree.fromstring(xmlstring) except: return [] for childs in root.findall("genre"): genreList.append(SHOUTcastGenre(name = childs.get("name"))) return genreList def onSelectionChanged(self): pass # till I find a better solution # if self.mode == self.STATIONLIST: # self.stationListIndex = self["list"].getCurrentIndex() # elif self.mode == self.FAVORITELIST: # self.favoriteListIndex = self["list"].getCurrentIndex() # elif self.mode == self.GENRELIST: # self.genreListIndex = self["list"].getCurrentIndex() def ok_pressed(self): if self.visible: sel = None try: sel = self["list"].l.getCurrentSelection()[0] except:return if sel is None: return else: if self.mode == self.GENRELIST: self.genreListIndex = self["list"].getCurrentIndex() self.getStationList(sel.name) elif self.mode == self.STATIONLIST: self.stationListIndex = self["list"].getCurrentIndex() self.stopPlaying() url = "http://yp.shoutcast.com%s?id=%s" % (self.tunein, sel.id) self["list"].hide() self["statustext"].setText(_("Getting streaming data from\n%s") % sel.name) self.currentStreamingStation = sel.name sendUrlCommand(url, None,10).addCallback(self.callbackPLS).addErrback(self.callbackStationListError) elif self.mode == self.FAVORITELIST: self.favoriteListIndex = self["list"].getCurrentIndex() if sel.configItem.type.value == "url": self.stopPlaying() self["headertext"].setText(self.headerTextString) self.currentStreamingStation = sel.configItem.name.value self.playServiceStream(sel.configItem.text.value) elif sel.configItem.type.value == "pls": self.stopPlaying() url = sel.configItem.text.value self["list"].hide() self["statustext"].setText(_("Getting streaming data from\n%s") % sel.configItem.name.value) self.currentStreamingStation = sel.configItem.name.value sendUrlCommand(url, None,10).addCallback(self.callbackPLS).addErrback(self.callbackStationListError) elif sel.configItem.type.value == "genre": self.getStationList(sel.configItem.name.value) elif self.mode == self.SEARCHLIST and self.searchSHOUTcastString != "": self.searchSHOUTcast(self.searchSHOUTcastString) else: self.showWindow() def stopPlaying(self): self.currentStreamingURL = "" self.currentStreamingStation = "" self["headertext"].setText("") self["titel"].setText("") self["station"].setText("") self.summaries.setText("") self["cover"].hide() self.session.nav.stopService() def callbackPLS(self, result): self["headertext"].setText(self.headerTextString) found = False parts = string.split(result,"\n") for lines in parts: if lines.find("File1=") != -1: line = string.split(lines,"File1=") found = True self.playServiceStream(line[-1].rstrip().strip()) if found: self["statustext"].setText("") self["list"].show() else: self.currentStreamingStation = "" self["statustext"].setText(_("No streaming data found...")) def getStationList(self,genre): self.stationListHeader = _("genre %s") % genre self.headerTextString = _("SHOUTcast station list for %s") % self.stationListHeader self["headertext"].setText("") self["statustext"].setText(_("Getting %s") % self.headerTextString) self["list"].hide() self.stationListURL = "http://yp.shoutcast.com/sbin/newxml.phtml?genre=%s" % genre self.stationListIndex = 0 sendUrlCommand(self.stationListURL, None,10).addCallback(self.callbackStationList).addErrback(self.callbackStationListError) def callbackStationList(self, xmlstring): self.searchSHOUTcastString = "" self.stationListXML = xmlstring self["headertext"].setText(self.headerTextString) self.mode = self.STATIONLIST self["list"].setMode(self.mode) self.stationList = self.fillStationList(xmlstring) self["statustext"].setText("") self["list"].setList([ (x,) for x in self.stationList]) if len(self.stationList): self["list"].moveToIndex(self.stationListIndex) self["list"].show() if self.reloadStationListTimerVar != 0: self.reloadStationListTimer.start(1000 * 60) def fillStationList(self,xmlstring): stationList = [] try: root = xml.etree.cElementTree.fromstring(xmlstring) except: return [] config_bitrate = int(config.plugins.shoutcast.streamingrate.value) for childs in root.findall("tunein"): self.tunein = childs.get("base") for childs in root.findall("station"): try: bitrate = int(childs.get("br")) except: bitrate = 0 if bitrate >= config_bitrate: stationList.append(SHOUTcastStation(name = childs.get("name"), mt = childs.get("mt"), id = childs.get("id"), br = childs.get("br"), genre = childs.get("genre"), ct = childs.get("ct"), lc = childs.get("lc"))) return stationList def menu_pressed(self): if not self.visible: self.showWindow() options = [(_("Config"), self.config),(_("Search"), self.search),] if self.mode == self.FAVORITELIST and self.getSelectedItem() is not None: options.extend(((_("rename current selected favorite"), self.renameFavorite),)) options.extend(((_("remove current selected favorite"), self.removeFavorite),)) elif self.mode == self.GENRELIST and self.getSelectedItem() is not None: options.extend(((_("Add current selected genre to favorite"), self.addGenreToFavorite),)) elif self.mode == self.STATIONLIST and self.getSelectedItem() is not None: options.extend(((_("Add current selected station to favorite"), self.addStationToFavorite),)) if len(self.currentStreamingURL) != 0: options.extend(((_("Add current playing stream to favorite"), self.addCurrentStreamToFavorite),)) options.extend(((_("Hide"), self.hideWindow),)) self.session.openWithCallback(self.menuCallback, ChoiceBox,list = options) def menuCallback(self, ret): ret and ret[1]() def hideWindow(self): self.visible = False self.hide() def showWindow(self): self.visible = True self.show() def addGenreToFavorite(self): sel = self.getSelectedItem() if sel is not None: self.addFavorite(name = sel.name, text = sel.name, favoritetype = "genre") def addStationToFavorite(self): sel = self.getSelectedItem() if sel is not None: self.addFavorite(name = sel.name, text = "http://yp.shoutcast.com%s?id=%s" % (self.tunein, sel.id), favoritetype = "pls", audio = sel.mt, bitrate = sel.br) def addCurrentStreamToFavorite(self): self.addFavorite(name = self.currentStreamingStation, text = self.currentStreamingURL, favoritetype = "url") def addFavorite(self, name = "", text = "", favoritetype = "", audio = "", bitrate = ""): self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value + 1 self.favoriteConfig.entriescount.save() newFavorite = self.initFavouriteEntryConfig() newFavorite.name.value = name newFavorite.text.value = text newFavorite.type.value = favoritetype newFavorite.audio.value = audio newFavorite.bitrate.value = bitrate newFavorite.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) def renameFavorite(self): sel = self.getSelectedItem() if sel is not None: self.session.openWithCallback(self.renameFavoriteFinished, VirtualKeyBoard, title = _("Enter new name for favorite item"), text = sel.configItem.name.value) def renameFavoriteFinished(self, text = None): if text: sel = self.getSelectedItem() sel.configItem.name.value = text sel.configItem.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) self.favoriteListIndex = 0 self.getFavoriteList() def removeFavorite(self): sel = self.getSelectedItem() if sel is not None: self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value - 1 self.favoriteConfig.entriescount.save() self.favoriteConfig.Entries.remove(sel.configItem) self.favoriteConfig.Entries.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) self.favoriteListIndex = 0 self.getFavoriteList() def search(self): self.session.openWithCallback(self.searchSHOUTcast, VirtualKeyBoard, title = _("Enter text to search for")) def searchSHOUTcast(self, searchstring = None): if searchstring: self.stopReloadStationListTimer() self.stationListHeader = _("search-criteria %s") % searchstring self.headerTextString = _("SHOUTcast station list for %s") % self.stationListHeader self["headertext"].setText("") self["statustext"].setText(_("Searching SHOUTcast for %s...") % searchstring) self["list"].hide() self.stationListURL = "http://yp.shoutcast.com/sbin/newxml.phtml?search=%s" % searchstring self.mode = self.SEARCHLIST self.searchSHOUTcastString = searchstring self.stationListIndex = 0 sendUrlCommand(self.stationListURL, None,10).addCallback(self.callbackStationList).addErrback(self.callbackStationListError) def config(self): self.stopReloadStationListTimer() self.session.openWithCallback(self.setupFinished, SHOUTcastSetup) def setupFinished(self, result): if result: if self.mode == self.STATIONLIST: self.reloadStationListTimerVar = int(config.plugins.shoutcast.reloadstationlist.value) self.stationListIndex = 0 self.callbackStationList(self.stationListXML) def callbackStationListError(self, error = None): if error is not None: try: self["list"].hide() self["statustext"].setText(_("%s\nPress OK to try again...") % str(error.getErrorMessage())) except: pass def Error(self, error = None): if error is not None: try: self["list"].hide() self["statustext"].setText(str(error.getErrorMessage())) except: pass def __onClose(self): self.stopReloadStationListTimer() self.session.nav.playService(self.CurrentService) containerStreamripper.dataAvail.remove(self.streamripperDataAvail) containerStreamripper.appClosed.remove(self.streamripperClosed) def GoogleImageCallback(self, result): foundPos = result.find("imgres?imgurl=") foundPos2 = result.find("&imgrefurl=") if foundPos != -1 and foundPos2 != -1: print "[SHOUTcast] downloading cover from %s " % result[foundPos+14:foundPos2] downloadPage(result[foundPos+14:foundPos2] ,"/tmp/.cover").addCallback(self.coverDownloadFinished).addErrback(self.coverDownloadFailed) def coverDownloadFailed(self,result): print "[SHOUTcast] cover download failed: %s " % result self["cover"].hide() def coverDownloadFinished(self,result): print "[SHOUTcast] cover download finished" self["cover"].updateIcon("/tmp/.cover") self["cover"].show() def __evUpdatedInfo(self): sTitle = "" currPlay = self.session.nav.getCurrentService() if currPlay is not None: sTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle) if (len(sTitle) !=0): url = "http://images.google.de/images?q=%s&btnG=Bilder-Suche" % quote(sTitle) sendUrlCommand(url, None,10).addCallback(self.GoogleImageCallback).addErrback(self.Error) if len(sTitle) == 0: sTitle = "n/a" title = _("Title: %s") % sTitle self["titel"].setText(title) self.summaries.setText(title) def __evAudioDecodeError(self): currPlay = self.session.nav.getCurrentService() sAudioType = currPlay.info().getInfoString(iServiceInformation.sUser+10) print "[SHOUTcast __evAudioDecodeError] audio-codec %s can't be decoded by hardware" % (sAudioType) self.session.open(MessageBox, _("This Dreambox can't decode %s streams!") % sAudioType, type = MessageBox.TYPE_INFO,timeout = 20 ) def __evPluginError(self): currPlay = self.session.nav.getCurrentService() message = currPlay.info().getInfoString(iServiceInformation.sUser+12) print "[SHOUTcast __evPluginError]" , message self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 ) def doEofInternal(self, playing): self.stopPlaying() def checkSkipShowHideLock(self): # nothing to do here pass def playServiceStream(self, url): self.session.nav.stopService() sref = eServiceReference(4097, 0, url) self.session.nav.playService(sref) self.currentStreamingURL = url self["titel"].setText(_("Title: n/a")) self["station"].setText(_("Station: %s") % self.currentStreamingStation) def createSummary(self): return SHOUTcastLCDScreen def initFavouriteEntryConfig(self): self.favoriteConfig.Entries.append(ConfigSubsection()) i = len(self.favoriteConfig.Entries) -1 self.favoriteConfig.Entries[i].name = ConfigText(default = "") self.favoriteConfig.Entries[i].text = ConfigText(default = "") self.favoriteConfig.Entries[i].type = ConfigText(default = "") self.favoriteConfig.Entries[i].audio = ConfigText(default = "") self.favoriteConfig.Entries[i].bitrate = ConfigText(default = "") return self.favoriteConfig.Entries[i] def initFavouriteConfig(self): count = self.favoriteConfig.entriescount.value if count != 0: i = 0 while i < count: self.initFavouriteEntryConfig() i += 1 def getSelectedItem(self): sel = None try: sel = self["list"].l.getCurrentSelection()[0] except:return None return sel
class SHOUTcastWidget(Screen): GENRELIST = 0 STATIONLIST = 1 FAVORITELIST = 2 SEARCHLIST = 3 STREAMRIPPER_BIN = '/usr/bin/streamripper' SC = 'http://api.shoutcast.com' SCY = 'http://yp.shoutcast.com' FAVORITE_FILE_DEFAULT = '/usr/lib/enigma2/python/Plugins/Extensions/IniSHOUTcast/favorites' FAVORITE_FILE_OLD = '/usr/lib/enigma2/python/Plugins/Extensions/IniSHOUTcast/favorites.user' FAVORITE_FILE = '/etc/enigma2/SHOUTcast.favorites' sz_w = getDesktop(0).size().width() - 90 sz_h = getDesktop(0).size().height() - 95 print "[SHOUTcast] Desktop size %dx%d" % (sz_w+90, sz_h+95) if sz_h < 500: sz_h += 4 skin = """ <screen name="SHOUTcastWidget" position="center,65" title="SHOUTcast" size="%d,%d"> <ePixmap position="5,0" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" /> <ePixmap position="150,0" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" /> <ePixmap position="295,0" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" /> <ePixmap position="440,0" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" /> <ePixmap pixmap="skin_default/buttons/key_menu.png" position="585,10" zPosition="0" size="35,25" alphatest="on" /> <widget render="Label" source="key_red" position="5,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_green" position="150,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_yellow" position="295,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget render="Label" source="key_blue" position="440,0" size="140,40" zPosition="5" valign="center" halign="center" backgroundColor="red" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget name="headertext" position="5,47" zPosition="1" size="%d,23" font="Regular;20" transparent="1" backgroundColor="#00000000"/> <widget name="statustext" position="5,240" zPosition="1" size="%d,90" font="Regular;20" halign="center" valign="center" transparent="0" backgroundColor="#00000000"/> <widget name="list" position="5,80" zPosition="2" size="%d,%d" scrollbarMode="showOnDemand" transparent="0" backgroundColor="#00000000"/> <widget name="titel" position="115,%d" zPosition="1" size="%d,40" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="station" position="115,%d" zPosition="1" size="%d,40" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="console" position="115,%d" zPosition="1" size="%d,40" font="Regular;18" transparent="1" backgroundColor="#00000000"/> <widget name="cover" zPosition="2" position="5,%d" size="102,110" alphatest="blend" /> <ePixmap position="%d,41" zPosition="4" size="120,35" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/IniSHOUTcast/shoutcast-logo1-fs8.png" transparent="1" alphatest="on" /> </screen>""" %( sz_w, sz_h, # size sz_w - 135, # size headertext sz_w - 100, # size statustext sz_w - 10, sz_h - 205, # size list sz_h - 105, # position titel sz_w - 125, # size titel sz_h - 70, # position station sz_w - 125, # size station sz_h - 25, # position console sz_w - 125, # size console sz_h - 105, # position cover sz_w - 125, # position logo ) def __init__(self, session): self.session = session Screen.__init__(self, session) self.oldtitle = None self.currentcoverfile = 0 self.currentGoogle = None self.nextGoogle = None self.currPlay = None self.CurrentService = self.session.nav.getCurrentlyPlayingServiceReference() self.session.nav.stopService() self.session.nav.event.append(self.__event) self["cover"] = Cover() self["key_red"] = StaticText(_("Record")) self["key_green"] = StaticText(_("Genres")) self["key_yellow"] = StaticText(_("Stations")) self["key_blue"] = StaticText(_("Favorites")) self.mode = self.FAVORITELIST self["list"] = SHOUTcastList() self["list"].connectSelChanged(self.onSelectionChanged) self["statustext"] = Label(_("Getting SHOUTcast genre list...")) self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions", "EPGSelectActions"], { "ok": self.ok_pressed, "back": self.close, "menu": self.menu_pressed, "red": self.red_pressed, "green": self.green_pressed, "yellow": self.yellow_pressed, "blue": self.blue_pressed, }, -1) self.stationList = [] self.stationListIndex = 0 self.genreList = [] self.genreListIndex = 0 self.favoriteList = [] self.favoriteListIndex = 0 self.favoriteConfig = Config() if os.path.exists(self.FAVORITE_FILE): self.favoriteConfig.loadFromFile(self.FAVORITE_FILE) elif os.path.exists(self.FAVORITE_FILE_OLD): self.favoriteConfig.loadFromFile(self.FAVORITE_FILE_OLD) else: self.favoriteConfig.loadFromFile(self.FAVORITE_FILE_DEFAULT) self.favoriteConfig.entriescount = ConfigInteger(0) self.favoriteConfig.Entries = ConfigSubList() self.initFavouriteConfig() self.stationListXML = "" self["titel"] = Label() self["station"] = Label() self["headertext"] = Label() self["console"] = Label() self.headerTextString = "" self.stationListHeader = "" self.tunein = "" self.searchSHOUTcastString = "" self.currentStreamingURL = "" self.currentStreamingStation = "" self.stationListURL = "" self.onClose.append(self.__onClose) self.onLayoutFinish.append(self.getFavoriteList) self.reloadStationListTimer = eTimer() self.reloadStationListTimer.timeout.get().append(self.reloadStationListTimerTimeout) self.reloadStationListTimerVar = int(config.plugins.shoutcast.reloadstationlist.value) self.visible = True global containerStreamripper if containerStreamripper is None: containerStreamripper = eConsoleAppContainer() containerStreamripper.dataAvail.append(self.streamripperDataAvail) containerStreamripper.appClosed.append(self.streamripperClosed) if containerStreamripper.running(): self["key_red"].setText(_("Stop record")) # just to hear to recording music when starting the plugin... self.currentStreamingStation = _("Recording stream station") self.playServiceStream("http://localhost:9191") def streamripperClosed(self, retval): if retval == 0: self["console"].setText("") self["key_red"].setText(_("Record")) def streamripperDataAvail(self, data): sData = data.replace('\n','') self["console"].setText(sData) def stopReloadStationListTimer(self): if self.reloadStationListTimer.isActive(): self.reloadStationListTimer.stop() def reloadStationListTimerTimeout(self): self.stopReloadStationListTimer() if self.mode == self.STATIONLIST: # print "[SHOUTcast] reloadStationList: %s" % self.stationListURL sendUrlCommand(self.stationListURL, None,10).addCallback(self.callbackStationList).addErrback(self.callbackStationListError) def InputBoxStartRecordingCallback(self, returnValue = None): if returnValue: recordingLength = int(returnValue) * 60 if not os.path.exists(config.plugins.shoutcast.dirname.value): os.mkdir(config.plugins.shoutcast.dirname.value) args = [] args.append(self.currentStreamingURL) args.append('-d') args.append(config.plugins.shoutcast.dirname.value) args.append('-r') args.append('9191') args.append('-u') args.append('Enigma2 HbbTV/1.1.1 (+PVR+RTSP+DL;Beyonwiz;;;)') if recordingLength != 0: args.append('-l') args.append("%d" % int(recordingLength)) if config.plugins.shoutcast.riptosinglefile.value: args.append('-a') args.append('-A') if not config.plugins.shoutcast.createdirforeachstream.value: args.append('-s') if config.plugins.shoutcast.addsequenceoutputfile.value: args.append('-q') cmd = [self.STREAMRIPPER_BIN, self.STREAMRIPPER_BIN] + args containerStreamripper.execute(*cmd) self["key_red"].setText(_("Stop record")) def deleteRecordingConfirmed(self,val): if val: containerStreamripper.sendCtrlC() def red_pressed(self): if containerStreamripper.running(): self.session.openWithCallback(self.deleteRecordingConfirmed, MessageBox, _("Do you really want to stop the recording?")) else: if len(self.currentStreamingURL) != 0: self.session.openWithCallback(self.InputBoxStartRecordingCallback, InputBox, windowTitle = _("Recording length"), title=_("Enter in minutes (0 means unlimited)"), text="0", type=Input.NUMBER) else: self.session.open(MessageBox, _("Only running streamings can be recorded!"), type = MessageBox.TYPE_INFO,timeout = 20 ) def green_pressed(self): if self.mode != self.GENRELIST: self.stopReloadStationListTimer() self.mode = self.GENRELIST if not self.genreList: self.getGenreList() else: self.showGenreList() def yellow_pressed(self): if self.mode != self.STATIONLIST: if len(self.stationList): self.mode = self.STATIONLIST self.headerTextString = _("SHOUTcast station list for %s") % self.stationListHeader self["headertext"].setText(self.headerTextString) self["list"].setMode(self.mode) self["list"].setList([ (x,) for x in self.stationList]) self["list"].moveToIndex(self.stationListIndex) if self.reloadStationListTimerVar != 0: self.reloadStationListTimer.start(60000 * self.reloadStationListTimerVar) def blue_pressed(self): if self.mode != self.FAVORITELIST: self.stopReloadStationListTimer() self.getFavoriteList(self.favoriteListIndex) def getFavoriteList(self, favoriteListIndex = 0): self["statustext"].setText("") self.headerTextString = _("Favorite list") self["headertext"].setText(self.headerTextString) self.mode = self.FAVORITELIST self["list"].setMode(self.mode) favoriteList = [] for item in self.favoriteConfig.Entries: favoriteList.append(Favorite(configItem=item)) self["list"].setList([ (x,) for x in favoriteList]) if len(favoriteList): self["list"].moveToIndex(favoriteListIndex) self["list"].show() def getGenreList(self, genre = "all" , id = 0): self["headertext"].setText("") self["statustext"].setText(_("Getting SHOUTcast genre list for %s..." % genre)) self["list"].hide() if len(devid) > 8: url = self.SC + "/genre/secondary?parentid=%s&k=%s&f=xml" % (id, devid) else: url = "http://207.200.98.1/sbin/newxml.phtml" sendUrlCommand(url, None,10).addCallback(self.callbackGenreList).addErrback(self.callbackGenreListError) def callbackGenreList(self, xmlstring): self["headertext"].setText(_("SHOUTcast genre list")) self.genreListIndex = 0 self.mode = self.GENRELIST self.genreList = self.fillGenreList(xmlstring) self["statustext"].setText("") if not len(self.genreList): self["statustext"].setText(_("Got 0 genres. Could be a network problem.\nPlease try again...")) else: self.showGenreList() def callbackGenreListError(self, error = None): if error is not None: try: self["list"].hide() self["statustext"].setText(_("%s\nPress green-button to try again...") % str(error.getErrorMessage())) except: pass def fillGenreList(self, xmlstring): genreList = [] # print "[SHOUTcast] fillGenreList: %s" % xmlstring try: root = xml.etree.cElementTree.fromstring(xmlstring) except: return [] data = root.find("data") if data == None: print "[SHOUTcast] Could not find data tag, assume flat listing!" return [SHOUTcastGenre(name=childs.get("name")) for childs in root.findall("genre")] for glist in data.findall("genrelist"): for childs in glist.findall("genre"): gn = childs.get("name") gid = childs.get("id") gparentid = childs.get("parentid") ghaschilds = childs.get("haschildren") # print "[SHOUTcast] Genre %s id=%s parent=%s haschilds=%s" % (gn, gid, gparentid, ghaschilds) genreList.append(SHOUTcastGenre(name = gn, id = gid, parentid = gparentid, haschilds = ghaschilds)) if ghaschilds == "true": for childlist in childs.findall("genrelist"): for genre in childlist.findall("genre"): gn = genre.get("name") gid = genre.get("id") gparentid = genre.get("parentid") ghaschilds = genre.get("haschildren") # print "[SHOUTcast] Genre %s id=%s parent=%s haschilds=%s" % (gn, gid, gparentid, ghaschilds) genreList.append(SHOUTcastGenre(name = gn, id = gid, parentid = gparentid, haschilds = ghaschilds)) return genreList def showGenreList(self): self["headertext"].setText(_("SHOUTcast genre list")) self["list"].setMode(self.mode) self["list"].setList([ (x,) for x in self.genreList]) self["list"].moveToIndex(self.genreListIndex) self["list"].show() def onSelectionChanged(self): pass # till I find a better solution # if self.mode == self.STATIONLIST: # self.stationListIndex = self["list"].getCurrentIndex() # elif self.mode == self.FAVORITELIST: # self.favoriteListIndex = self["list"].getCurrentIndex() # elif self.mode == self.GENRELIST: # self.genreListIndex = self["list"].getCurrentIndex() def ok_pressed(self): if self.visible: sel = None try: sel = self["list"].l.getCurrentSelection()[0] except:return if sel is None: return else: if self.mode == self.GENRELIST: self.genreListIndex = self["list"].getCurrentIndex() self.getStationList(sel.name) elif self.mode == self.STATIONLIST: self.stationListIndex = self["list"].getCurrentIndex() self.stopPlaying() if len(devid) > 8: url = self.SCY + "/sbin/tunein-station.pls?id=%s" % (sel.id) self["list"].hide() self["statustext"].setText(_("Getting streaming data from\n%s") % sel.name) self.currentStreamingStation = sel.name sendUrlCommand(url, None, 10).addCallback(self.callbackPLS).addErrback(self.callbackStationListError) elif self.mode == self.FAVORITELIST: self.favoriteListIndex = self["list"].getCurrentIndex() if sel.configItem.type.value == "url": self.stopPlaying() self["headertext"].setText(self.headerTextString) self.currentStreamingStation = sel.configItem.name.value self.playServiceStream(sel.configItem.text.value) elif sel.configItem.type.value == "pls": self.stopPlaying() url = sel.configItem.text.value self["list"].hide() self["statustext"].setText(_("Getting streaming data from\n%s") % sel.configItem.name.value) self.currentStreamingStation = sel.configItem.name.value sendUrlCommand(url, None,10).addCallback(self.callbackPLS).addErrback(self.callbackStationListError) elif sel.configItem.type.value == "genre": self.getStationList(sel.configItem.name.value) elif self.mode == self.SEARCHLIST and self.searchSHOUTcastString != "": self.searchSHOUTcast(self.searchSHOUTcastString) else: self.showWindow() def stopPlaying(self): self.currentStreamingURL = "" self.currentStreamingStation = "" self["headertext"].setText("") self["titel"].setText("") self["station"].setText("") self.summaries.setText("") if config.plugins.shoutcast.showcover.value: self["cover"].doHide() self.session.nav.stopService() def callbackPLS(self, result): self["headertext"].setText(self.headerTextString) found = False parts = string.split(result,"\n") for lines in parts: if lines.find("File1=") != -1: line = string.split(lines,"File1=") found = True self.playServiceStream(line[-1].rstrip().strip()) if found: self["statustext"].setText("") self["list"].show() else: self.currentStreamingStation = "" self["statustext"].setText(_("No streaming data found...")) self["list"].show() def getStationList(self,genre): self.stationListHeader = _("genre %s") % genre self.headerTextString = _("SHOUTcast station list for %s") % self.stationListHeader self["headertext"].setText("") self["statustext"].setText(_("Getting %s") % self.headerTextString) self["list"].hide() if len(devid) > 8: self.stationListURL = self.SC + "/station/advancedsearch&f=xml&k=%s&search=%s" % (devid, genre) else: self.stationListURL = "http://207.200.98.1/sbin/newxml.phtml?genre=%s" % genre self.stationListIndex = 0 sendUrlCommand(self.stationListURL, None, 10).addCallback(self.callbackStationList).addErrback(self.callbackStationListError) def callbackStationList(self, xmlstring): self.searchSHOUTcastString = "" self.stationListXML = xmlstring self["headertext"].setText(self.headerTextString) self.mode = self.STATIONLIST self["list"].setMode(self.mode) self.stationList = self.fillStationList(xmlstring) self["statustext"].setText("") self["list"].setList([ (x,) for x in self.stationList]) if len(self.stationList): self["list"].moveToIndex(self.stationListIndex) self["list"].show() if self.reloadStationListTimerVar != 0: self.reloadStationListTimer.start(1000 * 60) def fillStationList(self,xmlstring): stationList = [] try: root = xml.etree.cElementTree.fromstring(xmlstring) except: return [] config_bitrate = int(config.plugins.shoutcast.streamingrate.value) data = root.find("data") if data == None: print "[SHOUTcast] Could not find data tag!" return [] for slist in data.findall("stationlist"): for childs in slist.findall("tunein"): self.tunein = childs.get("base") for childs in slist.findall("station"): try: bitrate = int(childs.get("br")) except: bitrate = 0 if bitrate >= config_bitrate: stationList.append(SHOUTcastStation(name = childs.get("name"), mt = childs.get("mt"), id = childs.get("id"), br = childs.get("br"), genre = childs.get("genre"), ct = childs.get("ct"), lc = childs.get("lc"), ml = childs.get("ml"), nsc = childs.get("nsc"), cst = childs.get("cst"))) return stationList def menu_pressed(self): if not self.visible: self.showWindow() options = [(_("Config"), self.config),(_("Search"), self.search),] if self.mode == self.FAVORITELIST and self.getSelectedItem() is not None: options.extend(((_("rename current selected favorite"), self.renameFavorite),)) options.extend(((_("remove current selected favorite"), self.removeFavorite),)) elif self.mode == self.GENRELIST and self.getSelectedItem() is not None: options.extend(((_("Add current selected genre to favorite"), self.addGenreToFavorite),)) elif self.mode == self.STATIONLIST and self.getSelectedItem() is not None: options.extend(((_("Add current selected station to favorite"), self.addStationToFavorite),)) if len(self.currentStreamingURL) != 0: options.extend(((_("Add current playing stream to favorite"), self.addCurrentStreamToFavorite),)) options.extend(((_("Hide"), self.hideWindow),)) self.session.openWithCallback(self.menuCallback, ChoiceBox,list = options) def menuCallback(self, ret): ret and ret[1]() def hideWindow(self): self.visible = False self.hide() def showWindow(self): self.visible = True self.show() def addGenreToFavorite(self): sel = self.getSelectedItem() if sel is not None: self.addFavorite(name = sel.name, text = sel.name, favoritetype = "genre") def addStationToFavorite(self): sel = self.getSelectedItem() if sel is not None: self.addFavorite(name = sel.name, text = self.SCY + "/sbin/tunein-station.pls?id=%s" % (sel.id), favoritetype = "pls", audio = sel.mt, bitrate = sel.br) def addCurrentStreamToFavorite(self): self.addFavorite(name = self.currentStreamingStation, text = self.currentStreamingURL, favoritetype = "url") def addFavorite(self, name = "", text = "", favoritetype = "", audio = "", bitrate = ""): self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value + 1 self.favoriteConfig.entriescount.save() newFavorite = self.initFavouriteEntryConfig() newFavorite.name.value = name newFavorite.text.value = text newFavorite.type.value = favoritetype newFavorite.audio.value = audio newFavorite.bitrate.value = bitrate newFavorite.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) def renameFavorite(self): sel = self.getSelectedItem() if sel is not None: self.session.openWithCallback(self.renameFavoriteFinished, VirtualKeyBoard, title = _("Enter new name for favorite item"), text = sel.configItem.name.value) def renameFavoriteFinished(self, text = None): if text: sel = self.getSelectedItem() sel.configItem.name.value = text sel.configItem.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) self.favoriteListIndex = 0 self.getFavoriteList() def removeFavorite(self): sel = self.getSelectedItem() if sel is not None: self.favoriteConfig.entriescount.value = self.favoriteConfig.entriescount.value - 1 self.favoriteConfig.entriescount.save() self.favoriteConfig.Entries.remove(sel.configItem) self.favoriteConfig.Entries.save() self.favoriteConfig.saveToFile(self.FAVORITE_FILE) self.favoriteListIndex = 0 self.getFavoriteList() def search(self): self.session.openWithCallback(self.searchSHOUTcast, VirtualKeyBoard, title = _("Enter text to search for")) def searchSHOUTcast(self, searchstring = None): if searchstring: self.stopReloadStationListTimer() self.stationListHeader = _("search-criteria %s") % searchstring self.headerTextString = _("SHOUTcast station list for %s") % self.stationListHeader self["headertext"].setText("") self["statustext"].setText(_("Searching SHOUTcast for %s...") % searchstring) self["list"].hide() if len(devid) > 8: self.stationListURL = self.SC + "/station/advancedsearch&f=xml&k=%s&search=%s" % (devid, searchstring) else: self.stationListURL = "http://207.200.98.1/sbin/newxml.phtml?search=%s" % searchstring self.mode = self.SEARCHLIST self.searchSHOUTcastString = searchstring self.stationListIndex = 0 sendUrlCommand(self.stationListURL, None, 10).addCallback(self.callbackStationList).addErrback(self.callbackStationListError) def config(self): self.stopReloadStationListTimer() self.session.openWithCallback(self.setupFinished, SHOUTcastSetup) def setupFinished(self, result): if result: if config.plugins.shoutcast.showcover.value: self["cover"].doShow() else: self["cover"].doHide() if self.mode == self.STATIONLIST: self.reloadStationListTimerVar = int(config.plugins.shoutcast.reloadstationlist.value) self.stationListIndex = 0 self.callbackStationList(self.stationListXML) def callbackStationListError(self, error = None): if error is not None: try: self["list"].hide() self["statustext"].setText(_("%s\nPress OK to try again...") % str(error.getErrorMessage())) except: pass def Error(self, error = None): if error is not None: # print "[SHOUTcast] Error: %s" % error try: self["list"].hide() self["statustext"].setText(str(error.getErrorMessage())) except: pass if self.nextGoogle: self.currentGoogle = self.nextGoogle self.nextGoogle = None sendUrlCommand(self.currentGoogle, None, 10).addCallback(self.GoogleImageCallback).addErrback(self.Error) else: self.currentGoogle = None def __onClose(self): global coverfiles for f in coverfiles: try: os.unlink(f) except: pass self.stopReloadStationListTimer() self.session.nav.event.remove(self.__event) self.currPlay = None containerStreamripper.dataAvail.remove(self.streamripperDataAvail) containerStreamripper.appClosed.remove(self.streamripperClosed) self.session.nav.playService(self.CurrentService) def GoogleImageCallback(self, result): global coverfiles if self.nextGoogle: self.currentGoogle = self.nextGoogle self.nextGoogle = None sendUrlCommand(self.currentGoogle, None, 10).addCallback(self.GoogleImageCallback).addErrback(self.Error) return self.currentGoogle = None foundPos = result.find("unescapedUrl\":\"") foundPos2 = result.find("\",\"url\":\"") if foundPos != -1 and foundPos2 != -1: url=result[foundPos+15:foundPos2] if len(url)>15: url= url.replace(" ", "%20") print "[SHOUTcast] Download URL: %s" % url validurl = True else: validurl = False print "[SHOUTcast] Invalid cover url or picture format!" if config.plugins.shoutcast.showcover.value: self["cover"].doHide() if validurl: self.currentcoverfile = (self.currentcoverfile + 1) % len(coverfiles) try: os.unlink(coverfiles[self.currentcoverfile-1]) except: pass coverfile = coverfiles[self.currentcoverfile] print "[SHOUTcast] Downloading cover from %s to %s" % (url, coverfile) downloadPage(url, coverfile).addCallback(self.coverDownloadFinished, coverfile).addErrback(self.coverDownloadFailed) def coverDownloadFailed(self,result): print "[SHOUTcast] Cover download failed: %s" % result if config.plugins.shoutcast.showcover.value: self["statustext"].setText(_("Error downloading cover...")) self["cover"].doHide() def coverDownloadFinished(self, result, coverfile): if config.plugins.shoutcast.showcover.value: print "[SHOUTcast] Cover download finished: %s" % coverfile self["statustext"].setText("") self["cover"].updateIcon(coverfile) self["cover"].doShow() def __event(self, ev): if ev != 18: print "[SHOUTcast] EVENT ==>", ev if ev == 1 or ev == 4: print "[SHOUTcast] Tuned in, playing now!" if ev == 3 or ev == 7: self["statustext"].setText(_("Stream stopped playing, playback of stream stopped!")) print "[SHOUTcast] Stream stopped playing, playback of stream stopped!" self.session.nav.stopService() if ev == 5: if not self.currPlay: return sTitle = self.currPlay.info().getInfoString(iServiceInformation.sTagTitle) if self.oldtitle != sTitle: self.oldtitle=sTitle sTitle = sTitle.replace("Title:", "")[:55] if config.plugins.shoutcast.showcover.value: searchpara="album cover " if sTitle: url = "http://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=%s%s&biw=%s&bih=%s&ift=jpg&ift=gif&ift=png" % (quote(searchpara), quote(sTitle), config.plugins.shoutcast.coverwidth.value, config.plugins.shoutcast.coverheight.value) else: url = "http://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=no+cover+pic&biw=%s&bih=%s&ift=jpg&ift=gif&ift=png" % (config.plugins.shoutcast.coverwidth.value, config.plugins.shoutcast.coverheight.value) print "[SHOUTcast] Coverurl = %s" % url if self.currentGoogle: self.nextGoogle = url else: self.currentGoogle = url sendUrlCommand(url, None, 10).addCallback(self.GoogleImageCallback).addErrback(self.Error) if len(sTitle) == 0: sTitle = "n/a" title = _("Title: %s") % sTitle print "[SHOUTcast] Title: %s" % title self["titel"].setText(title) self.summaries.setText(title) else: print "[SHOUTcast] Ignoring useless updated info provided by stream engine!" #if ev == 6 or (ev > 8 and ev != 17): # print "[SHOUTcast] Abnormal event %s from stream, so stop playing!" % ev # self["statustext"].setText(_("Abnormal event from stream, aborting!")) # self.session.nav.stopService() def playServiceStream(self, url): self.currPlay = None self.session.nav.stopService() if config.plugins.shoutcast.showcover.value: self["cover"].doHide() sref = eServiceReference(eServiceReference.idServiceMP3, eServiceReference.noFlags, url) try: self.session.nav.playService(sref) except: print "[SHOUTcast] Could not play %s" % sref self.currPlay = self.session.nav.getCurrentService() self.currentStreamingURL = url self["titel"].setText(_("Title: n/a")) self["station"].setText(_("Station: %s") % self.currentStreamingStation) def createSummary(self): return SHOUTcastLCDScreen def initFavouriteEntryConfig(self): self.favoriteConfig.Entries.append(ConfigSubsection()) i = len(self.favoriteConfig.Entries) -1 self.favoriteConfig.Entries[i].name = ConfigText(default = "") self.favoriteConfig.Entries[i].text = ConfigText(default = "") self.favoriteConfig.Entries[i].type = ConfigText(default = "") self.favoriteConfig.Entries[i].audio = ConfigText(default = "") self.favoriteConfig.Entries[i].bitrate = ConfigText(default = "") return self.favoriteConfig.Entries[i] def initFavouriteConfig(self): count = self.favoriteConfig.entriescount.value if count != 0: i = 0 while i < count: self.initFavouriteEntryConfig() i += 1 def getSelectedItem(self): sel = None try: sel = self["list"].l.getCurrentSelection()[0] except:return None return sel