[LastFM] Show playing track on LCD screen
[enigma2-plugins.git] / lastfm / src / plugin.py
1 from enigma import eTimer, loadPic, getDesktop
2
3 from Screens.Screen import Screen
4 from Screens.HelpMenu import HelpableScreen
5 from Components.Pixmap import Pixmap, MovingPixmap
6 from Components.Label import Label
7 from Components.MenuList import MenuList
8 from Screens.InputBox import InputBox
9
10 from Components.ActionMap import ActionMap
11 from Components.config import config, ConfigSubsection, ConfigInteger, ConfigYesNo, ConfigText, ConfigSelection, ConfigPassword
12 from Plugins.Plugin import PluginDescriptor
13
14 from StreamPlayer import StreamPlayer
15 from LastFMConfig import LastFMConfigScreen
16 from LastFM import LastFM
17 from urllib2 import quote as urllib2_qoute
18 from twisted.web.client import downloadPage
19 from os import remove as os_remove, system as os_system
20 from random import randrange
21
22 ###############################################################################        
23 plugin_path = ""
24 streamplayer = False
25 lastfm_pluginversion = "1.0.0"
26 ###############################################################################        
27
28 config.plugins.LastFM = ConfigSubsection()
29
30 config.plugins.LastFM.menu = ConfigSelection(default = "plugin", choices = [("plugin", _("Plugin menu")), ("extensions", _("Extensions menu"))])
31 config.plugins.LastFM.name = ConfigText(default = _("Last.FM"), fixed_size = False, visible_width = 20)
32 config.plugins.LastFM.description = ConfigText(default = _("Listen to Last.FM Internet Radio"), fixed_size = False, visible_width = 80)
33 config.plugins.LastFM.showcoverart = ConfigYesNo(default = True)
34 config.plugins.LastFM.username = ConfigText("user", fixed_size = False)
35 config.plugins.LastFM.password = ConfigPassword(default = "passwd", fixed_size = False)
36 config.plugins.LastFM.timeoutstatustext = ConfigInteger(3,limits = (0, 10))
37 config.plugins.LastFM.timeouttabselect = ConfigInteger(2,limits = (0, 10))
38 config.plugins.LastFM.metadatarefreshinterval = ConfigInteger(1,limits = (0, 100))
39 config.plugins.LastFM.recommendedlevel = ConfigInteger(3,limits = (0, 100))
40 config.plugins.LastFM.sendSubmissions = ConfigYesNo(default = False)
41
42 config.plugins.LastFM.useproxy = ConfigYesNo(default = False)
43 config.plugins.LastFM.proxyport = ConfigInteger(6676,limits = (1, 65536))
44
45 config.plugins.LastFM.sreensaver = ConfigSubsection()
46 config.plugins.LastFM.sreensaver.use = ConfigYesNo(default = True)
47 config.plugins.LastFM.sreensaver.wait = ConfigInteger(30,limits = (0, 1000))
48 config.plugins.LastFM.sreensaver.showcoverart = ConfigYesNo(default = True)
49 config.plugins.LastFM.sreensaver.coverartanimation = ConfigYesNo(default = True)
50 config.plugins.LastFM.sreensaver.coverartspeed = ConfigInteger(10,limits = (0, 100))
51 config.plugins.LastFM.sreensaver.coverartinterval = ConfigInteger(10,limits = (0, 100))
52
53 ###############################################################################        
54     
55 def main(session,**kwargs):
56     global streamplayer
57     if streamplayer is not False:
58         streamplayer.setSession(session)
59     else:
60         streamplayer = StreamPlayer(session)
61         
62     session.openWithCallback(LastFMScreenMainCB,LastFMScreenMain,streamplayer)    
63
64 def LastFMScreenMainCB():
65     pass
66
67 def startScrobbler(reason, **kwargs):
68     if "session" in kwargs and config.plugins.LastFM.sendSubmissions.value:
69         global streamplayer
70         if streamplayer is False:
71             streamplayer = StreamPlayer(kwargs["session"])
72         else:
73             streamplayer.setSession(kwargs["session"])
74         
75         from scrobbler import EventListener
76         evl = EventListener(kwargs["session"],streamplayer)
77         evl.startListenToEvents()
78         
79 def Plugins(path,**kwargs):
80     global plugin_path
81     plugin_path = path
82
83     list = [PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], fnc = startScrobbler)]
84
85     if config.plugins.LastFM.menu.value == "plugin":
86         list.append (PluginDescriptor(
87             name = config.plugins.LastFM.name.value, 
88             description = config.plugins.LastFM.description.value + " "  + _("Ver.") + " " + lastfm_pluginversion, 
89             where = PluginDescriptor.WHERE_PLUGINMENU,
90             icon = "plugin.png",
91             fnc = main)
92             )
93     else:
94         list.append (PluginDescriptor(
95             name = config.plugins.LastFM.name.value, 
96             description = config.plugins.shoutcast.LastFM.value + " "  + _("Ver.") + " " + lastfm_pluginversion, 
97             where = PluginDescriptor.WHERE_EXTENSIONSMENU, 
98             fnc = main)
99             )           
100
101     return list
102
103 ############################################################################### 
104 class LastFMScreenMain(Screen,HelpableScreen,LastFM):
105     skin = """
106         <screen name="LastFM" position="center,center" size="600,440" title="%s" >
107             
108             <widget name="artist" position="0,5" size="100,30" valign=\"center\" halign=\"left\" zPosition=\"2\"  foregroundColor=\"white\" font=\"Regular;18\" />          
109             <widget name="album" position="0,45" size="100,30" valign=\"center\" halign=\"left\" zPosition=\"2\"  foregroundColor=\"white\" font=\"Regular;18\" />          
110             <widget name="track" position="0,85" size="100,30" valign=\"center\" halign=\"left\" zPosition=\"2\"  foregroundColor=\"white\" font=\"Regular;18\" />          
111             
112             <widget name="info_artist" position="105,5" size="300,30" valign=\"center\" halign=\"left\" zPosition=\"2\"  foregroundColor=\"white\" font=\"Regular;18\" />          
113             <widget name="duration" position="420,5" size="60,30" valign=\"center\" halign=\"right\" zPosition=\"2\"  foregroundColor=\"white\" font=\"Regular;18\" />          
114             <widget name="info_album" position="105,45" size="370,30" valign=\"center\" halign=\"left\" zPosition=\"2\"  foregroundColor=\"white\" font=\"Regular;18\" />          
115             <widget name="info_track" position="105,85" size="370,30" valign=\"center\" halign=\"left\" zPosition=\"2\"  foregroundColor=\"white\" font=\"Regular;18\" />          
116             <widget name="info_cover" position="484,5" size="116,116" />          
117             
118             <widget name="tablist" position="0,140" size="190,220" scrollbarMode="showOnDemand" />            
119             <widget name="streamlist" position="200,140" size="400,225" scrollbarMode="showOnDemand" />            
120             
121             <widget name="button_red" position="0,370" size="140,40" valign=\"center\" halign=\"center\" zPosition=\"3\" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" font=\"Regular;18\" />          
122             <widget name="button_green" position="140,370" size="140,40" valign=\"center\" halign=\"center\" zPosition=\"3\" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" font=\"Regular;18\"/>            
123             <widget name="button_yellow" position="280,370" size="140,40" valign=\"center\" halign=\"center\" zPosition=\"3\" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" font=\"Regular;18\" />            
124             <widget name="button_blue" position="420,370" size="140,40" valign=\"center\" halign=\"center\" zPosition=\"3\" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" font=\"Regular;18\" />             
125             <ePixmap pixmap="skin_default/buttons/red.png" position="0,370" zPosition="2" size="140,40" transparent="1" alphatest="on" />
126             <ePixmap pixmap="skin_default/buttons/green.png" position="140,370" zPosition="2" size="140,40" transparent="1" alphatest="on" />
127             <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,370" zPosition="2" size="140,40" transparent="1" alphatest="on" />
128             <ePixmap pixmap="skin_default/buttons/blue.png" position="420,370" zPosition="2" size="140,40" transparent="1" alphatest="on" />
129             <ePixmap position="570,380" size="35,25" pixmap="skin_default/buttons/key_menu.png" alphatest="on" />
130             <widget name="infolabel" position="10,415" size="500,15" valign=\"center\" halign=\"left\" zPosition=\"2\"  foregroundColor=\"white\" font=\"Regular;16\" />           
131         </screen>""" %(config.plugins.LastFM.name.value + " "  + _("Ver.") + " " + lastfm_pluginversion) # title
132          
133     noCoverArtPNG = "/usr/share/enigma2/skin_default/no_coverArt.png"
134     
135     def __init__(self, session,streamplayer, args = 0):
136         self.skin = LastFMScreenMain.skin
137         Screen.__init__(self, session)
138         HelpableScreen.__init__(self)
139         LastFM.__init__(self)
140         self.session = session
141         self.streamplayer = streamplayer#StreamPlayer(session)
142         self.streamplayer.onStateChanged.append(self.onStreamplayerStateChanged)
143         self.imageconverter = ImageConverter(116,116,self.setCoverArt)
144         Screen.__init__(self, session)
145         
146         self.tabs=[("Personal Stations",self.loadPersonalStations)
147                    ,("Global Tags",self.loadGlobalTags)
148                    ,("Top Tracks",self.loadTopTracks)
149                    ,("Recent Tracks",self.loadRecentTracks)
150                    ,("Loved Tracks",self.loadLovedTracks)
151                    ,("Banned Tracks",self.loadBannedTracks)
152                    ,("Friends",self.loadFriends)
153                    ,("Neighbours",self.loadNeighbours)
154                    ]
155         tablist =[]
156         for tab in self.tabs:
157             tablist.append((tab[0],tab))
158         self.tablist = MenuList(tablist)
159         self.tablist.onSelectionChanged.append(self.action_TabChanged)
160         
161         self["artist"] = Label(_("Artist")+":")
162         self["duration"] = Label("-00:00")
163         self["album"] = Label(_("Album")+":")
164         self["track"] = Label(_("Track")+":")
165         
166         self["info_artist"] = Label("N/A")
167         self["info_album"] = Label("N/A")
168         self["info_track"] = Label("N/A")
169         self["info_cover"] = Pixmap()
170         
171         self["tablist"] = self.tablist
172         self["streamlist"] = MenuList([])
173         
174         self["button_red"] = Label(_("Play"))
175         self["button_green"] = Label(_("Skip"))
176         self["button_yellow"] = Label(_("Love"))
177         self["button_blue"] = Label(_("Ban"))
178         self["infolabel"] = Label("")
179         
180         self["actions"] = ActionMap(["InfobarChannelSelection","WizardActions", "DirectionActions","MenuActions","ShortcutActions","GlobalActions","HelpActions","NumberActions"], 
181             {
182              "ok": self.action_ok,
183              "back": self.action_exit,
184              "red": self.action_startstop,
185              "green": self.skipTrack,
186              "yellow": self.love,
187              "blue": self.banTrack ,
188              "historyNext": self.action_nextTab,
189              "historyBack": self.action_prevTab,
190              
191              "menu": self.action_menu,
192              }, -1)
193         
194         self.helpList.append((self["actions"], "WizardActions", [("ok", _("Switch to selected Station"))]))
195         self.helpList.append((self["actions"], "InfobarChannelSelection", [("historyNext", _("Select next Tab"))]))
196         self.helpList.append((self["actions"], "InfobarChannelSelection", [("historyBack", _("Select prev Tab"))]))
197         self.helpList.append((self["actions"], "InfobarChannelSelection", [("switchChannelDown", _("Next Selection"))]))
198         self.helpList.append((self["actions"], "InfobarChannelSelection", [("switchChannelUp", _("Previous Selection"))]))     
199         self.helpList.append((self["actions"], "InfobarChannelSelection", [("zapDown", _("Page forward Selections"))]))
200         self.helpList.append((self["actions"], "InfobarChannelSelection", [("zapUp", _("Page backward Selections"))]))
201         self.helpList.append((self["actions"], "ShortcutActions", [("red", _("Start/stop streaming"))]))
202         self.helpList.append((self["actions"], "ShortcutActions", [("green", _("Skip current Track"))]))
203         self.helpList.append((self["actions"], "ShortcutActions", [("yellow", _("Mark current Track as loved"))]))
204         self.helpList.append((self["actions"], "ShortcutActions", [("blue", _("Ban Track, never play again"))]))                
205         self.helpList.append((self["actions"], "MenuActions", [("menu", _("Open") + " " + _("Setup"))]))                
206         self.helpList.append((self["actions"], "WizardActions", [("back", _("Quit" + " " + config.plugins.LastFM.name.value))]))
207
208         self.onLayoutFinish.append(self.initLastFM)
209         self.onLayoutFinish.append(self.tabchangedtimerFired)
210         self.onLayoutFinish.append(self.setCoverArt)
211         
212         self.guiupdatetimer = eTimer()
213         self.guiupdatetimer.timeout.get().append(self.guiupdatetimerFired)
214         self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
215         
216         self.tabchangetimer = eTimer()
217         self.tabchangetimer.timeout.get().append(self.tabchangedtimerFired)
218         
219         self.infolabelcleartimer = eTimer()
220         self.infolabelcleartimer.timeout.get().append(self.clearInfoLabel)
221
222         self.screensavertimer = eTimer()
223         self.screensavertimer.timeout.get().append(self.startScreensaver)
224         self.onShown.append(self.startScreensaverTimer)
225         
226
227     def initLastFM(self):
228         self.setInfoLabel(_("logging into last.fm"))
229         self.connect(config.plugins.LastFM.username.value,config.plugins.LastFM.password.value)
230         
231     def onStreamplayerStateChanged(self,reason):
232         if reason is self.streamplayer.STATE_PLAYLISTENDS:
233             self.loadPlaylist()
234         else:
235             pass
236     def onConnectSuccessful(self,text):
237         self.setInfoLabel(_("login successful"))
238     
239     def onConnectFailed(self,text):
240         self.setInfoLabel(_("login failed! ")+text,timeout=False)
241
242     def onTrackSkiped(self,reason):
243         self.setInfoLabel(_("Track skipped"))
244
245     def onTrackLoved(self,reason):
246         self.setInfoLabel(_("Track loved"))
247     
248     def onTrackBanned(self,reason):
249         self.setInfoLabel(_("Track banned"))       
250     
251     def onCommandFailed(self,reason):
252         self.setInfoLabel(reason)
253
254     def onGlobalTagsLoaded(self,tags):
255         self.setInfoLabel(_("Global Tags loaded"))
256         self.buildMenuList(tags)
257
258     def onTopTracksLoaded(self,tracks):
259         self.setInfoLabel(_("Top Tracks loaded"))
260         self.buildMenuList(tracks)
261
262     def onRecentTracksLoaded(self,tracks):
263         self.setInfoLabel(_("Recent Tracks loaded"))
264         self.buildMenuList(tracks)
265         
266     def onRecentBannedTracksLoaded(self,tracks):
267         self.setInfoLabel(_("Banned Tracks loaded"))
268         self.buildMenuList(tracks)
269
270     def onRecentLovedTracksLoaded(self,tracks):
271         self.setInfoLabel(_("Loved Tracks loaded"))
272         self.buildMenuList(tracks)
273
274     def onNeighboursLoaded(self,user):
275         self.setInfoLabel(_("Neighbours loaded"))
276         self.buildMenuList(user)
277
278     def onFriendsLoaded(self,user):
279         self.setInfoLabel(_("Friends loaded"))
280         self.buildMenuList(user)
281     
282     def onStationChanged(self,reason):
283         self.setInfoLabel(reason) 
284         self.loadPlaylist() 
285         
286     def onMetadataLoaded(self,metadata):
287         self.updateGUI()
288         self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
289     
290     def onPlaylistLoaded(self,reason):
291         self.streamplayer.setPlaylist(self.playlist)
292         self.streamplayer.play()
293
294     def skipTrack(self):
295         self.streamplayer.skip()
296         self.updateGUI()
297         
298     def banTrack(self):
299         self.ban()
300         self.streamplayer.skip()
301         self.updateGUI()
302         
303     def action_TabChanged(self):
304         self.tabchangetimer.stop()
305         self.tabchangetimer.start(config.plugins.LastFM.timeouttabselect.value*1000)
306                     
307     def guiupdatetimerFired(self):
308         self.updateGUI()
309         self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
310         
311     def tabchangedtimerFired(self):
312         self.tablist.getCurrent()[1][1]()
313         self.tabchangetimer.stop()
314
315     def startScreensaverTimer(self):
316         self.screensavertimer.start(config.plugins.LastFM.sreensaver.wait.value*1000)
317
318     def resetScreensaverTimer(self):
319         self.screensavertimer.stop()
320         self.screensavertimer.start(config.plugins.LastFM.sreensaver.wait.value*1000)
321         
322     def startScreensaver(self):
323         if config.plugins.LastFM.sreensaver.use.value:
324             self.screensavertimer.stop()
325             self.session.openWithCallback(self.updateGUI, LastFMSaveScreen,self)
326             
327     def action_nextTab(self):
328         self.tablist.down()
329         self.resetScreensaverTimer()
330         
331     def action_prevTab(self):
332         self.tablist.up()
333         self.resetScreensaverTimer()
334
335     def action_menu(self):
336         self.session.open(LastFMConfigScreen)
337         self.resetScreensaverTimer()
338
339     def action_exit(self):
340         self.screensavertimer.stop()
341         self.guiupdatetimer.stop()
342         self.streamplayer.stop(force=True)
343         self.streamplayer.onStateChanged=[]
344         
345         self.close()
346
347     def action_ok(self):
348         x = self["streamlist"].l.getCurrentSelection()
349         if x is None:
350             pass
351         elif len(x) >1:
352             if not x[1].startswith('lastfm://'):
353                 self.customstationtype = x[1]
354                 text = _("please enter an %s name to listen to"% x[1])
355                 texts = _("%s name"% x[1])
356                 self.session.openWithCallback(
357                     self.onTextForCustomStationEntered,
358                     InputBox,
359                     windowTitle = text,
360                     title = texts
361                     )
362             else:
363                 self.changeStation(x[1])
364                 self.resetScreensaverTimer()
365
366     def onTextForCustomStationEntered(self,text):
367         print "onTextForCustomStationEntered",text,self.customstationtype
368         if text is not None:
369             if self.customstationtype =="artist":
370                 self.changeStation(urllib2_qoute("lastfm://artist/%s/similarartists"%text))
371             elif self.customstationtype =="groupe":
372                 self.changeStation(urllib2_qoute("lastfm://group/%s"%text))
373             elif self.customstationtype =="tag":
374                 self.changeStation(urllib2_qoute("lastfm://globaltags/%s"%text))
375                         
376     def action_startstop(self):
377         self.resetScreensaverTimer()
378         if self.streamplayer.is_playing:
379             self.streamplayer.stop(force=True)
380             self.setInfoLabel(_("Stream stopped"))
381         else:
382             self.setInfoLabel(_("Starting stream"),timeout=True)
383             self.loadPlaylist()
384             self.updateGUI() #forcing guiupdate, so we dont wait till guiupdatetimer fired
385             self.guiupdatetimer.start(config.plugins.LastFM.metadatarefreshinterval.value*1000)
386
387     def setInfoLabel(self,text,timeout=True):
388         self.infolabelcleartimer.stop() 
389         self["infolabel"].setText(text)
390         if timeout is True:
391             self.infolabelcleartimer.start(config.plugins.LastFM.timeoutstatustext.value*1000)
392             
393     def clearInfoLabel(self):
394         self["infolabel"].setText("")
395         
396     def updateGUI(self):
397         
398         if self.streamplayer.is_playing is True:
399             self["duration"].setText(self.streamplayer.getRemaining())
400             self["button_red"].setText(_("Stop"))
401         else:
402             self["duration"].setText("00:00")
403             self["button_red"].setText(_("Play"))
404                          
405         if self.streamplayer.is_playing is not True or self.shown is not True:
406             return None
407             
408         if self.streamplayer.is_playing is True:
409             self.setTitle("Last.FM: "+self.streamplayer.getMetadata("station"))
410             self["info_artist"].setText(self.streamplayer.getMetadata("creator"))
411             self["info_album"].setText(self.streamplayer.getMetadata("album"))
412             self["info_track"].setText(self.streamplayer.getMetadata("title"))
413             self.summaries.setText(self.streamplayer.getMetadata("creator") + " - " + self.streamplayer.getMetadata("title"))
414         else:
415             self.setTitle("Last.FM")
416             self["info_artist"].setText("N/A")
417             self["info_album"].setText("N/A")
418             self["info_track"].setText("N/A")
419             self.summaries.setText("N/A")            
420         
421         if self.streamplayer.getMetadata("image").startswith("http") and config.plugins.LastFM.showcoverart.value:
422             self.imageconverter.convert(self.streamplayer.getMetadata("image"))
423         else:
424             self.setCoverArt()
425         
426         if self.streamplayer.is_playing is not True:
427             self.setTitle(myname)
428             self.setCoverArt()
429             self["info_artist"].setText("N/A")
430             self["info_album"].setText("N/A")
431             self["info_track"].setText("N/A")
432         
433     def setCoverArt(self,pixmap=None):
434         if pixmap is None:
435             self["info_cover"].instance.setPixmapFromFile(self.noCoverArtPNG)            
436         else:
437             self["info_cover"].instance.setPixmap(pixmap.__deref__())
438     
439
440     def loadPersonalStations(self):
441         tags = []
442         x= {}
443         x["_display"] = _("Personal Recommendations")
444         x["stationurl"] = self.getPersonalURL(config.plugins.LastFM.username.value,level=config.plugins.LastFM.recommendedlevel.value)
445         tags.append(x)
446
447         x= {}
448         x["_display"] = _("Neighbours Tracks")
449         x["stationurl"] = self.getNeighboursURL(config.plugins.LastFM.username.value)
450         tags.append(x)
451         
452         x= {}
453         x["_display"] = _("Loved Tracks")
454         x["stationurl"] = self.getLovedURL(config.plugins.LastFM.username.value)
455         tags.append(x)
456         
457         x= {}
458         x["_display"] = _("Play Artist Radio ...")
459         x["stationurl"] = 'artist'
460         tags.append(x)
461
462         x= {}
463         x["_display"] = _("Play Group Radio ...")
464         x["stationurl"] = 'groupe'
465         tags.append(x)
466         
467         x= {}
468         x["_display"] = _("Play Tag Radio ...")
469         x["stationurl"] = 'tag'
470         tags.append(x)
471         
472         
473         creator = self.streamplayer.getMetadata("creator")
474         if creator != "no creator" and creator != "N/A":
475             x= {}
476             x["_display"] = _("Tracks similar to ")+self.streamplayer.getMetadata("creator")
477             x["stationurl"] = self.getSimilarArtistsURL(artist=creator)
478             tags.append(x)
479             
480             x= {}
481             x["_display"] = _("Tracks liked by Fans of ")+self.streamplayer.getMetadata("creator")
482             x["stationurl"] = self.getArtistsLikedByFans(artist=creator)
483             tags.append(x)
484
485             x= {}
486             x["_display"] = _("Group of ")+self.streamplayer.getMetadata("creator")
487             x["stationurl"] = self.getArtistGroup(artist=creator)
488             tags.append(x)
489         
490         self.buildMenuList(tags)
491         
492     def loadGlobalTags(self):
493         self.setInfoLabel(_("Loading Global Tags"))
494         tags = self.getGlobalTags()
495
496     def loadTopTracks(self):
497         self.setInfoLabel(_("Loading Top Tacks"))
498         tracks = self.getTopTracks(config.plugins.LastFM.username.value)
499
500     def loadRecentTracks(self):
501         self.setInfoLabel(_("Loading Recent Tracks"))
502         tracks = self.getRecentTracks(config.plugins.LastFM.username.value)
503
504     def loadLovedTracks(self):
505         self.setInfoLabel(_("Loading Loved Tracks"))
506         tracks = self.getRecentLovedTracks(config.plugins.LastFM.username.value)
507
508     def loadBannedTracks(self):
509         self.setInfoLabel(_("Loading Loved Tracks"))
510         tracks = self.getRecentBannedTracks(config.plugins.LastFM.username.value)
511         
512     def loadNeighbours(self):
513         self.setInfoLabel(_("Loading Neighbours"))
514         tracks = self.getNeighbours(config.plugins.LastFM.username.value)
515
516     def loadFriends(self):
517         self.setInfoLabel(_("Loading Friends"))
518         tracks = self.getFriends(config.plugins.LastFM.username.value)
519
520     def buildMenuList(self,items):
521         menuliste = []
522         for i in items:
523             menuliste.append((i['_display'],i['stationurl']))
524         self["streamlist"].l.setList(menuliste) 
525
526     def createSummary(self):
527         return lastfmLCDScreen
528
529 class LastFMSaveScreen(Screen):
530     skin = """<screen position="0,0" size="720,576" flags="wfNoBorder" title="LastFMSaveScreen" >
531                 <widget name="cover" position="50,50" size="200,200" />          
532               </screen>"""
533               
534     noCoverArtPNG = "/usr/share/enigma2/skin_default/no_coverArt.png"
535     coverartsize= [200,200]
536     lastcreator=""
537     
538     def __init__(self,session,parent):
539         size_w = getDesktop(0).size().width()    
540         size_h = getDesktop(0).size().height()
541         self.skin = """<screen position="0,0" size="%i,%i" flags="wfNoBorder" title="LastFMSaveScreen" >
542                 <widget name="cover" position="50,50" size="%i,%i" />          
543               </screen>"""%(size_w,size_h,self.coverartsize[0],self.coverartsize[1])
544     
545         Screen.__init__(self,session)
546         self.imageconverter = ImageConverter(self.coverartsize[0],self.coverartsize[1],self.setCoverArt)
547         self.session = session
548         self.streamplayer = parent.streamplayer
549         self.parent = parent
550         self["cover"] = MovingPixmap()
551                         
552         self["actions"] = ActionMap(["InfobarChannelSelection","WizardActions", "DirectionActions","MenuActions","ShortcutActions","GlobalActions","HelpActions"], 
553             {
554              "ok": self.action_exit,
555              "back": self.action_exit,
556                          "red": self.parent.action_startstop,
557              "green": self.parent.skipTrack,
558              "yellow": self.parent.love,
559              "blue": self.parent.banTrack ,
560              }, -1)
561         
562         self.onLayoutFinish.append(self.update)
563         self.updatetimer = eTimer()
564         self.updatetimer.timeout.get().append(self.update)
565         self.updatetimer.start(1000)
566             
567         if config.plugins.LastFM.sreensaver.coverartanimation.value:
568             self.startmovingtimer = eTimer()
569             self.startmovingtimer.timeout.get().append(self.movePixmap)
570             self.startmovingtimer.start(config.plugins.LastFM.sreensaver.coverartinterval.value*1000)
571         
572     def action_ok(self):
573         pass
574     
575     def action_exit(self):
576         self.close()
577         
578     def setCoverArt(self,pixmap=None):
579         if pixmap is None:
580             self["cover"].instance.setPixmapFromFile(self.noCoverArtPNG)            
581         else:
582             self["cover"].instance.setPixmap(pixmap.__deref__())        
583     
584     def update(self):
585         if self.streamplayer.getMetadata("creator") == self.lastcreator:
586             pass
587         else:
588             self.lastcreator = self.streamplayer.getMetadata("creator")
589             self.setTitle(self.lastcreator+" - "+self.streamplayer.getMetadata("title"))
590             if config.plugins.LastFM.sreensaver.showcoverart.value is not True:
591                 pass#do nothing
592             elif self.streamplayer.getMetadata("image").startswith("http") and config.plugins.LastFM.showcoverart.value:
593                 self.imageconverter.convert(self.streamplayer.getMetadata("image"))
594             else:
595                 self.setCoverArt()
596         self.updatetimer.start(1000)
597         
598     def movePixmap(self):
599         self.startmovingtimer.stop() 
600         newX = randrange(getDesktop(0).size().width()-self.coverartsize[0]-1)
601         newY = randrange(getDesktop(0).size().height()-self.coverartsize[1]-1)
602         self["cover"].moveTo(newX, newY, time = config.plugins.LastFM.sreensaver.coverartspeed.value)
603         self["cover"].startMoving()
604         self.startmovingtimer.start(config.plugins.LastFM.sreensaver.coverartinterval.value*1000)
605
606 class lastfmLCDScreen(Screen):
607         skin = """
608         <screen name="LastFM_Summary" position="0,0" size="132,64" id="1">
609                 <widget name="text1" position="2,0" size="128,14" font="Regular;12" halign="center" valign="center"/>
610                 <widget name="text2" position="2,14" size="128,50" font="Regular;10" halign="center" valign="center"/>
611         </screen>"""
612
613         def __init__(self, session, parent):
614                 Screen.__init__(self, session)
615                 self["text1"] = Label(config.plugins.LastFM.name.value + " " + _("playing:"))
616                 self["text2"] = Label("")
617
618         def setText(self, text):
619                 self["text2"].setText(text)
620
621 class ImageConverter:
622     
623     lastURL = ""
624
625     def __init__(self,width,height,callBack):
626         self.callBack = callBack
627         self.width = width
628         self.height = height
629         self.targetfile= "/tmp/coverart"+str(randrange(5000))
630     
631         
632     def convert(self,sourceURL):
633         if self.lastURL != sourceURL:
634             extension = sourceURL.split(".")[-1]
635             self.tmpfile = self.targetfile+"."+extension
636             downloadPage(sourceURL,self.tmpfile).addCallback(self.onImageLoaded)
637             self.lastURL = sourceURL
638
639     def onImageLoaded(self,dummy):
640             self.currPic = loadPic(self.tmpfile, self.width, self.height, 0,1, 0,1)
641             os_remove(self.tmpfile)
642             self.callBack(pixmap=self.currPic)
643