X-Git-Url: http://git.maemo.org/git/?p=jamaendo;a=blobdiff_plain;f=jamaendo%2Fapi.py;h=7792c33c215cc45b1e0ed112fd3574ce604a827d;hp=f7cbc0e8dcbd219ab285cdb8f442f1a6760a48e1;hb=61536ca548691b15e7f63340a0fbfb5a3055d5be;hpb=7bec4c9364c520bd590f327896c164226974bf68 diff --git a/jamaendo/api.py b/jamaendo/api.py index f7cbc0e..7792c33 100644 --- a/jamaendo/api.py +++ b/jamaendo/api.py @@ -24,6 +24,7 @@ # Image / cover downloads.. and more? import urllib, threading, os, time, simplejson, re import logging, hashlib +import pycurl, StringIO _CACHEDIR = None _COVERDIR = None @@ -52,6 +53,19 @@ _TRACK_FIELDS = ['id', 'name', 'album_image', 'artist_id', 'artist_name', 'album _RADIO_FIELDS = ['id', 'name', 'idstr', 'image'] _TAG_FIELDS = ['id', 'name'] +def curlGET(url): + c = pycurl.Curl() + s = StringIO.StringIO() + c.setopt(pycurl.FOLLOWLOCATION, 1) + c.setopt(pycurl.URL, url) + c.setopt(pycurl.WRITEFUNCTION, s.write) + try: + c.perform() + finally: + c.close() + s.seek(0) + return s.read() + class LazyQuery(object): def set_from_json(self, json): for key, value in json.iteritems(): @@ -115,6 +129,9 @@ class Artist(LazyQuery): def _set_from(self, other): return self._set_from_impl(other, 'name', 'image', 'albums') + def get_data(self): + return {'name':self.name, 'image':self.image} + class Album(LazyQuery): def __init__(self, ID, json=None): self.ID = int(ID) @@ -137,6 +154,12 @@ class Album(LazyQuery): def _set_from(self, other): return self._set_from_impl(other, 'name', 'image', 'artist_name', 'artist_id', 'license_url', 'tracks') + def get_data(self): + return {'name':self.name, 'image':self.image, + 'artist_name':self.artist_name, + 'artist_id':self.artist_id, + 'license_url':self.license_url} + class Track(LazyQuery): def __init__(self, ID, json=None): self.ID = int(ID) @@ -157,6 +180,16 @@ class Track(LazyQuery): def ogg_url(self): return _OGGURL%(self.ID) + def get_data(self): + return {'name':self.name, + 'artist_id':self.artist_id, + 'artist_name':self.artist_name, + 'album_image':self.album_image, + 'album_name':self.album_name, + 'album_id':self.album_id, + 'numalbum':self.numalbum, + 'duration':self.duration} + def _needs_load(self): return self._needs_load_impl('name', 'artist_name', 'artist_id', 'album_name', 'album_id', 'numalbum', 'duration') @@ -225,9 +258,7 @@ class Query(object): log.info("%s", url) Query._ratelimit() try: - f = urllib.urlopen(url) - ret = simplejson.load(f) - f.close() + ret = simplejson.loads(curlGET(url)) except Exception, e: return None return ret @@ -245,13 +276,32 @@ class CoverFetcher(threading.Thread): self.cond = threading.Condition() self.work = [] + def _retrieve(self, url, fname): + BROKEN = 'http://imgjam.com/radios/default/default.100.png' + if url == BROKEN: + return None + f = open(fname, 'wb') + c = pycurl.Curl() + c.setopt(pycurl.FOLLOWLOCATION, 1) + c.setopt(pycurl.URL, str(url)) + c.setopt(pycurl.WRITEFUNCTION, f.write) + try: + c.perform() + except: + fname = None + finally: + c.close() + f.close() + log.debug("Coverfetch: %s -> %s", url, fname) + return fname + def _fetch_cover(self, albumid, size): try: coverdir = _COVERDIR if _COVERDIR else '/tmp' to = os.path.join(coverdir, '%d-%d.jpg'%(albumid, size)) if not os.path.isfile(to): url = _GET2+'image/album/redirect/?id=%d&imagesize=%d'%(albumid, size) - urllib.urlretrieve(url, to) + to = self._retrieve(url, to) return to except Exception, e: return None @@ -262,7 +312,7 @@ class CoverFetcher(threading.Thread): coverdir = _COVERDIR if _COVERDIR else '/tmp' to = os.path.join(coverdir, h+'.jpg') if not os.path.isfile(to): - urllib.urlretrieve(url, to) + to = self._retrieve(url, to) return to except Exception, e: return None @@ -276,7 +326,7 @@ class CoverFetcher(threading.Thread): def request_images(self, urls, cb): """cb([(url, image)])""" self.cond.acquire() - self.work.insert(0, ('images', urls, cb)) + self.work = [('image', url, cb) for url in urls] + self.work self.cond.notify() self.cond.release() @@ -294,22 +344,20 @@ class CoverFetcher(threading.Thread): multi = len(work) > 1 for job in work: - if job[0] == 'images': - self.process_images(job[1], job[2]) + if job[0] == 'image': + self.process_image(job[1], job[2]) else: self.process_cover(*job) - if multi: - time.sleep(1.0) def process_cover(self, albumid, size, cb): cover = self._fetch_cover(albumid, size) if cover: cb(albumid, size, cover) - def process_images(self, urls, cb): - results = [(url, image) for url, image in ((url, self._fetch_image(url)) for url in urls) if image is not None] - if results: - cb(results) + def process_image(self, url, cb): + image = self._fetch_image(url) + if image: + cb([(url, image)]) class CoverCache(object): """ @@ -644,7 +692,7 @@ def get_albums(artist_id): a = q.execute() if not a: raise JamendoAPIException(str(q)) - _update_cache(_artists, a) + _update_cache(_albums, a) return a def get_album(album_id):