Querying now works, complete enough to write the UI
authorKristoffer Grönlund <kristoffer.gronlund@purplescout.se>
Tue, 29 Dec 2009 12:47:23 +0000 (13:47 +0100)
committerKristoffer Grönlund <kristoffer.gronlund@purplescout.se>
Tue, 29 Dec 2009 12:47:23 +0000 (13:47 +0100)
jamaendo/api.py
jamaui/jam_artists_simple.png [new file with mode: 0644]
jamaui/logo_2600_710.png [new file with mode: 0644]
scripts/artists [deleted file]
scripts/query [new file with mode: 0755]

index b3683d8..9913fcc 100644 (file)
@@ -71,19 +71,73 @@ class DB(object):
     def close(self):
         self.fil.close()
 
-    def make_obj(self, element):
+    def make_artist_obj(self, element):
         if element.text is not None and element.text != "":
             return element.text
         else:
-            ret = Obj()
+            ret = {}
             for child in element:
-                if child.tag in ['name', 'id']:
-                    setattr(ret, child.tag, child.text)
+                if child.tag in ['name', 'id', 'image']:
+                    ret[child.tag] = child.text
             return ret
 
-    def artist_walker(self):
+    def make_album_obj(self, element):
+        if element.text is not None and element.text != "":
+            return element.text
+        else:
+            ret = {}
+            for child in element:
+                if child.tag in ['name', 'id', 'image']:
+                    if child.text:
+                        ret[child.tag] = child.text
+                    else:
+                        ret[child.tag] = ""
+                if child.tag == 'Tracks':
+                    tracks = []
+                    for track in child:
+                        trackd = {}
+                        for trackinfo in track:
+                            if trackinfo.tag in ['name', 'id', 'numalbum']:
+                                trackd[trackinfo.tag] = trackinfo.text
+                        tracks.append(trackd)
+                    ret['tracks'] = tracks
+            return ret
+
+    def artist_walker(self, name_match):
+        for event, element in etree.iterparse(self.fil, tag="artist"):
+            name = element.xpath('./name')[0].text.lower()
+            if name and name.find(name_match) > -1:
+                yield self.make_artist_obj(element)
+            element.clear()
+            while element.getprevious() is not None:
+                del element.getparent()[0]
+        raise StopIteration
+
+    def album_walker(self, name_match):
+        for event, element in etree.iterparse(self.fil, tag="album"):
+            name = element.xpath('./name')[0].text
+            if name and name.lower().find(name_match) > -1:
+                yield self.make_album_obj(element)
+            element.clear()
+            while element.getprevious() is not None:
+                del element.getparent()[0]
+        raise StopIteration
+
+    def artistid_walker(self, artistids):
         for event, element in etree.iterparse(self.fil, tag="artist"):
-            yield self.make_obj(element)
+            _id = element.xpath('./id')[0].text
+            if _id and int(_id) in artistids:
+                yield self.make_artist_obj(element)
+            element.clear()
+            while element.getprevious() is not None:
+                del element.getparent()[0]
+        raise StopIteration
+
+    def albumid_walker(self, albumids):
+        for event, element in etree.iterparse(self.fil, tag="album"):
+            _id = element.xpath('./id')[0].text
+            if _id and int(_id) in albumids:
+                yield self.make_album_obj(element)
             element.clear()
             while element.getprevious() is not None:
                 del element.getparent()[0]
@@ -91,4 +145,60 @@ class DB(object):
 
     def search_artists(self, substr):
         substr = substr.lower()
-        return [artist for artist in self.artist_walker() if artist.name.lower().find(substr) > -1]
+        return (artist for artist in self.artist_walker(substr))
+
+    def search_albums(self, substr):
+        substr = substr.lower()
+        return (album for album in self.album_walker(substr))
+
+    def get_album(self, artistid):
+        return (artist for artist in self.artistid_walker(artistid))
+
+    def get_album(self, albumid):
+        return (album for album in self.albumid_walker(albumid))
+
+_GET2 = '''http://api.jamendo.com/get2/'''
+
+class Query(object):
+    last_query = time.time()
+
+    def __init__(self, order, select=['id', 'name', 'image', 'artist_name'], request='album', track=None, n=8):
+        if request == 'track':
+            self.url = "%s%s/%s/json/%s?n=%s&order=%s" % (_GET2, '+'.join(select), request, '+'.join(track), n, order)
+        else:
+            self.url = "%s%s/%s/json/?n=%s&order=%s" % (_GET2, '+'.join(select), request, n, order)
+
+    def emit(self):
+        """ratelimited query"""
+        now = time.time()
+        if now - self.last_query < 1.0:
+            time.sleep(1.0 - (now - self.last_query))
+        self.last_query = now
+        f = urllib.urlopen(self.url)
+        ret = json.load(f)
+        f.close()
+        return ret
+
+class Queries(object):
+    albums_this_week = Query(order='ratingweek_desc')
+    albums_all_time = Query(order='ratingtotal_desc')
+    albums_this_month = Query(order='ratingmonth_desc')
+    albums_today = Query(order='ratingday_desc')
+    playlists_all_time = Query(select=['id','name', 'user_idstr'], request='playlist', order='ratingtotal_desc')
+    tracks_this_month = Query(select=['id', 'name', 'url', 'stream', 'album_name', 'album_url', 'album_id', 'artist_id', 'artist_name'],
+                              request='track',
+                              track=['track_album', 'album_artist'],
+                              order='ratingmonth_desc')
+
+def get_cover(albumid, size=200):
+    to = '~/.cache/jamaendo/cover-%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)
+    return to
+
+def get_ogg_url(trackid):
+   return _GET2+ 'stream/track/redirect/?id=%d&streamencoding=ogg2'%(trackid)
+
+def get_mp3_url(trackid):
+   return _GET2+ 'stream/track/redirect/?id=%d&streamencoding=mp31'%(trackid)
diff --git a/jamaui/jam_artists_simple.png b/jamaui/jam_artists_simple.png
new file mode 100644 (file)
index 0000000..f31fe50
Binary files /dev/null and b/jamaui/jam_artists_simple.png differ
diff --git a/jamaui/logo_2600_710.png b/jamaui/logo_2600_710.png
new file mode 100644 (file)
index 0000000..cce480b
Binary files /dev/null and b/jamaui/logo_2600_710.png differ
diff --git a/scripts/artists b/scripts/artists
deleted file mode 100755 (executable)
index 292fdd0..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env python
-from jamaendo.api import DB
-import sys
-
-def main():
-    db = DB()
-    print "Connecting to DB..."
-    db.connect()
-    print "Connected."
-    q = sys.argv[1]
-    print "Querying db for %s..." % (q)
-    artists = db.search_artists(q)
-    print artists
-
-if __name__=="__main__":
-    main()
diff --git a/scripts/query b/scripts/query
new file mode 100755 (executable)
index 0000000..707b48e
--- /dev/null
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+from jamaendo.api import DB, Queries
+import sys
+
+def pprint(x):
+    import json
+    print json.dumps(x, sort_keys=True, indent=4)
+
+def main():
+
+    query = sys.argv[1]
+
+    if query == 'today':
+        result = Queries.albums_today.emit()
+        pprint(result)
+    elif query == 'artist':
+        q = sys.argv[2]
+        db = DB()
+        db.connect()
+        for artist in db.search_artists(q):
+            pprint(artist)
+    elif query == 'album':
+        q = sys.argv[2]
+        db = DB()
+        db.connect()
+        for album in db.search_albums(q):
+            pprint(album)
+
+if __name__=="__main__":
+    main()