54811f73cb42161a7c52ac1ace90597486d3a8f2
[mussorgsky] / src / album_art.py
1 #!/usr/bin/env python2.5
2 import urllib2, urllib
3 import libxml2
4 import os
5 from album_art_spec import getCoverArtFileName, getCoverArtThumbFileName, get_thumb_filename_for_path
6 import dbus, time
7
8 try:
9     import PIL
10     import Image
11     pil_available = True
12 except ImportException:
13     pil_available = False
14     
15
16 LASTFM_APIKEY = "1e1d53528c86406757a6887addef0ace"
17 BASE_LASTFM = "http://ws.audioscrobbler.com/2.0/?method=album.getinfo"
18
19 # LastFM:
20 # http://www.lastfm.es/api/show?service=290
21 #
22 class MussorgskyAlbumArt:
23
24     def __init__ (self):
25         bus = dbus.SessionBus ()
26         handle = time.time()
27         try:
28             self.thumbnailer = bus.get_object ('org.freedesktop.thumbnailer',
29                                                '/org/freedesktop/thumbnailer/Generic')
30         except dbus.exceptions.DBusException:
31             if (pil_available):
32                 self.thumbnailer = LocalThumbnailer ()
33             else:
34                 print "No thumbnailer available"
35                 self.thumbnailer = None
36
37     def get_album_art (self, artist, album):
38         """
39         Return a tuple (album_art, thumbnail_album_art)
40         """
41         filename = getCoverArtFileName (album)
42         thumbnail = getCoverArtThumbFileName (album)
43
44         if (os.path.exists (filename)):
45             print "Album art already there " + filename
46         else:
47             online_resource = self.__last_fm (artist, album)
48             if (online_resource):
49                 self.__save_url_into_file (online_resource, filename)
50             else:
51                 return (None, None)
52
53         if (os.path.exists (thumbnail)):
54             print "Thumbnail exists"
55         else:
56             print "Requesting thumbnail"
57             self.__request_thumbnail (filename)
58
59         return (filename, thumbnail)
60
61     def __last_fm (self, artist, album):
62         if (not artist and not album):
63             return
64         
65         URL = BASE_LASTFM + "&api_key=" + LASTFM_APIKEY
66         if (artist):
67             URL += "&artist=" + urllib.quote(artist)
68         if (album):
69             URL += "&album=" + urllib.quote(album)
70             
71         print "Retrieving: %s" % (URL)
72         result = self.__get_url (URL)
73         if (not result):
74             return None
75         doc = libxml2.parseDoc (result)
76         image_nodes = doc.xpathEval ("//image[@size='large']")
77         if len (image_nodes) < 1:
78             return None
79         else:
80             return image_nodes[0].content
81
82     def __save_url_into_file (self, url, filename):
83         image = self.__get_url (url)
84         output_image = open (filename, 'w')
85         output_image.write (image)
86         output_image.close ()
87         print "Saved %s -> %s " % (url, filename)
88         
89     def __get_url (self, url):
90         request = urllib2.Request (url)
91         request.add_header ('User-Agent', 'Mussorgsky/0.1 Test')
92         opener = urllib2.build_opener ()
93         try:
94             return opener.open (request).read ()
95         except:
96             return None
97
98     def __request_thumbnail (self, filename):
99         if (not self.thumbnailer):
100             print "No thumbnailer available"
101             return
102         uri = "file://" + filename
103         handle = time.time ()
104         print "Call to thumbnailer"
105         self.thumbnailer.Queue ([uri], ["image/jpeg"], dbus.UInt32 (handle))
106
107
108 class LocalThumbnailer:
109     def __init__ (self):
110         self.THUMBNAIL_SIZE = (124,124)
111
112     def Queue (self, uris, mimes, handle):
113         print "Queue"
114         for i in range (0, len(uris)):
115             uri = uris[i]
116             fullCoverFileName = uri[7:]
117             print fullCoverFileName
118             if (os.path.exists (fullCoverFileName)):
119                 thumbFile = get_thumb_filename_for_path (fullCoverFileName)
120                 
121                 image = Image.open (fullCoverFileName)
122                 image = image.resize (self.THUMBNAIL_SIZE, Image.ANTIALIAS )
123                 image.save( thumbFile, "JPEG" )
124                 print "Thumbnail: " + thumbFile
125
126
127 if __name__ == "__main__":
128     import sys
129     if ( len (sys.argv) > 2):
130         artist = sys.argv[1]
131         album = sys.argv[2]
132     else:
133         print "ARTIST ALBUM"
134         sys.exit (-1)
135     maa = MussorgskyAlbumArt ()
136     print "Artist %s - Album %s" % (artist, unicode(album))
137     print maa.get_album_art (artist, unicode(album))
138     #assert (None, None) == maa.get_album_art ("muse", "absolution")