New year, big checkin
[jamaendo] / jamaendo / api.py
index 8bd7d91..a376b7d 100644 (file)
@@ -35,7 +35,7 @@ def set_cache_dir(cachedir):
 # makes a query internally to get the full story
 
 _ARTIST_FIELDS = ['id', 'name', 'image']
 # makes a query internally to get the full story
 
 _ARTIST_FIELDS = ['id', 'name', 'image']
-_ALBUM_FIELDS = ['id', 'name', 'image', 'artist_name', 'artist_id']
+_ALBUM_FIELDS = ['id', 'name', 'image', 'artist_name', 'artist_id', 'license_url']
 _TRACK_FIELDS = ['id', 'name', 'image', 'artist_name', 'album_name', 'album_id', 'numalbum', 'duration']
 _RADIO_FIELDS = ['id', 'name', 'idstr', 'image']
 
 _TRACK_FIELDS = ['id', 'name', 'image', 'artist_name', 'album_name', 'album_id', 'numalbum', 'duration']
 _RADIO_FIELDS = ['id', 'name', 'idstr', 'image']
 
@@ -97,7 +97,7 @@ class Artist(LazyQuery):
             self.set_from_json(json)
 
     def _needs_load(self):
             self.set_from_json(json)
 
     def _needs_load(self):
-        return self._needs_load_impl('name', 'image', 'albums')
+        return self._needs_load_impl('name', 'albums')
 
     def _set_from(self, other):
         return self._set_from_impl(other, 'name', 'image', 'albums')
 
     def _set_from(self, other):
         return self._set_from_impl(other, 'name', 'image', 'albums')
@@ -109,15 +109,16 @@ class Album(LazyQuery):
         self.image = None
         self.artist_name = None
         self.artist_id = None
         self.image = None
         self.artist_name = None
         self.artist_id = None
+        self.license_url = None
         self.tracks = None # None means not downloaded
         if json:
             self.set_from_json(json)
 
     def _needs_load(self):
         self.tracks = None # None means not downloaded
         if json:
             self.set_from_json(json)
 
     def _needs_load(self):
-        return self._needs_load_impl('name', 'image', 'artist_name', 'artist_id', 'tracks')
+        return self._needs_load_impl('name', 'image', 'artist_name', 'artist_id', 'license_url', 'tracks')
 
     def _set_from(self, other):
 
     def _set_from(self, other):
-        return self._set_from_impl(other, 'name', 'image', 'artist_name', 'artist_id', 'tracks')
+        return self._set_from_impl(other, 'name', 'image', 'artist_name', 'artist_id', 'license_url', 'tracks')
 
 class Track(LazyQuery):
     def __init__(self, ID, json=None):
 
 class Track(LazyQuery):
     def __init__(self, ID, json=None):
@@ -139,7 +140,7 @@ class Track(LazyQuery):
        return _OGGURL%(self.ID)
 
     def _needs_load(self):
        return _OGGURL%(self.ID)
 
     def _needs_load(self):
-        return self._needs_load_impl('name', 'image', 'artist_name', 'album_name', 'album_id', 'numalbum', 'duration')
+        return self._needs_load_impl('name', 'artist_name', 'album_name', 'album_id', 'numalbum', 'duration')
 
     def _set_from(self, other):
         return self._set_from_impl(other, 'name', 'image', 'artist_name', 'album_name', 'album_id', 'numalbum', 'duration')
 
     def _set_from(self, other):
         return self._set_from_impl(other, 'name', 'image', 'artist_name', 'album_name', 'album_id', 'numalbum', 'duration')
@@ -175,8 +176,8 @@ _CACHED_RADIOS = 10
 # TODO: cache queries?
 
 class Query(object):
 # TODO: cache queries?
 
 class Query(object):
-    last_query = time.time()
-    rate_limit = 1.0 # max queries per second
+    rate_limit = 1.1 # seconds between queries
+    last_query = time.time() - 1.5
 
     @classmethod
     def _ratelimit(cls):
 
     @classmethod
     def _ratelimit(cls):
@@ -189,7 +190,8 @@ class Query(object):
         pass
 
     def _geturl(self, url):
         pass
 
     def _geturl(self, url):
-        print "geturl: %s" % (url)
+        print "*** %s" % (url)
+        Query._ratelimit()
         f = urllib.urlopen(url)
         ret = simplejson.load(f)
         f.close()
         f = urllib.urlopen(url)
         ret = simplejson.load(f)
         f.close()
@@ -220,7 +222,6 @@ class CoverCache(object):
                     self._covers[(int(m.group(1)), int(m.group(2)))] = fl
 
     def fetch_cover(self, albumid, size):
                     self._covers[(int(m.group(1)), int(m.group(2)))] = fl
 
     def fetch_cover(self, albumid, size):
-        Query._ratelimit() # ratelimit cover fetching too?
         coverdir = _COVERDIR if _COVERDIR else '/tmp'
         to = os.path.join(coverdir, '%d-%d.jpg'%(albumid, size))
         if not os.path.isfile(to):
         coverdir = _COVERDIR if _COVERDIR else '/tmp'
         to = os.path.join(coverdir, '%d-%d.jpg'%(albumid, size))
         if not os.path.isfile(to):
@@ -287,12 +288,12 @@ class GetQuery(Query):
             },
         'tracks' : {
             'url' : _GET2+'+'.join(_TRACK_FIELDS)+'/track/json/track_album+album_artist?',
             },
         'tracks' : {
             'url' : _GET2+'+'.join(_TRACK_FIELDS)+'/track/json/track_album+album_artist?',
-            'params' : 'album_id=%d',
+            'params' : 'order=numalbum_asc&album_id=%d',
             'constructor' : [Track]
             },
         'radio' : {
             'url' : _GET2+'+'.join(_TRACK_FIELDS)+'/track/json/radio_track_inradioplaylist+track_album+album_artist/?',
             'constructor' : [Track]
             },
         'radio' : {
             'url' : _GET2+'+'.join(_TRACK_FIELDS)+'/track/json/radio_track_inradioplaylist+track_album+album_artist/?',
-            'params' : 'order=numradio_asc&radio_id=%d',
+            'params' : 'order=random_asc&radio_id=%d',
             'constructor' : [Track]
             },
         'favorite_albums' : {
             'constructor' : [Track]
             },
         'favorite_albums' : {
@@ -361,7 +362,7 @@ class SearchQuery(GetQuery):
 
 class JamendoAPIException(Exception):
     def __init__(self, url):
 
 class JamendoAPIException(Exception):
     def __init__(self, url):
-        Exception.__init__(url)
+        Exception.__init__(self, url)
 
 def _update_cache(cache, new_items):
     if not isinstance(new_items, list):
 
 def _update_cache(cache, new_items):
     if not isinstance(new_items, list):
@@ -382,6 +383,8 @@ def get_artist(artist_id):
         if not a:
             raise JamendoAPIException(str(q))
         _update_cache(_artists, a)
         if not a:
             raise JamendoAPIException(str(q))
         _update_cache(_artists, a)
+        if isinstance(a, list):
+            a = a[0]
     return a
 
 def get_albums(artist_id):
     return a
 
 def get_albums(artist_id):
@@ -402,6 +405,8 @@ def get_album(album_id):
         if not a:
             raise JamendoAPIException(str(q))
         _update_cache(_albums, a)
         if not a:
             raise JamendoAPIException(str(q))
         _update_cache(_albums, a)
+        if isinstance(a, list):
+            a = a[0]
     return a
 
 def get_tracks(album_id):
     return a
 
 def get_tracks(album_id):
@@ -422,6 +427,8 @@ def get_track(track_id):
         if not a:
             raise JamendoAPIException(str(q))
         _update_cache(_tracks, a)
         if not a:
             raise JamendoAPIException(str(q))
         _update_cache(_tracks, a)
+        if isinstance(a, list):
+            a = a[0]
     return a
 
 def get_radio_tracks(radio_id):
     return a
 
 def get_radio_tracks(radio_id):
@@ -494,9 +501,8 @@ def get_radio(radio_id):
     if not js:
         raise JamendoAPIException(str(q))
     if isinstance(js, list):
     if not js:
         raise JamendoAPIException(str(q))
     if isinstance(js, list):
-        return [Radio(x['id'], json=x) for x in js]
-    else:
-        return Radio(radio_id, json=js)
+        ks = js[0]
+    return Radio(radio_id, json=js)
 
 def starred_radios():
     """Returns: [Radio]"""
 
 def starred_radios():
     """Returns: [Radio]"""
@@ -526,6 +532,7 @@ Artist.load = _artist_loader
 def _album_loader(self):
     if self._needs_load():
         album = get_album(self.ID)
 def _album_loader(self):
     if self._needs_load():
         album = get_album(self.ID)
+        album.tracks = get_tracks(self.ID)
         self._set_from(album)
 Album.load = _album_loader
 
         self._set_from(album)
 Album.load = _album_loader