~ubuntu-branches/ubuntu/lucid/exaile/lucid

« back to all changes in this revision

Viewing changes to plugins/contextinfo/__init__.py

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Starr-Bochicchio
  • Date: 2010-02-12 19:51:01 UTC
  • mfrom: (1.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20100212195101-8jt3tculxcl92e6v
Tags: 0.3.1~b1-0ubuntu1
* New upstream release.
* Adjust exaile.install for new plugins.
* debian/control:
 - Drop unneeded python-dev Build-Dep.
 - Bump Standards-Version to 3.8.4 
* debian/rules: No empty po files to delete.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
from xl import main as ex, track, common, event, xdg, settings, providers
 
1
from xl import main as ex, trax, common, event, xdg, settings, providers
2
2
from xl.nls import gettext as _
3
3
from xlgui import panel, guiutil, playlist, menu
4
4
import HTMLParser
 
5
from StringIO import StringIO
5
6
import Image
6
7
import base64
7
8
import gobject
8
9
import gtk
9
10
import os
10
11
import pylast
 
12
import contextprefs
11
13
import re
12
14
import urllib
13
15
import webkit
14
16
import xlgui
15
17
from inspector import Inspector
16
18
 
17
 
LFM_API_KEY = '3b954460f7b207e5414ffdf8c5710592'
 
19
# Last.fm API Key for Exaile
 
20
# if you reuse this code in a different application, please
 
21
# register your own key with last.fm
 
22
LFM_API_KEY = "3599c79a97fd61ce518b75922688bc38"
 
23
 
18
24
PANEL = None
19
25
CURPATH = os.path.realpath(__file__)
20
26
BASEDIR = os.path.dirname(CURPATH)+os.path.sep
32
38
        selected = self.widget.get_selected_tracks()
33
39
        pl = xlgui.controller().main.get_selected_playlist()
34
40
        if pl:
35
 
            pl.playlist.add_tracks(selected, add_duplicates=False)
 
41
            pl.playlist.add_tracks(selected)
36
42
 
37
43
    def on_queue(self, selected=None):
38
44
        """
40
46
        """
41
47
        selected = self.widget.get_selected_tracks()
42
48
        pl = xlgui.controller().main.get_selected_playlist()
43
 
        ex.exaile().queue.add_tracks(selected, add_duplicates=False)
 
49
        ex.exaile().queue.add_tracks(selected)
44
50
        if pl:
45
 
            pl.playlist.add_tracks(selected, add_duplicates=False)
 
51
            pl.playlist.add_tracks(selected)
46
52
            pl.list.queue_draw()
47
53
 
48
54
class BrowserPage(webkit.WebView, providers.ProviderHandler):
260
266
    def drag_get_data(self, w, context, selection, target_id, etime):
261
267
        tracks = self.get_selected_tracks()
262
268
        for track in tracks:
263
 
            guiutil.DragTreeView.dragged_data[track.get_loc()] = track
 
269
            guiutil.DragTreeView.dragged_data[track.get_loc_for_io()] = track
264
270
        urls = guiutil.get_urls_for(tracks)
265
271
        selection.set_uris(urls)
266
272
 
291
297
        selected = self.get_selected_tracks()
292
298
        pl = xlgui.controller().main.get_selected_playlist()
293
299
        if pl:
294
 
            pl.playlist.add_tracks(selected, add_duplicates=False)
 
300
            pl.playlist.add_tracks(selected)
295
301
 
296
302
    def _navigation_requested_cb(self, view, frame, networkRequest):
297
303
        link = self.un_url(networkRequest.get_uri()).split('://', 1)
334
340
        ex.exaile().gui.panels['collection'].filter.set_text('artist=%s' % self.hover.split('://')[1])
335
341
        ex.exaile().gui.panel_notebook.set_current_page(0)
336
342
 
337
 
class ImageBuffer(object):
338
 
    def __init__(self):
339
 
        self.buffer = ""
340
 
 
341
 
    def write(self, str):
342
 
        self.buffer+=str
343
 
 
344
 
    def get_base64(self):
345
 
        return base64.b64encode(self.buffer)
346
 
 
347
343
class ContextTheme(object):
348
344
 
349
345
    LOCAL_COLORS = None
400
396
    else:
401
397
        return None
402
398
 
403
 
def get_image_data(filename, size):
 
399
class ImageBuffer(object):
 
400
    def __init__(self):
 
401
        self.buffer = ""
 
402
    
 
403
    def write(self, str):
 
404
        self.buffer+=str
 
405
        
 
406
    def get_base64(self):
 
407
        return base64.b64encode(self.buffer)
 
408
 
 
409
def get_image_data(data, size):
404
410
    imbuff = ImageBuffer()
405
 
    im = Image.open(filename)
 
411
    try:
 
412
        im = Image.open(StringIO(data))
 
413
    except Exception:
 
414
        im = Image.open(xdg.get_data_path('images/nocover.png'))
406
415
    im = im.resize(size, Image.ANTIALIAS)
407
416
    im.save(imbuff, "PNG")
408
417
    return 'data:image/png;base64,%s' % imbuff.get_base64()
413
422
        cover = ex.exaile().covers.get_cover(track)
414
423
    except: pass
415
424
    if cover == None:
416
 
        cover = xdg.get_data_path('images/nocover.png')
 
425
        cover = ex.exaile().covers.get_default_cover()
417
426
    return cover
418
427
 
419
428
def get_track_tag(track, tag, default):
420
429
    try:
421
 
        return str(track[tag][0])
 
430
        return track.get_tag_display(tag)
422
431
    except:
423
432
        return default
424
433
 
583
592
                    track_nbr = len(ex.exaile().collection.search('album=="%s"'% cd, tracks=tracks))
584
593
                cover = get_track_cover(tr)
585
594
                cover_data = get_image_data(cover, (60, 60))
 
595
                
586
596
                html+='''<tr class="cd-tr">\
587
597
<td><a href="album://%s"><img class="cd-img" src="%s"/></a></td>\
588
598
<td class="cd-title-td"><a href="album://%s"><b>%s</b><br/>%s</a></td>\
653
663
class DefaultPage(ContextPage):
654
664
 
655
665
    def __init__(self, theme, base='default://', template='default.html', async=[]):
 
666
        self.user = None
656
667
        try:
657
 
            self.username = settings.get_option('plugin/ascrobbler/user')
 
668
            self.username = settings.get_option('plugin/lastfm/user')
 
669
            self.password_hash = pylast.md5(settings.get_option('plugin/lastfm/password'))
658
670
        except:
659
671
            self.username = None
 
672
            self.password_hash = None
 
673
 
660
674
        ContextPage.__init__(self, theme, base, template, async+['last-played-tracks', 'last-played-artists', 'last-added-tracks', 'last-added-artists', 'most-played-tracks', 'most-played-artists', 'lfm-last-played', 'lfm-top-tracks', 'lfm-top-albums', 'lfm-top-artists'])
661
675
 
662
676
    def _last_played_tracks_title(self):
663
 
        return "Rencently Played Tracks"
 
677
        return "Recently Played Tracks"
664
678
 
665
679
    def _last_played_tracks(self, limit=10):
666
680
        tracks = get_top_tracks('__last_played', int(limit))
667
681
        return "<br/>".join(self.get_track_anchor_from_track(track, img=True) for track in tracks)
668
682
 
669
683
    def _last_played_albums_title(self):
670
 
        return "Rencently Played Albums"
 
684
        return "Recently Played Albums"
671
685
 
672
686
    def _last_played_albums(self, limit=5):
673
687
        cds = get_top_albums('last_played', int(limit))
676
690
        return ''
677
691
 
678
692
    def _last_played_artists_title(self):
679
 
        return "Rencently Played Artists"
 
693
        return "Recently Played Artists"
680
694
 
681
695
    def _last_played_artists(self, limit=10):
682
696
        artists = get_top_artists('__last_played', int(limit))
728
742
        artists = get_top_artists('__playcount', int(limit))
729
743
        return ', '.join(self.get_artist_anchor(artist) for artist in artists)
730
744
 
 
745
    def get_lfm_user(self):
 
746
        if not self.user:
 
747
            self.user = pylast.User(self.username, self.password_hash, pylast.network)
 
748
        return self.user
 
749
 
731
750
    def _lfm_last_played_title(self):
732
751
        return "Last Scrobbled Tracks"
733
752
 
734
753
    def _lfm_last_played(self, limit=10):
735
 
        if self.username:
736
 
            tracks = pylast.User(self.username, LFM_API_KEY, None, None).get_recent_tracks(int(limit))
737
 
            return '<br/>'.join(self.get_track_anchor_from_artist_title(tr.get_track().get_artist(), tr.get_track().get_title()) for tr in tracks)
 
754
        if get_lfm_user():
 
755
            tracks = self.get_lfm_user().get_recent_tracks(int(limit))
 
756
            return '<br/>'.join(self.get_track_anchor_from_artist_title(tr.track.get_artist(), tr.track.get_title()) for tr in tracks)
738
757
        return "Enter your username in the settings"
739
758
 
740
759
    def _lfm_top_tracks_title(self):
741
760
        return "Your Top Tracks on Last.fm"
742
761
 
743
762
    def _lfm_top_tracks(self, period='overall', limit=15):
744
 
        if self.username:
745
 
            tracks = pylast.User(self.username, LFM_API_KEY, None, None).get_top_tracks(period)[:int(limit)]
746
 
            return '<br/>'.join(self.get_track_anchor_from_artist_title(tr.get_item().get_artist(), tr.get_item().get_title()) for tr in tracks)
 
763
        if self.get_lfm_user():
 
764
            tracks = self.get_lfm_user().get_top_tracks(period, int(limit))
 
765
            return '<br/>'.join(self.get_track_anchor_from_artist_title(tr.track.get_artist(), tr.track.get_title()) for tr in tracks)
747
766
        return "Enter your username in the settings"
748
767
 
749
768
    def _lfm_top_artists_title(self):
750
769
        return "Your Top Artists on Last.fm"
751
770
 
752
771
    def _lfm_top_artists(self, period='overall', limit=20):
753
 
        if self.username:
754
 
            artists = pylast.User(self.username, LFM_API_KEY, None, None).get_top_artists(period)[:int(limit)]
755
 
            return ', '.join(self.get_artist_anchor(artist.get_item().get_name()) for artist in artists)
 
772
        if self.get_lfm_user():
 
773
            artists = self.get_lfm_user().get_top_artists(period,int(limit))
 
774
            return ', '.join(self.get_artist_anchor(artist.item.get_name()) for artist in artists)
756
775
        return "Enter your username in the settings"
757
776
 
758
777
    def _lfm_top_albums_title(self):
759
778
        return "Your Top Albums on Last.fm"
760
779
 
761
780
    def _lfm_top_albums(self, period='overall', limit=10):
762
 
        if self.username:
763
 
            cds = [album.get_item().get_title() for album in pylast.User(self.username, LFM_API_KEY, None, None).get_top_albums(period)[:int(limit)]]
 
781
        if self.get_lfm_user():
 
782
            cds = [album.get_item().get_title() for album in self.get_lfm_user().get_top_albums(period,int(limit))]
764
783
            tracks = []
765
784
            if len(cds)>0:
766
785
                for cd in cds:
772
791
class ArtistPage(DefaultPage):
773
792
    def __init__(self, theme, artist, base = 'artist://', template ='artist.html', async=[]):
774
793
        self.artist = artist
775
 
        self.artist_tracks = get_artist_tracks(artist)
 
794
        self.lfm_artist = None
 
795
 
776
796
        DefaultPage.__init__(self, theme, base, template, async+['compils', 'albums', 'artist-info', 'artist-img', 'artist-tags', 'similar-artists', 'top-tracks'])
777
797
 
 
798
    def get_lfm_artist(self):
 
799
        if not self.lfm_artist:
 
800
            self.lfm_artist = pylast.Artist(self.artist, pylast.network)
 
801
        return self.lfm_artist
 
802
 
778
803
    def get_template_fields(self):
779
804
        fields = ContextPage.get_template_fields(self)
780
805
        for field in fields:
805
830
    def _artist(self):
806
831
        return self.artist
807
832
 
808
 
    def _artist_img(self, size=pylast.IMAGE_LARGE):
 
833
    def _artist_img(self, size=pylast.COVER_LARGE):
809
834
        try:
810
 
            url = pylast.search_for_artist(self.artist, LFM_API_KEY, None, None).get_next_page()[0].get_image_url(size)
 
835
            url = self.get_lfm_artist().get_cover_image(size)
811
836
            return '<img id="artist-info-img" src="%s"/>' % url
812
837
        except:
813
838
            return ''
814
839
 
815
840
    def _artist_info(self):
816
 
        bio = pylast.search_for_artist(self.artist, LFM_API_KEY, None, None).get_next_page()[0].get_bio_summary()
817
 
        return self.LFMInfoParser(self, str(bio), self['artist']).data
 
841
        if self.get_lfm_artist():
 
842
            bio = self.get_lfm_artist().get_bio_summary()
 
843
            return self.LFMInfoParser(self, str(bio), self['artist']).data
 
844
        return ''
818
845
 
819
846
    def _top_tracks_title(self):
820
847
        return 'Top tracks by %s' % self['artist']
821
848
 
822
849
    def _top_tracks(self, limit=10):
823
 
        doc = pylast.search_for_artist(self['artist'],LFM_API_KEY, None, None).get_next_page()[0].get_top_tracks()[:int(limit)]
824
 
        return '<br/>'.join(self.get_track_anchor_from_artist_title(self['artist'], tr.get_item().get_title(), img=True) for tr in doc)
 
850
        if self.get_lfm_artist():
 
851
            doc = self.get_lfm_artist().get_top_tracks(int(limit))
 
852
            return '<br/>'.join(self.get_track_anchor_from_artist_title(self['artist'], tr.get_item().get_title(), img=True) for tr in doc)
 
853
        return ''
825
854
 
826
855
    def _artist_tags_title(self):
827
856
        return "Tags for %s" % self['artist']
828
857
 
829
858
    def _artist_tags(self, limit=10):
830
 
        doc = pylast.search_for_artist(self['artist'],LFM_API_KEY, None, None).get_next_page()[0].get_top_tags()[:int(limit)]
831
 
        return ', '.join(self.get_tag_anchor(tag) for tag in doc)
 
859
        if self.get_lfm_artist():
 
860
            doc = self.get_lfm_artist().get_top_tags(int(limit))
 
861
            return ', '.join(self.get_tag_anchor(tag.item) for tag in doc)
 
862
        return ''
832
863
 
833
864
    def _compils_title(self):
834
865
        return "Compilations with %s"%self['artist']
842
873
    def _similar_artists_title(self):
843
874
        return "Artists related to %s" % self['artist']
844
875
 
845
 
    def _similar_artists_images(self):
846
 
        doc = pylast.search_for_artist(self['artist'], LFM_API_KEY, None, None)
847
 
        temp = doc.get_next_page()[0].get_similar(10)
848
 
        data = []
849
 
        for art in temp:
850
 
             data.append('<img title ="%s" src="%s"/>' % (art, pylast.Artist.get_square_image(art)))
851
 
        return ''.join(data)
852
 
 
853
876
    def _similar_artists(self, limit=10):
854
 
        sim_artists = pylast.search_for_artist(self['artist'], LFM_API_KEY, None, None).get_next_page()[0].get_similar(int(limit))
855
 
        return ', '.join(self.get_artist_anchor(sim_artist) for sim_artist in sim_artists)
 
877
        if self.get_lfm_artist():
 
878
            sim_artists = self.get_lfm_artist().get_similar(int(limit))
 
879
            return ', '.join(self.get_artist_anchor(sim_artist.item) for sim_artist in sim_artists)
 
880
        return ''
856
881
 
857
882
    def _albums_title(self):
858
883
        return "Albums by %s" % self['artist']
908
933
 
909
934
    def __init__(self, theme, tag, base='tag://', template='tag.html', async=[]):
910
935
        self.tag = tag
 
936
        self.lfm_tag = None
 
937
 
911
938
        DefaultPage.__init__(self, theme, base, template, async+['similar-tags', 'top-artists', 'tag-top-tracks', 'tag-top-albums'])
 
939
        
 
940
    def get_lfm_tag(self):
 
941
        if not self.lfm_tag:
 
942
            self.lfm_tag = pylast.Tag(self.tag, pylast.network)
 
943
        return self.lfm_tag
912
944
 
913
945
    def _tag(self):
914
946
        return self.tag
917
949
        return "Tags similar to %s" % self['tag']
918
950
 
919
951
    def _similar_tags(self):
920
 
        tags = pylast.search_for_tag(self.tag, LFM_API_KEY, None, None).get_next_page()[0].get_similar()
921
 
        return ', '.join(self.get_tag_anchor(tag) for tag in tags[:20])
 
952
        if self.get_lfm_tag():
 
953
            tags = self.get_lfm_tag().get_similar()
 
954
            return ', '.join(self.get_tag_anchor(tag) for tag in tags[:20])
 
955
        return ''
922
956
 
923
957
    def _top_artists_title(self):
924
958
        return "Top %s artists" % self.tag
925
959
 
926
960
    def _top_artists(self):
927
 
        artists = pylast.search_for_tag(self.tag, LFM_API_KEY, None, None).get_next_page()[0].get_top_artists()
928
 
        return ', '.join(self.get_artist_anchor(artist.get_item().get_name()) for artist in artists[:20])
 
961
        if self.get_lfm_tag():
 
962
            artists = self.get_lfm_tag().get_top_artists()
 
963
            return ', '.join(self.get_artist_anchor(artist.item) for artist in artists[:20])
 
964
        return ''
929
965
 
930
966
    def _tag_top_tracks_title(self):
931
967
        return "Top %s tracks" % self.tag
932
968
 
933
969
    def _tag_top_tracks(self):
934
 
        tracks = pylast.search_for_tag(self.tag, LFM_API_KEY, None, None).get_next_page()[0].get_top_tracks()
935
 
        return '<br/>'.join(self.get_track_anchor_from_artist_title(track.get_item().get_artist(), track.get_item().get_title()) for track in tracks[:15])
 
970
        if self.get_lfm_tag():
 
971
            tracks = self.get_lfm_tag().get_top_tracks()
 
972
            return '<br/>'.join(self.get_track_anchor_from_artist_title(track.item.get_artist(), track.item.get_title()) for track in tracks[:15])
 
973
        return ''
936
974
 
937
975
    def _tag_top_albums_title(self):
938
976
        return "Top %s albums" % self.tag
939
977
 
940
978
    def _tag_top_albums(self):
941
 
        albums = pylast.search_for_tag(self.tag, LFM_API_KEY, None, None).get_next_page()[0].get_top_albums()
942
 
        return '<br/>'.join("%s %s"%(self['album-ico'],self.get_album_anchor_from_artist_title(album.get_item().get_artist(), album.get_item().get_title())) for album in albums[:15])
 
979
        if self.get_lfm_tag():
 
980
            albums = self.get_lfm_tag().get_top_albums()
 
981
            return '<br/>'.join("%s %s"%(self['album-ico'],self.get_album_anchor_from_artist_title(album.item.get_artist(), album.item.get_name())) for album in albums[:15])
 
982
        return ''
943
983
 
944
984
class PlayingPage(ArtistPage):
945
985
 
946
986
    def __init__(self, theme, track, base='playing://', template='playing.html', async=[]):
947
987
        self.track = track
 
988
        self.lfm_track = None
948
989
        ArtistPage.__init__(self, theme, get_track_tag(self.track, 'artist', 'unknown'),base, template, async+['track-tags', 'suggested-tracks', 'similar-tracks', 'lyrics'])
949
990
        event.add_callback(self.refresh_rating, 'rating_changed')
950
991
 
 
992
    def get_lfm_track(self):
 
993
        if not self.lfm_track:
 
994
            self.lfm_track = pylast.Track(get_track_tag(self.track, 'artist', 'unknown'), get_track_tag(self.track, 'title', 'unknown'), pylast.network)
 
995
        return self.lfm_track
 
996
 
951
997
    def link_clicked(self, link):
952
998
        if link[0] == 'rate':
953
999
            self.track.set_rating(int(link[1]))
964
1010
        return get_track_tag(self.track, 'album', 'unknown')
965
1011
 
966
1012
    def _track_cover(self):
967
 
        coverpath = get_track_cover(self.track)
968
 
        cover = get_image_data(coverpath, (100, 100))
969
 
        return "<a id='cover-image' href='%s'><img src='%s'></a>" % (self.get_album_href(self['album']), cover)
 
1013
        cover = get_track_cover(self.track)
 
1014
        cover_data = get_image_data(cover, (100, 100))
 
1015
        return "<a id='cover-image' href='%s'><img src='%s'></a>" % (self.get_album_href(self['album']), cover_data)
970
1016
 
971
1017
    def _playcount(self):
972
1018
        try:
973
 
            self['playcount'] = self.track['__playcount']
 
1019
            self['playcount'] = self.track.get_tag_display('__playcount')
974
1020
            if self['playcount'] == None:
975
1021
                self['playcount'] = 0
976
1022
        except:
1003
1049
    def _track_tags_title(self):
1004
1050
        return "Tags for %s" % self['title']
1005
1051
 
1006
 
    def _track_tags(self):
1007
 
        tags = pylast.search_for_track(self['artist'], self['title'], LFM_API_KEY, None, None).get_next_page()[0].get_top_tags()
1008
 
        return ', '.join(self.get_tag_anchor(tag) for tag in tags)
 
1052
    def _track_tags(self, limit=10):
 
1053
        if self.get_lfm_track():
 
1054
            tags = self.get_lfm_track().get_top_tags(limit)
 
1055
            return ', '.join(self.get_tag_anchor(tag.item) for tag in tags)
 
1056
        return ''
1009
1057
 
1010
1058
    def _suggested_tracks_title(self):
1011
1059
        return "Suggested tracks for %s" % self['title']
1018
1066
        return 'Tracks similar to %s' % self['title']
1019
1067
 
1020
1068
    def _similar_tracks(self, limit=10):
1021
 
        doc = pylast.search_for_track(self['artist'], self['title'],LFM_API_KEY, None, None).get_next_page()[0].get_similar()[:int(limit)]
1022
 
        return '<br/>'.join(self.get_track_anchor_from_artist_title(str(tr.get_artist()), str(tr.get_title()), img=True) for tr in doc)
 
1069
        if self.get_lfm_track():
 
1070
            doc = self.get_lfm_track().get_similar(int(limit))
 
1071
            return '<br/>'.join(self.get_track_anchor_from_artist_title(str(tr.get_artist()), str(tr.get_title()), img=True) for tr in doc)
 
1072
        return ''
1023
1073
 
1024
1074
    def _lyrics_title(self):
1025
1075
        return "Lyrics of %s by %s" % (self['title'],self['artist'])
1041
1091
    """
1042
1092
        The contextual panel
1043
1093
    """
1044
 
    ui_info = (BASEDIR+'context.glade', 'ContextPanelWindow')
 
1094
    ui_info = (BASEDIR+'context.ui', 'ContextPanelWindow')
1045
1095
 
1046
1096
    def __init__(self, parent):
1047
1097
        self.init__(parent, _('Context'))
1051
1101
            os.mkdir(cachedir)
1052
1102
 
1053
1103
        #TODO last.fm class
1054
 
        pylast.enable_caching(os.path.join(cachedir, 'lastfm.cache'))
 
1104
        pylast.network = pylast.get_lastfm_network(LFM_API_KEY)
 
1105
        pylast.network.enable_caching(os.path.join(cachedir, 'lastfm.cache'))
1055
1106
 
1056
1107
        self.controller = parent
1057
1108
 
1094
1145
            window.destroy()
1095
1146
 
1096
1147
        return (self._child, self.name)
 
1148
        
 
1149
def get_prefs_pane():
 
1150
    return contextprefs
1097
1151
 
1098
1152
def exaile_ready(object=None, a=None, b=None):
1099
1153
    global PANEL