1 from enigma import eTimer
2 from enigma import eConsoleAppContainer
3 from enigma import loadPic
5 from Screens.Screen import Screen
6 from Screens.MessageBox import MessageBox
7 from Screens.HelpMenu import HelpableScreen , HelpMenu
9 from Components.Pixmap import Pixmap
10 from Components.Label import Label
11 from Components.MenuList import MenuList
12 from Components.ActionMap import ActionMap, NumberActionMap
13 from Components.config import config, ConfigSubsection, ConfigSlider,ConfigInteger,ConfigYesNo, ConfigText
14 from Components.HelpMenuList import HelpMenuList
16 from Tools import Notifications
18 from Plugins.Plugin import PluginDescriptor
21 from StreamPlayer import StreamPlayer
22 from LastFMConfig import LastFMConfigScreen
23 from LastFM import LastFM
27 ###############################################################################
31 ###############################################################################
33 config.plugins.LastFM = ConfigSubsection()
34 config.plugins.LastFM.showcoverart = ConfigYesNo(default = False)
35 config.plugins.LastFM.username = ConfigText("user",fixed_size=False)
36 config.plugins.LastFM.password = ConfigText("passwd",fixed_size=False)
37 config.plugins.LastFM.timeoutstatustext = ConfigInteger(3,limits = (0, 10))
38 config.plugins.LastFM.timeouttabselect = ConfigInteger(2,limits = (0, 10))
39 config.plugins.LastFM.metadatarefreshinterval = ConfigInteger(5,limits = (0, 100))
40 config.plugins.LastFM.recommendedlevel = ConfigInteger(3,limits = (0, 100))
42 ###############################################################################
43 def main(session,**kwargs):
44 session.open(LastFMScreenMain)
46 def Plugins(path,**kwargs):
49 return PluginDescriptor(
51 description="the social music revolution",
52 where = PluginDescriptor.WHERE_PLUGINMENU,
55 ###############################################################################
56 class LastFMScreenMain(Screen,HelpableScreen):
58 <screen position="110,83" size="530,430" title="Last.FM" >
60 <widget name="artist" position="0,0" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
61 <widget name="album" position="0,40" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
62 <widget name="track" position="0,80" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
64 <widget name="info_artist" position="70,0" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
65 <widget name="info_album" position="70,40" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
66 <widget name="info_track" position="70,80" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
67 <widget name="info_cover" position="414,0" size="116,116" />
69 <widget name="tablist" position="0,120" size="150,260" scrollbarMode="showOnDemand" />
70 <widget name="streamlist" position="150,120" size="380,260" scrollbarMode="showOnDemand" />
72 <widget name="button_red" position="10,400" size="60,30" backgroundColor=\"red\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
73 <widget name="button_green" position="80,400" size="60,30" backgroundColor=\"green\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\"/>
74 <widget name="button_yellow" position="150,400" size="60,30" backgroundColor=\"yellow\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
75 <widget name="button_blue" position="220,400" size="60,30" backgroundColor=\"blue\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
76 <widget name="infolabel" position="290,400" size="290,30" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
79 noCoverArtPNG = "/usr/share/enigma2/no_coverArt.png"
81 def __init__(self, session, args = 0):
82 Screen.__init__(self, session)
83 HelpableScreen.__init__(self)
84 self.skin = LastFMScreenMain.skin
85 self.session = session
86 self.lastfm = LastFM()
87 self.streamplayer = StreamPlayer(session)
88 self.imageconverter = ImageConverter(self.setCoverArt)
89 Screen.__init__(self, session)
90 self.tabs=[("personal Stations",self.loadPersonalStations)
91 ,("Global Tags",self.loadGlobalTags)
92 ,("Top Tracks",self.loadTopTracks)
93 ,("Recent Tracks",self.loadRecentTracks)
94 ,("Loved Tracks",self.loadLovedTracks)
95 ,("Banned Tracks",self.loadBannedTracks)
96 ,("Friends",self.loadFriends)
97 ,("Neighbours",self.loadNeighbours)
100 for tab in self.tabs:
101 tablist.append((tab[0],tab))
102 self.tablist = MenuList(tablist)
103 self.tablist.onSelectionChanged.append(self.action_TabChanged)
105 self["artist"] = Label(_("Artist")+":")
106 self["album"] = Label(_("Album")+":")
107 self["track"] = Label(_("Track")+":")
109 self["info_artist"] = Label("N/A")
110 self["info_album"] = Label("N/A")
111 self["info_track"] = Label("N/A")
112 self["info_cover"] = Pixmap()
114 self["tablist"] = self.tablist
115 self["streamlist"] = MenuList([])
117 self["button_red"] = Label(_("play"))
118 self["button_green"] = Label(_("skip"))
119 self["button_yellow"] = Label(_("love"))
120 self["button_blue"] = Label(_("ban"))
121 self["infolabel"] = Label("")
123 self["actions"] = ActionMap(["InfobarChannelSelection","WizardActions", "DirectionActions","MenuActions","ShortcutActions","GlobalActions","HelpActions"],
125 "ok": self.action_ok,
126 "back": self.action_exit,
127 "red": self.action_startstop,
128 "green": self.action_green,
129 "yellow": self.action_yellow,
130 "blue": self.action_blue ,
131 "historyNext": self.action_nextTab,
132 "historyBack": self.action_prevTab,
134 "menu": self.action_menu,
136 self.helpList.append((self["actions"], "WizardActions", [("ok", _("switch to selected Station"))]))
137 self.helpList.append((self["actions"], "WizardActions", [("back", _("quit Last.FM"))]))
139 self.helpList.append((self["actions"], "MenuActions", [("menu", _("open Configuration"))]))
141 self.helpList.append((self["actions"], "ShortcutActions", [("red", _("start/stop streaming"))]))
142 self.helpList.append((self["actions"], "ShortcutActions", [("green", _("skip current Track"))]))
143 self.helpList.append((self["actions"], "ShortcutActions", [("yellow", _("mark current Track as loved"))]))
144 self.helpList.append((self["actions"], "ShortcutActions", [("blue", _("ban Track, never play again"))]))
145 self.helpList.append((self["actions"], "InfobarChannelSelection", [("historyNext", _("select next Tab"))]))
146 self.helpList.append((self["actions"], "InfobarChannelSelection", [("historyBack", _("select prev Tab"))]))
148 self.onLayoutFinish.append(self.initLastFM)
149 self.onLayoutFinish.append(self.tabchangedtimerFired)
150 self.onLayoutFinish.append(self.setCoverArt)
152 self.guiupdatetimer = eTimer()
153 self.guiupdatetimer.timeout.get().append(self.updateGUI)
155 self.tabchangetimer = eTimer()
156 self.tabchangetimer.timeout.get().append(self.tabchangedtimerFired)
158 self.infolabelcleartimer = eTimer()
159 self.infolabelcleartimer.timeout.get().append(self.clearInfoLabel)
162 def action_TabChanged(self):
163 self.tabchangetimer.stop()
164 self.tabchangetimer.start(config.plugins.LastFM.timeouttabselect.value*1000)
166 def tabchangedtimerFired(self):
167 self.tablist.getCurrent()[1][1]()
168 self.tabchangetimer.stop()
170 def action_nextTab(self):
173 def action_prevTab(self):
176 def showTab(self,tabnumber):
177 self.currenttab=tabnumber
178 print "showing tab",tabnumber
179 print self.tabs[tabnumber]
181 def action_menu(self):
182 self.session.open(LastFMConfigScreen)
184 def action_exit(self):
186 self.guiupdatetimer.stop()
187 self.streamplayer.stop()
192 selectedTag = self["streamlist"].l.getCurrentSelection()[1]
193 self.lastfm.changestation(selectedTag)
195 def action_startstop(self):
196 if self.streamplayer.is_playing:
197 self.streamplayer.stop()
198 self.lastfm.metadata = {}
199 self.setInfoLabel("stream stopped")
202 self.setInfoLabel("starting stream",timeout=True)
203 if self.lastfm.info.has_key("stream_url"):
204 self.streamplayer.play(self.lastfm.info["stream_url"])
205 self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
207 def action_green(self):
209 self.setInfoLabel("Track skipped",timeout=True)
211 def action_yellow(self):
213 self.setInfoLabel("Track loved",timeout=True)
215 def action_blue(self):
217 self.setInfoLabel("Track banned",timeout=True)
219 def setInfoLabel(self,text,timeout=True):
220 self.infolabelcleartimer.stop()
221 self["infolabel"].setText(text)
223 self.infolabelcleartimer.start(config.plugins.LastFM.timeoutstatustext.value*1000)
225 def clearInfoLabel(self):
226 self["infolabel"].setText("")
229 if self.streamplayer.is_playing is not True:
233 if self.lastfm.state:
234 self.lastfm.getmetadata()
236 if self.streamplayer.is_playing:
237 self["button_red"].setText(_("stop"))
239 self["button_red"].setText(_("play"))
241 if self.lastfm.metadata.has_key("station"):
242 self.setTitle(myname+": "+self.lastfm.metadata["station"])
244 self.setTitle(myname)
246 if self.lastfm.metadata.has_key("artist"):
247 self["info_artist"].setText(self.lastfm.metadata["artist"])
249 self["info_artist"].setText("N/A")
251 if self.lastfm.metadata.has_key("album"):
252 self["info_album"].setText(self.lastfm.metadata["album"])
254 self["info_album"].setText("N/A")
256 if self.lastfm.metadata.has_key("track"):
257 self["info_track"].setText(self.lastfm.metadata["track"])
259 self["info_track"].setText("N/A")
261 if self.lastfm.metadata.has_key("albumcover_large") and config.plugins.LastFM.showcoverart.value:
262 self.imageconverter.convert(self.lastfm.metadata["albumcover_large"])
263 elif self.lastfm.metadata.has_key("albumcover_medium") and config.plugins.LastFM.showcoverart.value:
264 self.imageconverter.convert(self.lastfm.metadata["albumcover_medium"])
265 elif self.lastfm.metadata.has_key("albumcover_small") and config.plugins.LastFM.showcoverart.value:
266 self.imageconverter.convert(self.lastfm.metadata["albumcover_small"],self.setCoverArt)
270 if self.streamplayer.is_playing:
271 self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
273 self.setTitle(myname)
275 self["info_artist"].setText("N/A")
276 self["info_album"].setText("N/A")
277 self["info_track"].setText("N/A")
279 def setCoverArt(self,pixmap=None):
281 self["info_cover"].instance.setPixmapFromFile(self.noCoverArtPNG)
283 self["info_cover"].instance.setPixmap(pixmap.__deref__())
285 def initLastFM(self):
286 self.setInfoLabel("loggin into last.fm")
287 (result,resulttext) = self.lastfm.connect(config.plugins.LastFM.username.value,config.plugins.LastFM.password.value)
289 self.setInfoLabel("login failed")
290 Notifications.AddPopup("Login to Last.FM failed!", resulttext,MessageBox.TYPE_INFO, 5)
292 self.setInfoLabel("login successful",timeout=True)
294 def loadPersonalStations(self):
297 x["_display"] = "Personal Radio"
298 x["stationurl"] = self.lastfm.getPersonalURL(config.plugins.LastFM.username.value,level=config.plugins.LastFM.recommendedlevel.value)
302 x["_display"] = "Neighbours Tracks"
303 x["stationurl"] = self.lastfm.getNeighboursURL(config.plugins.LastFM.username.value)
307 x["_display"] = "Loved Tracks"
308 x["stationurl"] = self.lastfm.getLovedURL(config.plugins.LastFM.username.value)
311 if self.lastfm.metadata.has_key("artist"):
313 x["_display"] = "similar Tracks of current Artist"
314 x["stationurl"] = self.lastfm.getSimilarArtistsURL()
318 x["_display"] = "Tracks liked by Fans of current Track"
319 x["stationurl"] = self.lastfm.getArtistsLikedByFans()
323 x["_display"] = "Group of Artist of current Track"
324 x["stationurl"] = self.lastfm.getArtistGroup()
328 self.buildMenuList(tags)
330 def loadGlobalTags(self):
331 self.setInfoLabel("loading Global Tags")
332 tags = self.lastfm.getGlobalTags()
333 self.buildMenuList(tags)
335 def loadTopTracks(self):
336 self.setInfoLabel("loading Top Tacks")
337 tracks = self.lastfm.getTopTracks(config.plugins.LastFM.username.value)
338 self.buildMenuList(tracks)
340 def loadRecentTracks(self):
341 self.setInfoLabel("loading recent Tracks")
342 tracks = self.lastfm.getRecentTracks(config.plugins.LastFM.username.value)
343 self.buildMenuList(tracks)
345 def loadLovedTracks(self):
346 self.setInfoLabel("loading loved Tracks")
347 tracks = self.lastfm.getRecentLovedTracks(config.plugins.LastFM.username.value)
348 self.buildMenuList(tracks)
350 def loadBannedTracks(self):
351 self.setInfoLabel("loading loved Tracks")
352 tracks = self.lastfm.getRecentBannedTracks(config.plugins.LastFM.username.value)
353 self.buildMenuList(tracks)
355 def loadNeighbours(self):
356 self.setInfoLabel("loading Neighbours")
357 tracks = self.lastfm.getNeighbours(config.plugins.LastFM.username.value)
358 self.buildMenuList(tracks)
360 def loadFriends(self):
361 self.setInfoLabel("loading Friends")
362 tracks = self.lastfm.getFriends(config.plugins.LastFM.username.value)
363 self.buildMenuList(tracks)
365 def buildMenuList(self,items):
368 menuliste.append((i['_display'],i['stationurl']))
369 self["streamlist"].l.setList(menuliste)
372 class ImageConverter:
374 targetfile= "/tmp/coverart"
377 def __init__(self,callBack):
378 self.callBack = callBack
380 def convert(self,sourceURL):
381 if self.lastURL == sourceURL:
382 print "imageurl not changed, skipped"
384 extension = sourceURL.split(".")[-1]
385 tmpfile = self.targetfile+"."+extension
387 fpurl = urllib.urlopen(sourceURL)
391 fp = open(tmpfile,"w")
395 self.currPic = loadPic(tmpfile, 116, 116, 1, 1, 0,1)
399 self.callBack(pixmap=self.currPic)
400 self.lastURL = sourceURL