-from enigma import eTimer\r
-from enigma import eConsoleAppContainer\r
-from enigma import loadPic\r
-\r
-from Screens.Screen import Screen\r
-from Screens.MessageBox import MessageBox\r
-from Screens.HelpMenu import HelpableScreen , HelpMenu \r
-\r
-from Components.Pixmap import Pixmap,MovingPixmap\r
-from Components.Label import Label\r
-from Components.MenuList import MenuList\r
-from Components.ActionMap import ActionMap, NumberActionMap\r
-from Components.config import config, ConfigSubsection, ConfigSlider,ConfigInteger,ConfigYesNo, ConfigText\r
-from Components.HelpMenuList import HelpMenuList\r
-\r
-\r
-from Tools import Notifications\r
-\r
-from Plugins.Plugin import PluginDescriptor\r
-\r
-from StreamPlayer import StreamPlayer\r
-from LastFMConfig import LastFMConfigScreen\r
-from LastFM import LastFM, lastfm_event_register\r
-import httpclient\r
-import os\r
-import urllib\r
-\r
-import random\r
-\r
-############################################################################### \r
-plugin_path = ""\r
-\r
-############################################################################### \r
-\r
-config.plugins.LastFM = ConfigSubsection()\r
-config.plugins.LastFM.showcoverart = ConfigYesNo(default = True)\r
-config.plugins.LastFM.username = ConfigText("user",fixed_size=False)\r
-config.plugins.LastFM.password = ConfigText("passwd",fixed_size=False)\r
-config.plugins.LastFM.timeoutstatustext = ConfigInteger(3,limits = (0, 10))\r
-config.plugins.LastFM.timeouttabselect = ConfigInteger(2,limits = (0, 10))\r
-config.plugins.LastFM.metadatarefreshinterval = ConfigInteger(5,limits = (0, 100))\r
-config.plugins.LastFM.recommendedlevel = ConfigInteger(3,limits = (0, 100))\r
-\r
-config.plugins.LastFM.sreensaver = ConfigSubsection()\r
-config.plugins.LastFM.sreensaver.use = ConfigYesNo(default = True)\r
-config.plugins.LastFM.sreensaver.wait = ConfigInteger(30,limits = (0, 1000))\r
-config.plugins.LastFM.sreensaver.showcoverart = ConfigYesNo(default = True)\r
-config.plugins.LastFM.sreensaver.coverartanimation = ConfigYesNo(default = True)\r
-config.plugins.LastFM.sreensaver.coverartspeed = ConfigInteger(10,limits = (0, 100))\r
-config.plugins.LastFM.sreensaver.coverartinterval = ConfigInteger(10,limits = (0, 100))\r
-\r
-############################################################################### \r
-def main(session,**kwargs):\r
- session.open(LastFMScreenMain) \r
- \r
-def Plugins(path,**kwargs):\r
- global plugin_path\r
- plugin_path = path\r
- return PluginDescriptor(\r
- name="Last.FM", \r
- description="the social music revolution", \r
- where = PluginDescriptor.WHERE_PLUGINMENU,\r
- fnc = main\r
- )\r
-############################################################################### \r
-class LastFMScreenMain(Screen,HelpableScreen,LastFM):\r
- skin = """\r
- <screen position="110,83" size="530,430" title="Last.FM" >\r
- \r
- <widget name="artist" position="0,0" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" /> \r
- <widget name="album" position="0,40" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" /> \r
- <widget name="track" position="0,80" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" /> \r
- \r
- <widget name="info_artist" position="70,0" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" /> \r
- <widget name="info_album" position="70,40" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" /> \r
- <widget name="info_track" position="70,80" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" /> \r
- <widget name="info_cover" position="414,0" size="116,116" /> \r
- \r
- <widget name="tablist" position="0,120" size="150,260" scrollbarMode="showOnDemand" /> \r
- <widget name="streamlist" position="150,120" size="380,260" scrollbarMode="showOnDemand" /> \r
- \r
- <widget name="button_red" position="10,400" size="60,30" backgroundColor=\"red\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" /> \r
- <widget name="button_green" position="80,400" size="60,30" backgroundColor=\"green\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\"/> \r
- <widget name="button_yellow" position="150,400" size="60,30" backgroundColor=\"yellow\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" /> \r
- <widget name="button_blue" position="220,400" size="60,30" backgroundColor=\"blue\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" /> \r
- <widget name="infolabel" position="290,400" size="290,30" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" /> \r
- </screen>"""\r
- \r
- noCoverArtPNG = "/usr/share/enigma2/no_coverArt.png"\r
- \r
- def __init__(self, session, args = 0):\r
- self.skin = LastFMScreenMain.skin\r
- Screen.__init__(self, session)\r
- HelpableScreen.__init__(self)\r
- LastFM.__init__(self)\r
- self.session = session\r
- self.streamplayer = StreamPlayer(session)\r
- self.streamplayer.onStateChanged.append(self.updateGUI)\r
- self.imageconverter = ImageConverter(116,116,self.setCoverArt)\r
- Screen.__init__(self, session)\r
- \r
- self.tabs=[("personal Stations",self.loadPersonalStations)\r
- ,("Global Tags",self.loadGlobalTags)\r
- ,("Top Tracks",self.loadTopTracks)\r
- ,("Recent Tracks",self.loadRecentTracks)\r
- ,("Loved Tracks",self.loadLovedTracks)\r
- ,("Banned Tracks",self.loadBannedTracks)\r
- ,("Friends",self.loadFriends)\r
- ,("Neighbours",self.loadNeighbours)\r
- ]\r
- tablist =[]\r
- for tab in self.tabs:\r
- tablist.append((tab[0],tab))\r
- self.tablist = MenuList(tablist)\r
- self.tablist.onSelectionChanged.append(self.action_TabChanged)\r
- \r
- self["artist"] = Label(_("Artist")+":")\r
- self["album"] = Label(_("Album")+":")\r
- self["track"] = Label(_("Track")+":")\r
- \r
- self["info_artist"] = Label("N/A")\r
- self["info_album"] = Label("N/A")\r
- self["info_track"] = Label("N/A")\r
- self["info_cover"] = Pixmap()\r
- \r
- self["tablist"] = self.tablist\r
- self["streamlist"] = MenuList([])\r
- \r
- self["button_red"] = Label(_("play"))\r
- self["button_green"] = Label(_("skip"))\r
- self["button_yellow"] = Label(_("love"))\r
- self["button_blue"] = Label(_("ban"))\r
- self["infolabel"] = Label("")\r
- \r
- self["actions"] = ActionMap(["InfobarChannelSelection","WizardActions", "DirectionActions","MenuActions","ShortcutActions","GlobalActions","HelpActions","NumberActions"], \r
- {\r
- "ok": self.action_ok,\r
- "back": self.action_exit,\r
- "red": self.action_startstop,\r
- "green": self.skip,\r
- "yellow": self.love,\r
- "blue": self.ban ,\r
- "historyNext": self.action_nextTab,\r
- "historyBack": self.action_prevTab,\r
- \r
- "menu": self.action_menu,\r
- }, -1)\r
- \r
- self.helpList.append((self["actions"], "WizardActions", [("ok", _("switch to selected Station"))]))\r
- self.helpList.append((self["actions"], "WizardActions", [("back", _("quit Last.FM"))]))\r
-\r
- self.helpList.append((self["actions"], "MenuActions", [("menu", _("open Configuration"))]))\r
-\r
- self.helpList.append((self["actions"], "ShortcutActions", [("red", _("start/stop streaming"))]))\r
- self.helpList.append((self["actions"], "ShortcutActions", [("green", _("skip current Track"))]))\r
- self.helpList.append((self["actions"], "ShortcutActions", [("yellow", _("mark current Track as loved"))]))\r
- self.helpList.append((self["actions"], "ShortcutActions", [("blue", _("ban Track, never play again"))]))\r
- self.helpList.append((self["actions"], "InfobarChannelSelection", [("historyNext", _("select next Tab"))]))\r
- self.helpList.append((self["actions"], "InfobarChannelSelection", [("historyBack", _("select prev Tab"))]))\r
-\r
- self.onLayoutFinish.append(self.initLastFM)\r
- self.onLayoutFinish.append(self.tabchangedtimerFired)\r
- self.onLayoutFinish.append(self.setCoverArt)\r
- \r
- self.guiupdatetimer = eTimer()\r
- self.guiupdatetimer.timeout.get().append(self.guiupdatetimerFired)\r
- self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)\r
- \r
- self.tabchangetimer = eTimer()\r
- self.tabchangetimer.timeout.get().append(self.tabchangedtimerFired)\r
- \r
- self.infolabelcleartimer = eTimer()\r
- self.infolabelcleartimer.timeout.get().append(self.clearInfoLabel)\r
-\r
- self.screensavertimer = eTimer()\r
- self.screensavertimer.timeout.get().append(self.startScreensaver)\r
- self.onShown.append(self.startScreensaverTimer)\r
-\r
- def initLastFM(self):\r
- self.setInfoLabel("loggin into last.fm")\r
- self.connect(config.plugins.LastFM.username.value,config.plugins.LastFM.password.value)\r
- \r
- def onConnectSuccessful(self,text):\r
- self.setInfoLabel("login successful") \r
- \r
- def onConnectFailed(self,text):\r
- self.setInfoLabel("login failed! "+text,timeout=False)\r
-\r
- def onTrackSkiped(self,reason):\r
- self.setInfoLabel("Track skiped")\r
-\r
- def onTrackLoved(self,reason):\r
- self.setInfoLabel("Track loved")\r
- \r
- def onTrackBaned(self,reason):\r
- self.setInfoLabel("Track baned")\r
- \r
- def onCommandFailed(self,reason):\r
- self.setInfoLabel(reason)\r
-\r
- def onGlobalTagsLoaded(self,tags):\r
- self.setInfoLabel("Global Tags loaded")\r
- self.buildMenuList(tags)\r
-\r
- def onTopTracksLoaded(self,tracks):\r
- self.setInfoLabel("Top Tracks loaded")\r
- self.buildMenuList(tracks)\r
-\r
- def onRecentTracksLoaded(self,tracks):\r
- self.setInfoLabel("recent Tracks loaded")\r
- self.buildMenuList(tracks)\r
- \r
- def onRecentBannedTracksLoaded(self,tracks):\r
- self.setInfoLabel("banned Tracks loaded")\r
- self.buildMenuList(tracks)\r
-\r
- def onRecentLovedTracksLoaded(self,tracks):\r
- self.setInfoLabel("loved Tracks loaded")\r
- self.buildMenuList(tracks)\r
-\r
- def onNeighboursLoaded(self,user):\r
- self.setInfoLabel("Neighbours loaded")\r
- self.buildMenuList(user)\r
-\r
- def onFriendsLoaded(self,user):\r
- self.setInfoLabel("Friends loaded")\r
- self.buildMenuList(user)\r
- \r
- def onStationChanged(self,reason):\r
- self.setInfoLabel(reason) \r
- \r
- def onMetadataLoaded(self,metadata):\r
- self.updateGUI()\r
- self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)\r
-\r
- def action_TabChanged(self):\r
- self.tabchangetimer.stop()\r
- self.tabchangetimer.start(config.plugins.LastFM.timeouttabselect.value*1000)\r
- \r
- def guiupdatetimerFired(self):\r
- if self.streamplayer.is_playing:\r
- self.getMetadata()\r
- self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)\r
- \r
- def tabchangedtimerFired(self):\r
- self.tablist.getCurrent()[1][1]()\r
- self.tabchangetimer.stop()\r
-\r
- def startScreensaverTimer(self):\r
- if config.plugins.LastFM.sreensaver.use.value:\r
- self.screensavertimer.start(config.plugins.LastFM.sreensaver.wait.value*1000)\r
-\r
- def resetScreensaverTimer(self):\r
- self.screensavertimer.stop()\r
- self.screensavertimer.start(config.plugins.LastFM.sreensaver.wait.value*1000)\r
- \r
- def startScreensaver(self):\r
- self.screensavertimer.stop()\r
- self.session.openWithCallback(self.updateGUI, LastFMSaveScreen,self.metadata)\r
- \r
- def action_nextTab(self):\r
- self.tablist.down()\r
- self.resetScreensaverTimer()\r
- \r
- def action_prevTab(self):\r
- self.tablist.up()\r
- self.resetScreensaverTimer()\r
-\r
- def action_menu(self):\r
- self.session.open(LastFMConfigScreen)\r
- self.resetScreensaverTimer()\r
-\r
- def action_exit(self):\r
- self.screensavertimer.stop()\r
- self.guiupdatetimer.stop()\r
- self.streamplayer.stop()\r
- self.close()\r
-\r
- def action_ok(self):\r
- x = self["streamlist"].l.getCurrentSelection()\r
- if len(x) >1:\r
- self.changeStation(x[1])\r
- self.resetScreensaverTimer()\r
-\r
- def action_startstop(self):\r
- self.resetScreensaverTimer()\r
- if self.streamplayer.is_playing:\r
- self.streamplayer.stop()\r
- self.metadata = {}\r
- self.setInfoLabel("stream stopped")\r
- \r
- else:\r
- self.setInfoLabel("starting stream",timeout=True)\r
- if self.info.has_key("stream_url"):\r
- self.streamplayer.play(self.info["stream_url"])\r
- self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)\r
-\r
- def setInfoLabel(self,text,timeout=True):\r
- self.infolabelcleartimer.stop() \r
- self["infolabel"].setText(text)\r
- if timeout is True:\r
- self.infolabelcleartimer.start(config.plugins.LastFM.timeoutstatustext.value*1000)\r
- \r
- def clearInfoLabel(self):\r
- self["infolabel"].setText("")\r
- \r
- def updateGUI(self):\r
- print "updateGUI"\r
- if self.streamplayer.is_playing is True:\r
- self["button_red"].setText(_("stop"))\r
- else:\r
- self["button_red"].setText(_("play")) \r
- \r
- if self.streamplayer.is_playing is not True or self.shown is not True:\r
- return None\r
- \r
- if self.metadata.has_key("station"):\r
- self.setTitle("Last.FM: "+self.metadata["station"])\r
- else:\r
- self.setTitle("Last.FM")\r
-\r
- if self.metadata.has_key("artist"):\r
- self["info_artist"].setText(self.metadata["artist"])\r
- else:\r
- self["info_artist"].setText("N/A")\r
-\r
- if self.metadata.has_key("album"):\r
- self["info_album"].setText(self.metadata["album"])\r
- else:\r
- self["info_album"].setText("N/A")\r
-\r
- if self.metadata.has_key("track"):\r
- self["info_track"].setText(self.metadata["track"])\r
- else:\r
- self["info_track"].setText("N/A")\r
- \r
- if self.metadata.has_key("albumcover_large") and config.plugins.LastFM.showcoverart.value:\r
- self.imageconverter.convert(self.metadata["albumcover_large"])\r
- elif self.metadata.has_key("albumcover_medium") and config.plugins.LastFM.showcoverart.value:\r
- self.imageconverter.convert(self.metadata["albumcover_medium"])\r
- elif self.metadata.has_key("albumcover_small") and config.plugins.LastFM.showcoverart.value:\r
- self.imageconverter.convert(self.metadata["albumcover_small"],self.setCoverArt)\r
- else:\r
- self.setCoverArt()\r
- \r
- if self.streamplayer.is_playing is not True:\r
- self.setTitle(myname)\r
- self.setCoverArt()\r
- self["info_artist"].setText("N/A")\r
- self["info_album"].setText("N/A")\r
- self["info_track"].setText("N/A")\r
- \r
- def setCoverArt(self,pixmap=None):\r
- if pixmap is None:\r
- self["info_cover"].instance.setPixmapFromFile(self.noCoverArtPNG) \r
- else:\r
- self["info_cover"].instance.setPixmap(pixmap.__deref__())\r
- \r
-\r
- def loadPersonalStations(self):\r
- tags = []\r
- x= {}\r
- x["_display"] = "Personal Radio"\r
- x["stationurl"] = self.getPersonalURL(config.plugins.LastFM.username.value,level=config.plugins.LastFM.recommendedlevel.value)\r
- tags.append(x)\r
- \r
- x= {}\r
- x["_display"] = "Neighbours Tracks"\r
- x["stationurl"] = self.getNeighboursURL(config.plugins.LastFM.username.value)\r
- tags.append(x)\r
- \r
- x= {}\r
- x["_display"] = "Loved Tracks"\r
- x["stationurl"] = self.getLovedURL(config.plugins.LastFM.username.value)\r
- tags.append(x)\r
- \r
- if self.metadata.has_key("artist"):\r
- x= {}\r
- x["_display"] = "similar Tracks of current Artist"\r
- x["stationurl"] = self.getSimilarArtistsURL()\r
- tags.append(x)\r
- \r
- x= {}\r
- x["_display"] = "Tracks liked by Fans of current Track"\r
- x["stationurl"] = self.getArtistsLikedByFans()\r
- tags.append(x)\r
-\r
- x= {}\r
- x["_display"] = "Group of Artist of current Track"\r
- x["stationurl"] = self.getArtistGroup()\r
- tags.append(x)\r
- \r
- self.buildMenuList(tags)\r
- \r
- def loadGlobalTags(self):\r
- self.setInfoLabel("loading Global Tags")\r
- tags = self.getGlobalTags()\r
-\r
- def loadTopTracks(self):\r
- self.setInfoLabel("loading Top Tacks")\r
- tracks = self.getTopTracks(config.plugins.LastFM.username.value)\r
-\r
- def loadRecentTracks(self):\r
- self.setInfoLabel("loading recent Tracks")\r
- tracks = self.getRecentTracks(config.plugins.LastFM.username.value)\r
-\r
- def loadLovedTracks(self):\r
- self.setInfoLabel("loading loved Tracks")\r
- tracks = self.getRecentLovedTracks(config.plugins.LastFM.username.value)\r
-\r
- def loadBannedTracks(self):\r
- self.setInfoLabel("loading loved Tracks")\r
- tracks = self.getRecentBannedTracks(config.plugins.LastFM.username.value)\r
- \r
- def loadNeighbours(self):\r
- self.setInfoLabel("loading Neighbours")\r
- tracks = self.getNeighbours(config.plugins.LastFM.username.value)\r
-\r
- def loadFriends(self):\r
- self.setInfoLabel("loading Friends")\r
- tracks = self.getFriends(config.plugins.LastFM.username.value)\r
-\r
- def buildMenuList(self,items):\r
- menuliste = []\r
- for i in items:\r
- menuliste.append((i['_display'],i['stationurl']))\r
- self["streamlist"].l.setList(menuliste) \r
-\r
-class LastFMSaveScreen(Screen):\r
- skin = """<screen position="0,0" size="720,576" flags="wfNoBorder" title="LastFMSaveScreen" >\r
- <widget name="cover" position="50,50" size="200,200" /> \r
- </screen>"""\r
- noCoverArtPNG = "/usr/share/enigma2/no_coverArt.png"\r
- coverartsize= [200,200]\r
- def __init__(self,session,initialMetadata):\r
- self.skin = """<screen position="0,0" size="720,576" flags="wfNoBorder" title="LastFMSaveScreen" >\r
- <widget name="cover" position="50,50" size="%i,%i" /> \r
- </screen>"""%(self.coverartsize[0],self.coverartsize[1])\r
- \r
- Screen.__init__(self,session)\r
- self.imageconverter = ImageConverter(self.coverartsize[0],self.coverartsize[1],self.setCoverArt)\r
- self.session = session\r
- self.initialMetadata = initialMetadata\r
- self["cover"] = MovingPixmap()\r
- self["actions"] = ActionMap(["InfobarChannelSelection","WizardActions", "DirectionActions","MenuActions","ShortcutActions","GlobalActions","HelpActions"], \r
- {\r
- "ok": self.action_exit,\r
- "back": self.action_exit,\r
- }, -1)\r
- \r
- self.onLayoutFinish.append(self.update)\r
- self.onLayoutFinish.append(self.registerToMetadataUpdates)\r
- \r
- if config.plugins.LastFM.sreensaver.coverartanimation.value:\r
- self.startmovingtimer = eTimer()\r
- self.startmovingtimer.timeout.get().append(self.movePixmap)\r
- self.startmovingtimer.start(config.plugins.LastFM.sreensaver.coverartinterval.value*1000)\r
- \r
- def action_ok(self):\r
- pass\r
- \r
- def action_exit(self):\r
- lastfm_event_register.removeOnMetadataChanged(self.update)\r
- self.close()\r
- \r
- def setCoverArt(self,pixmap=None):\r
- if pixmap is None:\r
- self["cover"].instance.setPixmapFromFile(self.noCoverArtPNG) \r
- else:\r
- self["cover"].instance.setPixmap(pixmap.__deref__())\r
- \r
- def registerToMetadataUpdates(self):\r
- lastfm_event_register.addOnMetadataChanged(self.update)#added here, to make shure that is called after onLayoutFinished\r
- \r
- \r
- def update(self,metadata=None):\r
- \r
- if metadata is None:\r
- metadata = self.initialMetadata\r
- \r
- if config.plugins.LastFM.sreensaver.showcoverart.value is not True:\r
- pass#do nothing\r
- elif metadata.has_key("albumcover_large") and config.plugins.LastFM.showcoverart.value:\r
- self.imageconverter.convert(metadata["albumcover_large"])\r
- elif metadata.has_key("albumcover_medium") and config.plugins.LastFM.showcoverart.value:\r
- self.imageconverter.convert(metadata["albumcover_medium"])\r
- elif metadata.has_key("albumcover_small") and config.plugins.LastFM.showcoverart.value:\r
- self.imageconverter.convert(metadata["albumcover_small"],self.setCoverArt)\r
- else:\r
- self.setCoverArt()\r
-\r
- def movePixmap(self):\r
- self.startmovingtimer.stop() \r
- newX = random.randrange(720-self.coverartsize[0]-1)\r
- newY = random.randrange(576-self.coverartsize[1]-1)\r
- self["cover"].moveTo(newX, newY, time = config.plugins.LastFM.sreensaver.coverartspeed.value)\r
- self["cover"].startMoving()\r
- self.startmovingtimer.start(config.plugins.LastFM.sreensaver.coverartinterval.value*1000)\r
-\r
-class ImageConverter:\r
- \r
- lastURL = ""\r
-\r
- def __init__(self,width,height,callBack):\r
- self.callBack = callBack\r
- self.width = width\r
- self.height = height\r
- self.targetfile= "/tmp/coverart"+str(random.randrange(5000))\r
- \r
- \r
- def convert(self,sourceURL):\r
- if self.lastURL != sourceURL:\r
- extension = sourceURL.split(".")[-1]\r
- self.tmpfile = self.targetfile+"."+extension\r
- httpclient.getFile(self.tmpfile,sourceURL,callback=self.onImageLoaded)\r
- self.lastURL = sourceURL\r
-\r
- def onImageLoaded(self,dummy):\r
- self.currPic = loadPic(self.tmpfile, self.width, self.height, 0,1, 0,1)\r
- os.remove(self.tmpfile)\r
- self.callBack(pixmap=self.currPic)\r
+from enigma import eTimer
+from enigma import eConsoleAppContainer
+from enigma import loadPic
+
+from Screens.Screen import Screen
+from Screens.MessageBox import MessageBox
+from Screens.HelpMenu import HelpableScreen , HelpMenu
+
+from Components.Pixmap import Pixmap,MovingPixmap
+from Components.Label import Label
+from Components.MenuList import MenuList
+from Components.ActionMap import ActionMap, NumberActionMap
+from Components.config import config, ConfigSubsection, ConfigSlider,ConfigInteger,ConfigYesNo, ConfigText
+from Components.HelpMenuList import HelpMenuList
+
+
+from Tools import Notifications
+
+from Plugins.Plugin import PluginDescriptor
+
+from StreamPlayer import StreamPlayer
+from LastFMConfig import LastFMConfigScreen
+from LastFM import LastFM, lastfm_event_register
+import httpclient
+import os
+import urllib
+
+import random
+
+###############################################################################
+plugin_path = ""
+
+###############################################################################
+
+config.plugins.LastFM = ConfigSubsection()
+config.plugins.LastFM.showcoverart = ConfigYesNo(default = True)
+config.plugins.LastFM.username = ConfigText("user",fixed_size=False)
+config.plugins.LastFM.password = ConfigText("passwd",fixed_size=False)
+config.plugins.LastFM.timeoutstatustext = ConfigInteger(3,limits = (0, 10))
+config.plugins.LastFM.timeouttabselect = ConfigInteger(2,limits = (0, 10))
+config.plugins.LastFM.metadatarefreshinterval = ConfigInteger(5,limits = (0, 100))
+config.plugins.LastFM.recommendedlevel = ConfigInteger(3,limits = (0, 100))
+
+config.plugins.LastFM.sreensaver = ConfigSubsection()
+config.plugins.LastFM.sreensaver.use = ConfigYesNo(default = True)
+config.plugins.LastFM.sreensaver.wait = ConfigInteger(30,limits = (0, 1000))
+config.plugins.LastFM.sreensaver.showcoverart = ConfigYesNo(default = True)
+config.plugins.LastFM.sreensaver.coverartanimation = ConfigYesNo(default = True)
+config.plugins.LastFM.sreensaver.coverartspeed = ConfigInteger(10,limits = (0, 100))
+config.plugins.LastFM.sreensaver.coverartinterval = ConfigInteger(10,limits = (0, 100))
+
+###############################################################################
+def main(session,**kwargs):
+ session.open(LastFMScreenMain)
+
+def Plugins(path,**kwargs):
+ global plugin_path
+ plugin_path = path
+ return PluginDescriptor(
+ name="Last.FM",
+ description="the social music revolution",
+ where = PluginDescriptor.WHERE_PLUGINMENU,
+ fnc = main
+ )
+###############################################################################
+class LastFMScreenMain(Screen,HelpableScreen,LastFM):
+ skin = """
+ <screen position="110,83" size="530,430" title="Last.FM" >
+
+ <widget name="artist" position="0,0" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
+ <widget name="album" position="0,40" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
+ <widget name="track" position="0,80" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
+
+ <widget name="info_artist" position="70,0" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
+ <widget name="info_album" position="70,40" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
+ <widget name="info_track" position="70,80" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
+ <widget name="info_cover" position="414,0" size="116,116" />
+
+ <widget name="tablist" position="0,120" size="150,260" scrollbarMode="showOnDemand" />
+ <widget name="streamlist" position="150,120" size="380,260" scrollbarMode="showOnDemand" />
+
+ <widget name="button_red" position="10,400" size="60,30" backgroundColor=\"red\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
+ <widget name="button_green" position="80,400" size="60,30" backgroundColor=\"green\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\"/>
+ <widget name="button_yellow" position="150,400" size="60,30" backgroundColor=\"yellow\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
+ <widget name="button_blue" position="220,400" size="60,30" backgroundColor=\"blue\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
+ <widget name="infolabel" position="290,400" size="290,30" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
+ </screen>"""
+
+ noCoverArtPNG = "/usr/share/enigma2/no_coverArt.png"
+
+ def __init__(self, session, args = 0):
+ self.skin = LastFMScreenMain.skin
+ Screen.__init__(self, session)
+ HelpableScreen.__init__(self)
+ LastFM.__init__(self)
+ self.session = session
+ self.streamplayer = StreamPlayer(session)
+ self.streamplayer.onStateChanged.append(self.updateGUI)
+ self.imageconverter = ImageConverter(116,116,self.setCoverArt)
+ Screen.__init__(self, session)
+
+ self.tabs=[("personal Stations",self.loadPersonalStations)
+ ,("Global Tags",self.loadGlobalTags)
+ ,("Top Tracks",self.loadTopTracks)
+ ,("Recent Tracks",self.loadRecentTracks)
+ ,("Loved Tracks",self.loadLovedTracks)
+ ,("Banned Tracks",self.loadBannedTracks)
+ ,("Friends",self.loadFriends)
+ ,("Neighbours",self.loadNeighbours)
+ ]
+ tablist =[]
+ for tab in self.tabs:
+ tablist.append((tab[0],tab))
+ self.tablist = MenuList(tablist)
+ self.tablist.onSelectionChanged.append(self.action_TabChanged)
+
+ self["artist"] = Label(_("Artist")+":")
+ self["album"] = Label(_("Album")+":")
+ self["track"] = Label(_("Track")+":")
+
+ self["info_artist"] = Label("N/A")
+ self["info_album"] = Label("N/A")
+ self["info_track"] = Label("N/A")
+ self["info_cover"] = Pixmap()
+
+ self["tablist"] = self.tablist
+ self["streamlist"] = MenuList([])
+
+ self["button_red"] = Label(_("play"))
+ self["button_green"] = Label(_("skip"))
+ self["button_yellow"] = Label(_("love"))
+ self["button_blue"] = Label(_("ban"))
+ self["infolabel"] = Label("")
+
+ self["actions"] = ActionMap(["InfobarChannelSelection","WizardActions", "DirectionActions","MenuActions","ShortcutActions","GlobalActions","HelpActions","NumberActions"],
+ {
+ "ok": self.action_ok,
+ "back": self.action_exit,
+ "red": self.action_startstop,
+ "green": self.skip,
+ "yellow": self.love,
+ "blue": self.ban ,
+ "historyNext": self.action_nextTab,
+ "historyBack": self.action_prevTab,
+
+ "menu": self.action_menu,
+ }, -1)
+
+ self.helpList.append((self["actions"], "WizardActions", [("ok", _("switch to selected Station"))]))
+ self.helpList.append((self["actions"], "WizardActions", [("back", _("quit Last.FM"))]))
+
+ self.helpList.append((self["actions"], "MenuActions", [("menu", _("open Configuration"))]))
+
+ self.helpList.append((self["actions"], "ShortcutActions", [("red", _("start/stop streaming"))]))
+ self.helpList.append((self["actions"], "ShortcutActions", [("green", _("skip current Track"))]))
+ self.helpList.append((self["actions"], "ShortcutActions", [("yellow", _("mark current Track as loved"))]))
+ self.helpList.append((self["actions"], "ShortcutActions", [("blue", _("ban Track, never play again"))]))
+ self.helpList.append((self["actions"], "InfobarChannelSelection", [("historyNext", _("select next Tab"))]))
+ self.helpList.append((self["actions"], "InfobarChannelSelection", [("historyBack", _("select prev Tab"))]))
+
+ self.onLayoutFinish.append(self.initLastFM)
+ self.onLayoutFinish.append(self.tabchangedtimerFired)
+ self.onLayoutFinish.append(self.setCoverArt)
+
+ self.guiupdatetimer = eTimer()
+ self.guiupdatetimer.timeout.get().append(self.guiupdatetimerFired)
+ self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
+
+ self.tabchangetimer = eTimer()
+ self.tabchangetimer.timeout.get().append(self.tabchangedtimerFired)
+
+ self.infolabelcleartimer = eTimer()
+ self.infolabelcleartimer.timeout.get().append(self.clearInfoLabel)
+
+ self.screensavertimer = eTimer()
+ self.screensavertimer.timeout.get().append(self.startScreensaver)
+ self.onShown.append(self.startScreensaverTimer)
+
+ def initLastFM(self):
+ self.setInfoLabel("loggin into last.fm")
+ self.connect(config.plugins.LastFM.username.value,config.plugins.LastFM.password.value)
+
+ def onConnectSuccessful(self,text):
+ self.setInfoLabel("login successful")
+
+ def onConnectFailed(self,text):
+ self.setInfoLabel("login failed! "+text,timeout=False)
+
+ def onTrackSkiped(self,reason):
+ self.setInfoLabel("Track skiped")
+
+ def onTrackLoved(self,reason):
+ self.setInfoLabel("Track loved")
+
+ def onTrackBaned(self,reason):
+ self.setInfoLabel("Track baned")
+
+ def onCommandFailed(self,reason):
+ self.setInfoLabel(reason)
+
+ def onGlobalTagsLoaded(self,tags):
+ self.setInfoLabel("Global Tags loaded")
+ self.buildMenuList(tags)
+
+ def onTopTracksLoaded(self,tracks):
+ self.setInfoLabel("Top Tracks loaded")
+ self.buildMenuList(tracks)
+
+ def onRecentTracksLoaded(self,tracks):
+ self.setInfoLabel("recent Tracks loaded")
+ self.buildMenuList(tracks)
+
+ def onRecentBannedTracksLoaded(self,tracks):
+ self.setInfoLabel("banned Tracks loaded")
+ self.buildMenuList(tracks)
+
+ def onRecentLovedTracksLoaded(self,tracks):
+ self.setInfoLabel("loved Tracks loaded")
+ self.buildMenuList(tracks)
+
+ def onNeighboursLoaded(self,user):
+ self.setInfoLabel("Neighbours loaded")
+ self.buildMenuList(user)
+
+ def onFriendsLoaded(self,user):
+ self.setInfoLabel("Friends loaded")
+ self.buildMenuList(user)
+
+ def onStationChanged(self,reason):
+ self.setInfoLabel(reason)
+
+ def onMetadataLoaded(self,metadata):
+ self.updateGUI()
+ self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
+
+ def action_TabChanged(self):
+ self.tabchangetimer.stop()
+ self.tabchangetimer.start(config.plugins.LastFM.timeouttabselect.value*1000)
+
+ def guiupdatetimerFired(self):
+ if self.streamplayer.is_playing:
+ self.getMetadata()
+ self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
+
+ def tabchangedtimerFired(self):
+ self.tablist.getCurrent()[1][1]()
+ self.tabchangetimer.stop()
+
+ def startScreensaverTimer(self):
+ if config.plugins.LastFM.sreensaver.use.value:
+ self.screensavertimer.start(config.plugins.LastFM.sreensaver.wait.value*1000)
+
+ def resetScreensaverTimer(self):
+ self.screensavertimer.stop()
+ self.screensavertimer.start(config.plugins.LastFM.sreensaver.wait.value*1000)
+
+ def startScreensaver(self):
+ self.screensavertimer.stop()
+ self.session.openWithCallback(self.updateGUI, LastFMSaveScreen,self.metadata)
+
+ def action_nextTab(self):
+ self.tablist.down()
+ self.resetScreensaverTimer()
+
+ def action_prevTab(self):
+ self.tablist.up()
+ self.resetScreensaverTimer()
+
+ def action_menu(self):
+ self.session.open(LastFMConfigScreen)
+ self.resetScreensaverTimer()
+
+ def action_exit(self):
+ self.screensavertimer.stop()
+ self.guiupdatetimer.stop()
+ self.streamplayer.stop()
+ self.close()
+
+ def action_ok(self):
+ x = self["streamlist"].l.getCurrentSelection()
+ if x is None:
+ pass
+ elif len(x) >1:
+ self.changeStation(x[1])
+ self.resetScreensaverTimer()
+
+ def action_startstop(self):
+ self.resetScreensaverTimer()
+ if self.streamplayer.is_playing:
+ self.streamplayer.stop()
+ self.metadata = {}
+ self.setInfoLabel("stream stopped")
+
+ else:
+ self.setInfoLabel("starting stream",timeout=True)
+ if self.info.has_key("stream_url"):
+ self.streamplayer.play(self.info["stream_url"])
+ self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
+
+ def setInfoLabel(self,text,timeout=True):
+ self.infolabelcleartimer.stop()
+ self["infolabel"].setText(text)
+ if timeout is True:
+ self.infolabelcleartimer.start(config.plugins.LastFM.timeoutstatustext.value*1000)
+
+ def clearInfoLabel(self):
+ self["infolabel"].setText("")
+
+ def updateGUI(self):
+ print "updateGUI"
+ if self.streamplayer.is_playing is True:
+ self["button_red"].setText(_("stop"))
+ else:
+ self["button_red"].setText(_("play"))
+
+ if self.streamplayer.is_playing is not True or self.shown is not True:
+ return None
+
+ if self.metadata.has_key("station"):
+ self.setTitle("Last.FM: "+self.metadata["station"])
+ else:
+ self.setTitle("Last.FM")
+
+ if self.metadata.has_key("artist"):
+ self["info_artist"].setText(self.metadata["artist"])
+ else:
+ self["info_artist"].setText("N/A")
+
+ if self.metadata.has_key("album"):
+ self["info_album"].setText(self.metadata["album"])
+ else:
+ self["info_album"].setText("N/A")
+
+ if self.metadata.has_key("track"):
+ self["info_track"].setText(self.metadata["track"])
+ else:
+ self["info_track"].setText("N/A")
+
+ if self.metadata.has_key("albumcover_large") and config.plugins.LastFM.showcoverart.value:
+ self.imageconverter.convert(self.metadata["albumcover_large"])
+ elif self.metadata.has_key("albumcover_medium") and config.plugins.LastFM.showcoverart.value:
+ self.imageconverter.convert(self.metadata["albumcover_medium"])
+ elif self.metadata.has_key("albumcover_small") and config.plugins.LastFM.showcoverart.value:
+ self.imageconverter.convert(self.metadata["albumcover_small"],self.setCoverArt)
+ else:
+ self.setCoverArt()
+
+ if self.streamplayer.is_playing is not True:
+ self.setTitle(myname)
+ self.setCoverArt()
+ self["info_artist"].setText("N/A")
+ self["info_album"].setText("N/A")
+ self["info_track"].setText("N/A")
+
+ def setCoverArt(self,pixmap=None):
+ if pixmap is None:
+ self["info_cover"].instance.setPixmapFromFile(self.noCoverArtPNG)
+ else:
+ self["info_cover"].instance.setPixmap(pixmap.__deref__())
+
+
+ def loadPersonalStations(self):
+ tags = []
+ x= {}
+ x["_display"] = "Personal Radio"
+ x["stationurl"] = self.getPersonalURL(config.plugins.LastFM.username.value,level=config.plugins.LastFM.recommendedlevel.value)
+ tags.append(x)
+
+ x= {}
+ x["_display"] = "Neighbours Tracks"
+ x["stationurl"] = self.getNeighboursURL(config.plugins.LastFM.username.value)
+ tags.append(x)
+
+ x= {}
+ x["_display"] = "Loved Tracks"
+ x["stationurl"] = self.getLovedURL(config.plugins.LastFM.username.value)
+ tags.append(x)
+
+ if self.metadata.has_key("artist"):
+ x= {}
+ x["_display"] = "similar Tracks of current Artist"
+ x["stationurl"] = self.getSimilarArtistsURL()
+ tags.append(x)
+
+ x= {}
+ x["_display"] = "Tracks liked by Fans of current Track"
+ x["stationurl"] = self.getArtistsLikedByFans()
+ tags.append(x)
+
+ x= {}
+ x["_display"] = "Group of Artist of current Track"
+ x["stationurl"] = self.getArtistGroup()
+ tags.append(x)
+
+ self.buildMenuList(tags)
+
+ def loadGlobalTags(self):
+ self.setInfoLabel("loading Global Tags")
+ tags = self.getGlobalTags()
+
+ def loadTopTracks(self):
+ self.setInfoLabel("loading Top Tacks")
+ tracks = self.getTopTracks(config.plugins.LastFM.username.value)
+
+ def loadRecentTracks(self):
+ self.setInfoLabel("loading recent Tracks")
+ tracks = self.getRecentTracks(config.plugins.LastFM.username.value)
+
+ def loadLovedTracks(self):
+ self.setInfoLabel("loading loved Tracks")
+ tracks = self.getRecentLovedTracks(config.plugins.LastFM.username.value)
+
+ def loadBannedTracks(self):
+ self.setInfoLabel("loading loved Tracks")
+ tracks = self.getRecentBannedTracks(config.plugins.LastFM.username.value)
+
+ def loadNeighbours(self):
+ self.setInfoLabel("loading Neighbours")
+ tracks = self.getNeighbours(config.plugins.LastFM.username.value)
+
+ def loadFriends(self):
+ self.setInfoLabel("loading Friends")
+ tracks = self.getFriends(config.plugins.LastFM.username.value)
+
+ def buildMenuList(self,items):
+ menuliste = []
+ for i in items:
+ menuliste.append((i['_display'],i['stationurl']))
+ self["streamlist"].l.setList(menuliste)
+
+class LastFMSaveScreen(Screen):
+ skin = """<screen position="0,0" size="720,576" flags="wfNoBorder" title="LastFMSaveScreen" >
+ <widget name="cover" position="50,50" size="200,200" />
+ </screen>"""
+ noCoverArtPNG = "/usr/share/enigma2/no_coverArt.png"
+ coverartsize= [200,200]
+ def __init__(self,session,initialMetadata):
+ self.skin = """<screen position="0,0" size="720,576" flags="wfNoBorder" title="LastFMSaveScreen" >
+ <widget name="cover" position="50,50" size="%i,%i" />
+ </screen>"""%(self.coverartsize[0],self.coverartsize[1])
+
+ Screen.__init__(self,session)
+ self.imageconverter = ImageConverter(self.coverartsize[0],self.coverartsize[1],self.setCoverArt)
+ self.session = session
+ self.initialMetadata = initialMetadata
+ self["cover"] = MovingPixmap()
+ self["actions"] = ActionMap(["InfobarChannelSelection","WizardActions", "DirectionActions","MenuActions","ShortcutActions","GlobalActions","HelpActions"],
+ {
+ "ok": self.action_exit,
+ "back": self.action_exit,
+ }, -1)
+
+ self.onLayoutFinish.append(self.update)
+ self.onLayoutFinish.append(self.registerToMetadataUpdates)
+
+ if config.plugins.LastFM.sreensaver.coverartanimation.value:
+ self.startmovingtimer = eTimer()
+ self.startmovingtimer.timeout.get().append(self.movePixmap)
+ self.startmovingtimer.start(config.plugins.LastFM.sreensaver.coverartinterval.value*1000)
+
+ def action_ok(self):
+ pass
+
+ def action_exit(self):
+ lastfm_event_register.removeOnMetadataChanged(self.update)
+ self.close()
+
+ def setCoverArt(self,pixmap=None):
+ if pixmap is None:
+ self["cover"].instance.setPixmapFromFile(self.noCoverArtPNG)
+ else:
+ self["cover"].instance.setPixmap(pixmap.__deref__())
+
+ def registerToMetadataUpdates(self):
+ lastfm_event_register.addOnMetadataChanged(self.update)#added here, to make shure that is called after onLayoutFinished
+
+
+ def update(self,metadata=None):
+
+ if metadata is None:
+ metadata = self.initialMetadata
+
+ if config.plugins.LastFM.sreensaver.showcoverart.value is not True:
+ pass#do nothing
+ elif metadata.has_key("albumcover_large") and config.plugins.LastFM.showcoverart.value:
+ self.imageconverter.convert(metadata["albumcover_large"])
+ elif metadata.has_key("albumcover_medium") and config.plugins.LastFM.showcoverart.value:
+ self.imageconverter.convert(metadata["albumcover_medium"])
+ elif metadata.has_key("albumcover_small") and config.plugins.LastFM.showcoverart.value:
+ self.imageconverter.convert(metadata["albumcover_small"],self.setCoverArt)
+ else:
+ self.setCoverArt()
+
+ def movePixmap(self):
+ self.startmovingtimer.stop()
+ newX = random.randrange(720-self.coverartsize[0]-1)
+ newY = random.randrange(576-self.coverartsize[1]-1)
+ self["cover"].moveTo(newX, newY, time = config.plugins.LastFM.sreensaver.coverartspeed.value)
+ self["cover"].startMoving()
+ self.startmovingtimer.start(config.plugins.LastFM.sreensaver.coverartinterval.value*1000)
+
+class ImageConverter:
+
+ lastURL = ""
+
+ def __init__(self,width,height,callBack):
+ self.callBack = callBack
+ self.width = width
+ self.height = height
+ self.targetfile= "/tmp/coverart"+str(random.randrange(5000))
+
+
+ def convert(self,sourceURL):
+ if self.lastURL != sourceURL:
+ extension = sourceURL.split(".")[-1]
+ self.tmpfile = self.targetfile+"."+extension
+ httpclient.getFile(self.tmpfile,sourceURL,callback=self.onImageLoaded)
+ self.lastURL = sourceURL
+
+ def onImageLoaded(self,dummy):
+ self.currPic = loadPic(self.tmpfile, self.width, self.height, 0,1, 0,1)
+ os.remove(self.tmpfile)
+ self.callBack(pixmap=self.currPic)
\ No newline at end of file