Console version can now play songs
authorKristoffer Grönlund <kristoffer.gronlund@purplescout.se>
Tue, 29 Dec 2009 16:42:04 +0000 (17:42 +0100)
committerKristoffer Grönlund <kristoffer.gronlund@purplescout.se>
Sat, 2 Jan 2010 23:37:44 +0000 (00:37 +0100)
jamaendo/api.py
jamaui/console.py [new file with mode: 0644]
jamaui/player.py
scripts/player [changed mode: 0644->0755]

index 15a61bf..5d2bde9 100644 (file)
@@ -79,6 +79,15 @@ class LocalDB(object):
             for child in element:
                 if child.tag in ['name', 'id', 'image']:
                     ret[child.tag] = child.text
             for child in element:
                 if child.tag in ['name', 'id', 'image']:
                     ret[child.tag] = child.text
+                if child.tag == 'Albums':
+                    albums = []
+                    for album in child:
+                        albie = {}
+                        for albumitem in album:
+                            if albumitem.tag in ['name', 'id']:
+                                albie[albumitem.tag] = albumitem.text
+                        albums.append(albie)
+                    ret['albums'] = albums
             return ret
 
     def make_album_obj(self, element):
             return ret
 
     def make_album_obj(self, element):
@@ -86,6 +95,13 @@ class LocalDB(object):
             return element.text
         else:
             ret = {}
             return element.text
         else:
             ret = {}
+            artist = element.getparent().getparent()
+            if artist is not None:
+                for child in artist:
+                    if child.tag == 'name':
+                        ret['artist'] = child.text
+                    elif child.tag == 'id':
+                        ret['artist_id'] = child.text
             for child in element:
                 if child.tag in ['name', 'id', 'image']:
                     if child.text:
             for child in element:
                 if child.tag in ['name', 'id', 'image']:
                     if child.text:
@@ -136,7 +152,7 @@ class LocalDB(object):
     def albumid_walker(self, albumids):
         for event, element in etree.iterparse(self.fil, tag="album"):
             _id = element.xpath('./id')[0].text
     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:
+            if _id and (int(_id) in albumids):
                 yield self.make_album_obj(element)
             element.clear()
             while element.getprevious() is not None:
                 yield self.make_album_obj(element)
             element.clear()
             while element.getprevious() is not None:
@@ -151,11 +167,11 @@ class LocalDB(object):
         substr = substr.lower()
         return (album for album in self.album_walker(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_artists(self, artistids):
+        return (artist for artist in self.artistid_walker(artistids))
 
 
-    def get_album(self, albumid):
-        return (album for album in self.albumid_walker(albumid))
+    def get_albums(self, albumids):
+        return (album for album in self.albumid_walker(albumids))
 
 _GET2 = '''http://api.jamendo.com/get2/'''
 
 
 _GET2 = '''http://api.jamendo.com/get2/'''
 
diff --git a/jamaui/console.py b/jamaui/console.py
new file mode 100644 (file)
index 0000000..5c02a0b
--- /dev/null
@@ -0,0 +1,103 @@
+# console interface to jamaui/jamaendo
+
+# debugging hack - add . to path
+import os, sys
+local_module_dir = os.path.join(os.path.dirname(sys.argv[0]), '..')
+if os.path.isdir(local_module_dir):
+    sys.path.append(local_module_dir)
+
+from jamaendo.api import LocalDB, Query, Queries, refresh_dump
+from jamaui.player import Player, Playlist
+import time
+
+class Refresher(object):
+    def __init__(self):
+        self.done = False
+        self.last_percent = 0
+        print "Preparing local database..."
+    def complete(self):
+        self.done = True
+    def progress(self, percent):
+        if percent - self.last_percent >= 5:
+            print "\r%d%%" % (percent),
+            self.last_percent = percent
+
+    def run(self):
+        refresh_dump(self.complete, self.progress, force=False)
+        while not self.done:
+            time.sleep(1)
+
+
+def pprint(x):
+    import json
+    print json.dumps(x, sort_keys=True, indent=4)
+
+class Console(object):
+    def run(self):
+        Refresher().run()
+
+        query = sys.argv[1]
+
+        queries = ['today',
+                   'tracks_this_month',
+                   'artist',
+                   'album',
+                   'play_track',
+                   'play_album']
+        if query in queries:
+            getattr(self, "query_"+query)()
+        else:
+            print "Valid queries: " + ", ".join(queries)
+
+    def query_today(self):
+        result = Queries.albums_today()
+        pprint(result)
+
+    def query_tracks_this_month(self):
+        result = Queries.tracks_this_month()
+        pprint(result)
+
+    def query_artist(self):
+        q = sys.argv[2]
+        db = LocalDB()
+        db.connect()
+        for artist in db.search_artists(q):
+            pprint(artist)
+
+    def query_album(self):
+        q = sys.argv[2]
+        db = LocalDB()
+        db.connect()
+        for album in db.search_albums(q):
+            print "%s: %s - %s" % (album['id'], album['artist'], album['name'])
+
+    def query_play_track(self):
+        trackid = int(sys.argv[2])
+        uri = Query.track_mp3(trackid)
+        items = [uri]
+        playlist = Playlist(items)
+        player = Player()
+        player.play(playlist)
+
+    def query_play_album(self):
+        albumid = int(sys.argv[2])
+        db = LocalDB()
+        db.connect()
+        album = None
+        for a in db.get_albums([albumid]):
+            album = a
+            break
+        if not album:
+            return
+        print "%s - %s" % (album['artist'], album['name'])
+        items = [Query.track_mp3(int(track['id'])) for track in album['tracks']]
+
+        playlist = Playlist(items)
+        player = Player()
+        player.play(playlist)
+
+        while player.playing():
+            time.sleep(1)
+
+if __name__=="__main__":
+    main()
index 07b89b4..0b27777 100644 (file)
@@ -48,6 +48,8 @@ class GStreamer(object):
             self.player = None
             return False
 
             self.player = None
             return False
 
+        log.debug("Setting up for %s : %s", filetype, uri)
+
         # On maemo use software decoding to workaround some bugs their gst:
         # 1. Weird volume bugs in playbin when playing ogg or wma files
         # 2. When seeking the DSPs sometimes lie about the real position info
         # On maemo use software decoding to workaround some bugs their gst:
         # 1. Weird volume bugs in playbin when playing ogg or wma files
         # 2. When seeking the DSPs sometimes lie about the real position info
@@ -64,14 +66,14 @@ class GStreamer(object):
 
         self._set_uri_to_be_played(uri)
 
 
         self._set_uri_to_be_played(uri)
 
-        bus = self._player.get_bus()
+        bus = self.player.get_bus()
         bus.add_signal_watch()
         bus.connect('message', self._on_message)
         return True
 
     def get_state(self):
         if self.player:
         bus.add_signal_watch()
         bus.connect('message', self._on_message)
         return True
 
     def get_state(self):
         if self.player:
-            state = self._player.get_state()[1]
+            state = self.player.get_state()[1]
             return self.STATES.get(state, 'none')
         return 'none'
 
             return self.STATES.get(state, 'none')
         return 'none'
 
@@ -80,6 +82,7 @@ class GStreamer(object):
 
     def play(self):
         if self.player:
 
     def play(self):
         if self.player:
+            log.debug("playing")
             self.player.set_state(gst.STATE_PLAYING)
 
     def pause(self):
             self.player.set_state(gst.STATE_PLAYING)
 
     def pause(self):
@@ -191,31 +194,54 @@ class GStreamer(object):
         self.eos_callback = cb
 
 class Playlist(object):
         self.eos_callback = cb
 
 class Playlist(object):
-    def __init__(self):
-        self.items = []
+    def __init__(self, items = []):
+        self.items = items
+        self.current = -1
 
     def add(self, item):
         self.items.append(item)
 
 
     def add(self, item):
         self.items.append(item)
 
+    def next(self):
+        if self.has_next():
+            self.current = self.current + 1
+            return self.items[self.current]
+        return None
+
+    def has_next(self):
+        return self.current < (len(self.items)-1)
+
 class Player(Playlist):
     def __init__(self):
         self.gstreamer = GStreamer()
         self.gstreamer.set_eos_callback(self._on_eos)
 class Player(Playlist):
     def __init__(self):
         self.gstreamer = GStreamer()
         self.gstreamer.set_eos_callback(self._on_eos)
+        self.playlist = None
 
 
-    def play(self, item=None):
-        pass
+    def play(self, playlist = None):
+        if playlist:
+            self.playlist = playlist
+        if self.playlist is not None:
+            if self.playlist.has_next():
+                self.gstreamer.setup('mp3', self.playlist.next())
+                self.gstreamer.play()
 
     def pause(self):
 
     def pause(self):
-        pass
+        self.gstreamer.pause()
 
     def stop(self):
 
     def stop(self):
-        pass
+        self.gstreamer.stop()
+
+    def playing(self):
+        return self.gstreamer.playing()
 
     def next(self):
 
     def next(self):
-        pass
+        if self.playlist.has_next():
+            self.gstreamer.setup('mp3', self.playlist.next())
+            self.gstreamer.play()
+        else:
+            self.stop()
 
     def prev(self):
         pass
 
     def _on_eos(self):
 
     def prev(self):
         pass
 
     def _on_eos(self):
-        pass
+        self.next()
old mode 100644 (file)
new mode 100755 (executable)
index 706819f..802bd4d
@@ -7,8 +7,11 @@ if os.path.isdir(local_module_dir):
     sys.path.append(local_module_dir)
 
 def main():
     sys.path.append(local_module_dir)
 
 def main():
-    from jamaui.ui import JamaUI
-    player = JamaUI()
+    #from jamaui.ui import JamaUI
+    #player = JamaUI()
+    from jamaui.console import Console
+    player = Console()
+
     player.run()
 
 if __name__=="__main__":
     player.run()
 
 if __name__=="__main__":