2 from enigma import eTimer
3 from enigma import eConsoleAppContainer
4 from enigma import loadPic
6 from Screens.Screen import Screen
7 from Screens.MessageBox import MessageBox
8 from Screens.HelpMenu import HelpableScreen , HelpMenu
10 from Components.Pixmap import Pixmap
11 from Components.Label import Label
12 from Components.MenuList import MenuList
13 from Components.ActionMap import ActionMap, NumberActionMap
14 from Components.config import config, ConfigSubsection, ConfigSlider,ConfigInteger,ConfigYesNo, ConfigText
15 from Components.HelpMenuList import HelpMenuList
17 from Tools import Notifications
19 from Plugins.Plugin import PluginDescriptor
22 from StreamPlayer import StreamPlayer
23 from LastFMConfig import LastFMConfigScreen
24 from LastFM import LastFM
28 ###############################################################################
34 ###############################################################################
36 config.plugins.LastFM = ConfigSubsection()
37 config.plugins.LastFM.showcoverart = ConfigYesNo(default = False)
38 config.plugins.LastFM.username = ConfigText("user",fixed_size=False)
39 config.plugins.LastFM.password = ConfigText("passwd",fixed_size=False)
40 config.plugins.LastFM.timeoutstatustext = ConfigInteger(3,limits = (0, 10))
41 config.plugins.LastFM.timeouttabselect = ConfigInteger(2,limits = (0, 10))
42 config.plugins.LastFM.metadatarefreshinterval = ConfigInteger(5,limits = (0, 100))
43 config.plugins.LastFM.recommendedlevel = ConfigInteger(3,limits = (0, 100))
45 ###############################################################################
46 def main(session,**kwargs):
47 session.open(LastFMScreenMain)
49 def Plugins(path,**kwargs):
52 return PluginDescriptor(
54 description="the social music revolution",
55 where = PluginDescriptor.WHERE_PLUGINMENU,
58 ###############################################################################
59 class LastFMScreenMain(Screen,HelpableScreen):
61 <screen position="110,83" size="530,430" title="Last.FM" >
63 <widget name="artist" position="0,0" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
64 <widget name="album" position="0,40" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
65 <widget name="track" position="0,80" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
67 <widget name="info_artist" position="70,0" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
68 <widget name="info_album" position="70,40" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
69 <widget name="info_track" position="70,80" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
70 <widget name="info_cover" position="414,0" size="116,116" />
72 <widget name="tablist" position="0,120" size="150,260" scrollbarMode="showOnDemand" />
73 <widget name="streamlist" position="150,120" size="380,260" scrollbarMode="showOnDemand" />
75 <widget name="button_red" position="10,400" size="60,30" backgroundColor=\"red\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
76 <widget name="button_green" position="80,400" size="60,30" backgroundColor=\"green\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\"/>
77 <widget name="button_yellow" position="150,400" size="60,30" backgroundColor=\"yellow\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
78 <widget name="button_blue" position="220,400" size="60,30" backgroundColor=\"blue\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
79 <widget name="infolabel" position="290,400" size="290,30" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
82 noCoverArtPNG = "/usr/share/enigma2/no_coverArt.png"
84 def __init__(self, session, args = 0):
85 Screen.__init__(self, session)
86 HelpableScreen.__init__(self)
87 self.skin = LastFMScreenMain.skin
88 self.session = session
89 self.lastfm = LastFM()
90 self.streamplayer = StreamPlayer(session)
91 self.imageconverter = ImageConverter(self.setCoverArt)
92 Screen.__init__(self, session)
93 self.tabs=[("personal Stations",self.loadPersonalStations)
94 ,("Global Tags",self.loadGlobalTags)
95 ,("Top Tracks",self.loadTopTracks)
96 ,("Recent Tracks",self.loadRecentTracks)
97 ,("Loved Tracks",self.loadLovedTracks)
98 ,("Banned Tracks",self.loadBannedTracks)
99 ,("Friends",self.loadFriends)
100 ,("Neighbours",self.loadNeighbours)
103 for tab in self.tabs:
104 tablist.append((tab[0],tab))
105 self.tablist = MenuList(tablist)
106 self.tablist.onSelectionChanged.append(self.action_TabChanged)
108 self["artist"] = Label(_("Artist")+":")
109 self["album"] = Label(_("Album")+":")
110 self["track"] = Label(_("Track")+":")
112 self["info_artist"] = Label("N/A")
113 self["info_album"] = Label("N/A")
114 self["info_track"] = Label("N/A")
115 self["info_cover"] = Pixmap()
117 self["tablist"] = self.tablist
118 self["streamlist"] = MenuList([])
120 self["button_red"] = Label(_("play"))
121 self["button_green"] = Label(_("skip"))
122 self["button_yellow"] = Label(_("love"))
123 self["button_blue"] = Label(_("ban"))
124 self["infolabel"] = Label("")
126 self["actions"] = ActionMap(["InfobarChannelSelection","WizardActions", "DirectionActions","MenuActions","ShortcutActions","GlobalActions","HelpActions"],
128 "ok": self.action_ok,
129 "back": self.action_exit,
130 "red": self.action_startstop,
131 "green": self.action_green,
132 "yellow": self.action_yellow,
133 "blue": self.action_blue ,
134 "historyNext": self.action_nextTab,
135 "historyBack": self.action_prevTab,
137 "menu": self.action_menu,
139 self.helpList.append((self["actions"], "WizardActions", [("ok", _("switch to selected Station"))]))
140 self.helpList.append((self["actions"], "WizardActions", [("back", _("quit Last.FM"))]))
142 self.helpList.append((self["actions"], "MenuActions", [("menu", _("open Configuration"))]))
144 self.helpList.append((self["actions"], "ShortcutActions", [("red", _("start/stop streaming"))]))
145 self.helpList.append((self["actions"], "ShortcutActions", [("green", _("skip current Track"))]))
146 self.helpList.append((self["actions"], "ShortcutActions", [("yellow", _("mark current Track as loved"))]))
147 self.helpList.append((self["actions"], "ShortcutActions", [("blue", _("ban Track, never play again"))]))
148 self.helpList.append((self["actions"], "InfobarChannelSelection", [("historyNext", _("select next Tab"))]))
149 self.helpList.append((self["actions"], "InfobarChannelSelection", [("historyBack", _("select prev Tab"))]))
151 self.onLayoutFinish.append(self.initLastFM)
152 self.onLayoutFinish.append(self.tabchangedtimerFired)
153 self.onLayoutFinish.append(self.setCoverArt)
155 self.guiupdatetimer = eTimer()
156 self.guiupdatetimer.timeout.get().append(self.updateGUI)
158 self.tabchangetimer = eTimer()
159 self.tabchangetimer.timeout.get().append(self.tabchangedtimerFired)
161 self.infolabelcleartimer = eTimer()
162 self.infolabelcleartimer.timeout.get().append(self.clearInfoLabel)
165 def action_TabChanged(self):
166 self.tabchangetimer.stop()
167 self.tabchangetimer.start(config.plugins.LastFM.timeouttabselect.value*1000)
169 def tabchangedtimerFired(self):
170 self.tablist.getCurrent()[1][1]()
171 self.tabchangetimer.stop()
173 def action_nextTab(self):
176 def action_prevTab(self):
179 def showTab(self,tabnumber):
180 self.currenttab=tabnumber
181 print "showing tab",tabnumber
182 print self.tabs[tabnumber]
184 def action_menu(self):
185 self.session.open(LastFMConfigScreen)
187 def action_exit(self):
189 self.guiupdatetimer.stop()
190 self.streamplayer.stop()
195 selectedTag = self["streamlist"].l.getCurrentSelection()[1]
196 self.lastfm.changestation(selectedTag)
198 def action_startstop(self):
199 if self.streamplayer.is_playing:
200 self.streamplayer.stop()
201 self.lastfm.metadata = {}
202 self.setInfoLabel("stream stopped")
205 self.setInfoLabel("starting stream",timeout=True)
206 if self.lastfm.info.has_key("stream_url"):
207 self.streamplayer.play(self.lastfm.info["stream_url"])
208 self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
210 def action_green(self):
212 self.setInfoLabel("Track skipped",timeout=True)
214 def action_yellow(self):
216 self.setInfoLabel("Track loved",timeout=True)
218 def action_blue(self):
220 self.setInfoLabel("Track banned",timeout=True)
222 def setInfoLabel(self,text,timeout=True):
223 self.infolabelcleartimer.stop()
224 self["infolabel"].setText(text)
226 self.infolabelcleartimer.start(config.plugins.LastFM.timeoutstatustext.value*1000)
228 def clearInfoLabel(self):
229 self["infolabel"].setText("")
232 if self.streamplayer.is_playing is not True:
236 if self.lastfm.state:
237 self.lastfm.getmetadata()
239 if self.streamplayer.is_playing:
240 self["button_red"].setText(_("stop"))
242 self["button_red"].setText(_("play"))
244 if self.lastfm.metadata.has_key("station"):
245 self.setTitle(myname+": "+self.lastfm.metadata["station"])
247 self.setTitle(myname)
249 if self.lastfm.metadata.has_key("artist"):
250 self["info_artist"].setText(self.lastfm.metadata["artist"])
252 self["info_artist"].setText("N/A")
254 if self.lastfm.metadata.has_key("album"):
255 self["info_album"].setText(self.lastfm.metadata["album"])
257 self["info_album"].setText("N/A")
259 if self.lastfm.metadata.has_key("track"):
260 self["info_track"].setText(self.lastfm.metadata["track"])
262 self["info_track"].setText("N/A")
264 if self.lastfm.metadata.has_key("albumcover_large") and config.plugins.LastFM.showcoverart.value:
265 self.imageconverter.convert(self.lastfm.metadata["albumcover_large"])
266 elif self.lastfm.metadata.has_key("albumcover_medium") and config.plugins.LastFM.showcoverart.value:
267 self.imageconverter.convert(self.lastfm.metadata["albumcover_medium"])
268 elif self.lastfm.metadata.has_key("albumcover_small") and config.plugins.LastFM.showcoverart.value:
269 self.imageconverter.convert(self.lastfm.metadata["albumcover_small"],self.setCoverArt)
273 if self.streamplayer.is_playing:
274 self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
276 self.setTitle(myname)
278 self["info_artist"].setText("N/A")
279 self["info_album"].setText("N/A")
280 self["info_track"].setText("N/A")
282 def setCoverArt(self,pixmap=None):
284 self["info_cover"].instance.setPixmapFromFile(self.noCoverArtPNG)
286 self["info_cover"].instance.setPixmap(pixmap.__deref__())
288 def initLastFM(self):
289 self.setInfoLabel("loggin into last.fm")
290 (result,resulttext) = self.lastfm.connect(config.plugins.LastFM.username.value,config.plugins.LastFM.password.value)
292 self.setInfoLabel("login failed")
293 Notifications.AddPopup("Login to Last.FM failed!", resulttext,MessageBox.TYPE_INFO, 5)
295 self.setInfoLabel("login successful",timeout=True)
297 def loadPersonalStations(self):
300 x["_display"] = "Personal Radio"
301 x["stationurl"] = self.lastfm.getPersonalURL(config.plugins.LastFM.username.value,level=config.plugins.LastFM.recommendedlevel.value)
305 x["_display"] = "Neighbours Tracks"
306 x["stationurl"] = self.lastfm.getNeighboursURL(config.plugins.LastFM.username.value)
310 x["_display"] = "Loved Tracks"
311 x["stationurl"] = self.lastfm.getLovedURL(config.plugins.LastFM.username.value)
314 if self.lastfm.metadata.has_key("artist"):
316 x["_display"] = "similar Tracks of current Artist"
317 x["stationurl"] = self.lastfm.getSimilarArtistsURL()
321 x["_display"] = "Tracks liked by Fans of current Track"
322 x["stationurl"] = self.lastfm.getArtistsLikedByFans()
326 x["_display"] = "Group of Artist of current Track"
327 x["stationurl"] = self.lastfm.getArtistGroup()
331 self.buildMenuList(tags)
333 def loadGlobalTags(self):
334 self.setInfoLabel("loading Global Tags")
335 tags = self.lastfm.getGlobalTags()
336 self.buildMenuList(tags)
338 def loadTopTracks(self):
339 self.setInfoLabel("loading Top Tacks")
340 tracks = self.lastfm.getTopTracks(config.plugins.LastFM.username.value)
341 self.buildMenuList(tracks)
343 def loadRecentTracks(self):
344 self.setInfoLabel("loading recent Tracks")
345 tracks = self.lastfm.getRecentTracks(config.plugins.LastFM.username.value)
346 self.buildMenuList(tracks)
348 def loadLovedTracks(self):
349 self.setInfoLabel("loading loved Tracks")
350 tracks = self.lastfm.getRecentLovedTracks(config.plugins.LastFM.username.value)
351 self.buildMenuList(tracks)
353 def loadBannedTracks(self):
354 self.setInfoLabel("loading loved Tracks")
355 tracks = self.lastfm.getRecentBannedTracks(config.plugins.LastFM.username.value)
356 self.buildMenuList(tracks)
358 def loadNeighbours(self):
359 self.setInfoLabel("loading Neighbours")
360 tracks = self.lastfm.getNeighbours(config.plugins.LastFM.username.value)
361 self.buildMenuList(tracks)
363 def loadFriends(self):
364 self.setInfoLabel("loading Friends")
365 tracks = self.lastfm.getFriends(config.plugins.LastFM.username.value)
366 self.buildMenuList(tracks)
368 def buildMenuList(self,items):
371 menuliste.append((i['_display'],i['stationurl']))
372 self["streamlist"].l.setList(menuliste)
375 class ImageConverter:
377 targetfile= "/tmp/coverart"
380 def __init__(self,callBack):
381 self.callBack = callBack
383 def convert(self,sourceURL):
384 if self.lastURL == sourceURL:
385 print "imageurl not changed, skipped"
387 extension = sourceURL.split(".")[-1]
388 tmpfile = self.targetfile+"."+extension
390 fpurl = urllib.urlopen(sourceURL)
394 fp = open(tmpfile,"w")
398 self.currPic = loadPic(tmpfile, 116, 116, 1, 1, 0,1)
402 self.callBack(pixmap=self.currPic)
403 self.lastURL = sourceURL