1 from enigma import eTimer
\r
2 from enigma import eConsoleAppContainer
\r
3 from enigma import loadPic
\r
5 from Screens.Screen import Screen
\r
6 from Screens.MessageBox import MessageBox
\r
7 from Screens.HelpMenu import HelpableScreen , HelpMenu
\r
9 from Components.Pixmap import Pixmap
\r
10 from Components.Label import Label
\r
11 from Components.MenuList import MenuList
\r
12 from Components.ActionMap import ActionMap, NumberActionMap
\r
13 from Components.config import config, ConfigSubsection, ConfigSlider,ConfigInteger,ConfigYesNo, ConfigText
\r
14 from Components.HelpMenuList import HelpMenuList
\r
17 from Tools import Notifications
\r
19 from Plugins.Plugin import PluginDescriptor
\r
21 from StreamPlayer import StreamPlayer
\r
22 from LastFMConfig import LastFMConfigScreen
\r
23 from LastFM import LastFM
\r
27 ###############################################################################
\r
30 ###############################################################################
\r
32 config.plugins.LastFM = ConfigSubsection()
\r
33 config.plugins.LastFM.showcoverart = ConfigYesNo(default = False)
\r
34 config.plugins.LastFM.username = ConfigText("user",fixed_size=False)
\r
35 config.plugins.LastFM.password = ConfigText("passwd",fixed_size=False)
\r
36 config.plugins.LastFM.timeoutstatustext = ConfigInteger(3,limits = (0, 10))
\r
37 config.plugins.LastFM.timeouttabselect = ConfigInteger(2,limits = (0, 10))
\r
38 config.plugins.LastFM.metadatarefreshinterval = ConfigInteger(5,limits = (0, 100))
\r
39 config.plugins.LastFM.recommendedlevel = ConfigInteger(3,limits = (0, 100))
\r
41 ###############################################################################
\r
42 def main(session,**kwargs):
\r
43 session.open(LastFMScreenMain)
\r
45 def Plugins(path,**kwargs):
\r
48 return PluginDescriptor(
\r
50 description="the social music revolution",
\r
51 where = PluginDescriptor.WHERE_PLUGINMENU,
\r
54 ###############################################################################
\r
55 class LastFMScreenMain(Screen,HelpableScreen,LastFM):
\r
57 <screen position="110,83" size="530,430" title="Last.FM" >
\r
59 <widget name="artist" position="0,0" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
\r
60 <widget name="album" position="0,40" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
\r
61 <widget name="track" position="0,80" size="70,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
\r
63 <widget name="info_artist" position="70,0" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
\r
64 <widget name="info_album" position="70,40" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
\r
65 <widget name="info_track" position="70,80" size="344,30" valign=\"center\" halign=\"left\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
\r
66 <widget name="info_cover" position="414,0" size="116,116" />
\r
68 <widget name="tablist" position="0,120" size="150,260" scrollbarMode="showOnDemand" />
\r
69 <widget name="streamlist" position="150,120" size="380,260" scrollbarMode="showOnDemand" />
\r
71 <widget name="button_red" position="10,400" size="60,30" backgroundColor=\"red\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
\r
72 <widget name="button_green" position="80,400" size="60,30" backgroundColor=\"green\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\"/>
\r
73 <widget name="button_yellow" position="150,400" size="60,30" backgroundColor=\"yellow\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
\r
74 <widget name="button_blue" position="220,400" size="60,30" backgroundColor=\"blue\" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
\r
75 <widget name="infolabel" position="290,400" size="290,30" valign=\"center\" halign=\"center\" zPosition=\"2\" foregroundColor=\"white\" font=\"Regular;18\" />
\r
78 noCoverArtPNG = "/usr/share/enigma2/no_coverArt.png"
\r
80 def __init__(self, session, args = 0):
\r
81 self.skin = LastFMScreenMain.skin
\r
82 Screen.__init__(self, session)
\r
83 HelpableScreen.__init__(self)
\r
84 LastFM.__init__(self)
\r
85 self.session = session
\r
86 self.streamplayer = StreamPlayer(session)
\r
87 self.imageconverter = ImageConverter(self.setCoverArt)
\r
88 Screen.__init__(self, session)
\r
89 self.tabs=[("personal Stations",self.loadPersonalStations)
\r
90 ,("Global Tags",self.loadGlobalTags)
\r
91 ,("Top Tracks",self.loadTopTracks)
\r
92 ,("Recent Tracks",self.loadRecentTracks)
\r
93 ,("Loved Tracks",self.loadLovedTracks)
\r
94 ,("Banned Tracks",self.loadBannedTracks)
\r
95 ,("Friends",self.loadFriends)
\r
96 ,("Neighbours",self.loadNeighbours)
\r
99 for tab in self.tabs:
\r
100 tablist.append((tab[0],tab))
\r
101 self.tablist = MenuList(tablist)
\r
102 self.tablist.onSelectionChanged.append(self.action_TabChanged)
\r
104 self["artist"] = Label(_("Artist")+":")
\r
105 self["album"] = Label(_("Album")+":")
\r
106 self["track"] = Label(_("Track")+":")
\r
108 self["info_artist"] = Label("N/A")
\r
109 self["info_album"] = Label("N/A")
\r
110 self["info_track"] = Label("N/A")
\r
111 self["info_cover"] = Pixmap()
\r
113 self["tablist"] = self.tablist
\r
114 self["streamlist"] = MenuList([])
\r
116 self["button_red"] = Label(_("play"))
\r
117 self["button_green"] = Label(_("skip"))
\r
118 self["button_yellow"] = Label(_("love"))
\r
119 self["button_blue"] = Label(_("ban"))
\r
120 self["infolabel"] = Label("")
\r
122 self["actions"] = ActionMap(["InfobarChannelSelection","WizardActions", "DirectionActions","MenuActions","ShortcutActions","GlobalActions","HelpActions"],
\r
124 "ok": self.action_ok,
\r
125 "back": self.action_exit,
\r
126 "red": self.action_startstop,
\r
127 "green": self.skip,
\r
128 "yellow": self.love,
\r
130 "historyNext": self.action_nextTab,
\r
131 "historyBack": self.action_prevTab,
\r
133 "menu": self.action_menu,
\r
135 self.helpList.append((self["actions"], "WizardActions", [("ok", _("switch to selected Station"))]))
\r
136 self.helpList.append((self["actions"], "WizardActions", [("back", _("quit Last.FM"))]))
\r
138 self.helpList.append((self["actions"], "MenuActions", [("menu", _("open Configuration"))]))
\r
140 self.helpList.append((self["actions"], "ShortcutActions", [("red", _("start/stop streaming"))]))
\r
141 self.helpList.append((self["actions"], "ShortcutActions", [("green", _("skip current Track"))]))
\r
142 self.helpList.append((self["actions"], "ShortcutActions", [("yellow", _("mark current Track as loved"))]))
\r
143 self.helpList.append((self["actions"], "ShortcutActions", [("blue", _("ban Track, never play again"))]))
\r
144 self.helpList.append((self["actions"], "InfobarChannelSelection", [("historyNext", _("select next Tab"))]))
\r
145 self.helpList.append((self["actions"], "InfobarChannelSelection", [("historyBack", _("select prev Tab"))]))
\r
147 self.onLayoutFinish.append(self.initLastFM)
\r
148 self.onLayoutFinish.append(self.tabchangedtimerFired)
\r
149 self.onLayoutFinish.append(self.setCoverArt)
\r
151 self.guiupdatetimer = eTimer()
\r
152 self.guiupdatetimer.timeout.get().append(self.guiupdatetimerFired)
\r
153 self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
\r
155 self.tabchangetimer = eTimer()
\r
156 self.tabchangetimer.timeout.get().append(self.tabchangedtimerFired)
\r
158 self.infolabelcleartimer = eTimer()
\r
159 self.infolabelcleartimer.timeout.get().append(self.clearInfoLabel)
\r
161 def initLastFM(self):
\r
162 self.setInfoLabel("loggin into last.fm")
\r
163 self.connect(config.plugins.LastFM.username.value,config.plugins.LastFM.password.value)
\r
165 def onConnectSuccessful(self,text):
\r
166 self.setInfoLabel("login successful")
\r
168 def onConnectFailed(self,text):
\r
169 self.setInfoLabel("login failed! "+text,timeout=False)
\r
171 def onTrackSkiped(self,reason):
\r
172 self.setInfoLabel("Track skiped")
\r
174 def onTrackLoved(self,reason):
\r
175 self.setInfoLabel("Track loved")
\r
177 def onTrackBaned(self,reason):
\r
178 self.setInfoLabel("Track baned")
\r
180 def onCommandFailed(self,reason):
\r
181 self.setInfoLabel(reason)
\r
183 def onGlobalTagsLoaded(self,tags):
\r
184 self.setInfoLabel("Global Tags loaded")
\r
185 self.buildMenuList(tags)
\r
187 def onTopTracksLoaded(self,tracks):
\r
188 self.setInfoLabel("Top Tracks loaded")
\r
189 self.buildMenuList(tracks)
\r
191 def onRecentTracksLoaded(self,tracks):
\r
192 self.setInfoLabel("recent Tracks loaded")
\r
193 self.buildMenuList(tracks)
\r
195 def onRecentBannedTracksLoaded(self,tracks):
\r
196 self.setInfoLabel("banned Tracks loaded")
\r
197 self.buildMenuList(tracks)
\r
199 def onRecentLovedTracksLoaded(self,tracks):
\r
200 self.setInfoLabel("loved Tracks loaded")
\r
201 self.buildMenuList(tracks)
\r
203 def onNeighboursLoaded(self,user):
\r
204 self.setInfoLabel("Neighbours loaded")
\r
205 self.buildMenuList(user)
\r
207 def onFriendsLoaded(self,user):
\r
208 self.setInfoLabel("Friends loaded")
\r
209 self.buildMenuList(user)
\r
211 def onStationChanged(self,reason):
\r
212 self.setInfoLabel(reason)
\r
214 def onMetadataLoaded(self,metadata):
\r
216 self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
\r
218 def action_TabChanged(self):
\r
219 self.tabchangetimer.stop()
\r
220 self.tabchangetimer.start(config.plugins.LastFM.timeouttabselect.value*1000)
\r
222 def guiupdatetimerFired(self):
\r
223 if self.streamplayer.is_playing:
\r
225 self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
\r
227 def tabchangedtimerFired(self):
\r
228 self.tablist.getCurrent()[1][1]()
\r
229 self.tabchangetimer.stop()
\r
231 def action_nextTab(self):
\r
232 self.tablist.down()
\r
234 def action_prevTab(self):
\r
237 def action_menu(self):
\r
238 self.session.open(LastFMConfigScreen)
\r
240 def action_exit(self):
\r
241 print "action_exit"
\r
242 self.guiupdatetimer.stop()
\r
243 self.streamplayer.stop()
\r
246 def action_ok(self):
\r
247 selectedTag = self["streamlist"].l.getCurrentSelection()[1]
\r
248 self.changeStation(selectedTag)
\r
250 def action_startstop(self):
\r
251 if self.streamplayer.is_playing:
\r
252 self.streamplayer.stop()
\r
254 self.setInfoLabel("stream stopped")
\r
257 self.setInfoLabel("starting stream",timeout=True)
\r
258 if self.info.has_key("stream_url"):
\r
259 self.streamplayer.play(self.info["stream_url"])
\r
260 self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
\r
262 def setInfoLabel(self,text,timeout=True):
\r
263 self.infolabelcleartimer.stop()
\r
264 self["infolabel"].setText(text)
\r
265 if timeout is True:
\r
266 self.infolabelcleartimer.start(config.plugins.LastFM.timeoutstatustext.value*1000)
\r
268 def clearInfoLabel(self):
\r
269 self["infolabel"].setText("")
\r
271 def updateGUI(self):
\r
272 if self.streamplayer.is_playing is not True:
\r
275 if self.streamplayer.is_playing:
\r
276 self["button_red"].setText(_("stop"))
\r
278 self["button_red"].setText(_("play"))
\r
280 if self.metadata.has_key("station"):
\r
281 self.setTitle("Last.FM: "+self.metadata["station"])
\r
283 self.setTitle("Last.FM")
\r
285 if self.metadata.has_key("artist"):
\r
286 self["info_artist"].setText(self.metadata["artist"])
\r
288 self["info_artist"].setText("N/A")
\r
290 if self.metadata.has_key("album"):
\r
291 self["info_album"].setText(self.metadata["album"])
\r
293 self["info_album"].setText("N/A")
\r
295 if self.metadata.has_key("track"):
\r
296 self["info_track"].setText(self.metadata["track"])
\r
298 self["info_track"].setText("N/A")
\r
300 if self.metadata.has_key("albumcover_large") and config.plugins.LastFM.showcoverart.value:
\r
301 self.imageconverter.convert(self.metadata["albumcover_large"])
\r
302 elif self.metadata.has_key("albumcover_medium") and config.plugins.LastFM.showcoverart.value:
\r
303 self.imageconverter.convert(self.metadata["albumcover_medium"])
\r
304 elif self.metadata.has_key("albumcover_small") and config.plugins.LastFM.showcoverart.value:
\r
305 self.imageconverter.convert(self.metadata["albumcover_small"],self.setCoverArt)
\r
309 if self.streamplayer.is_playing is not True:
\r
310 self.setTitle(myname)
\r
312 self["info_artist"].setText("N/A")
\r
313 self["info_album"].setText("N/A")
\r
314 self["info_track"].setText("N/A")
\r
316 def setCoverArt(self,pixmap=None):
\r
318 self["info_cover"].instance.setPixmapFromFile(self.noCoverArtPNG)
\r
320 self["info_cover"].instance.setPixmap(pixmap.__deref__())
\r
323 def loadPersonalStations(self):
\r
326 x["_display"] = "Personal Radio"
\r
327 x["stationurl"] = self.getPersonalURL(config.plugins.LastFM.username.value,level=config.plugins.LastFM.recommendedlevel.value)
\r
331 x["_display"] = "Neighbours Tracks"
\r
332 x["stationurl"] = self.getNeighboursURL(config.plugins.LastFM.username.value)
\r
336 x["_display"] = "Loved Tracks"
\r
337 x["stationurl"] = self.getLovedURL(config.plugins.LastFM.username.value)
\r
340 if self.metadata.has_key("artist"):
\r
342 x["_display"] = "similar Tracks of current Artist"
\r
343 x["stationurl"] = self.getSimilarArtistsURL()
\r
347 x["_display"] = "Tracks liked by Fans of current Track"
\r
348 x["stationurl"] = self.getArtistsLikedByFans()
\r
352 x["_display"] = "Group of Artist of current Track"
\r
353 x["stationurl"] = self.getArtistGroup()
\r
357 self.buildMenuList(tags)
\r
359 def loadGlobalTags(self):
\r
360 self.setInfoLabel("loading Global Tags")
\r
361 tags = self.getGlobalTags()
\r
363 def loadTopTracks(self):
\r
364 self.setInfoLabel("loading Top Tacks")
\r
365 tracks = self.getTopTracks(config.plugins.LastFM.username.value)
\r
367 def loadRecentTracks(self):
\r
368 self.setInfoLabel("loading recent Tracks")
\r
369 tracks = self.getRecentTracks(config.plugins.LastFM.username.value)
\r
371 def loadLovedTracks(self):
\r
372 self.setInfoLabel("loading loved Tracks")
\r
373 tracks = self.getRecentLovedTracks(config.plugins.LastFM.username.value)
\r
375 def loadBannedTracks(self):
\r
376 self.setInfoLabel("loading loved Tracks")
\r
377 tracks = self.getRecentBannedTracks(config.plugins.LastFM.username.value)
\r
379 def loadNeighbours(self):
\r
380 self.setInfoLabel("loading Neighbours")
\r
381 tracks = self.getNeighbours(config.plugins.LastFM.username.value)
\r
383 def loadFriends(self):
\r
384 self.setInfoLabel("loading Friends")
\r
385 tracks = self.getFriends(config.plugins.LastFM.username.value)
\r
387 def buildMenuList(self,items):
\r
390 menuliste.append((i['_display'],i['stationurl']))
\r
391 self["streamlist"].l.setList(menuliste)
\r
394 class ImageConverter:
\r
396 targetfile= "/tmp/coverart"
\r
399 def __init__(self,callBack):
\r
400 self.callBack = callBack
\r
402 def convert(self,sourceURL):
\r
403 if self.lastURL != sourceURL:
\r
404 extension = sourceURL.split(".")[-1]
\r
405 self.tmpfile = self.targetfile+"."+extension
\r
406 host = sourceURL.split("/")[2]
\r
407 path = "/"+"/".join(sourceURL.split("/")[3:])
\r
409 httpclient.getFile(self.tmpfile,host,80,path,callback=self.onImageLoaded)
\r
410 self.lastURL = sourceURL
\r
412 def onImageLoaded(self):
\r
413 self.currPic = loadPic(self.tmpfile, 116, 116, 0,0, 0,1)
\r
414 os.remove(self.tmpfile)
\r
415 self.callBack(pixmap=self.currPic)
\r