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