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