[rygel] server: Add DataSource for playlist XML data



commit 9e130b56df14788e5ec9680d66dc5ba2c8e09a3e
Author: Jens Georg <jensg openismus com>
Date:   Thu Nov 1 15:33:21 2012 +0100

    server: Add DataSource for playlist XML data

 .../rygel-http-playlist-handler.vala               |   95 +++++++++++++++++++-
 1 files changed, 93 insertions(+), 2 deletions(-)
---
diff --git a/src/librygel-server/rygel-http-playlist-handler.vala b/src/librygel-server/rygel-http-playlist-handler.vala
index 915d143..a7fa0e1 100644
--- a/src/librygel-server/rygel-http-playlist-handler.vala
+++ b/src/librygel-server/rygel-http-playlist-handler.vala
@@ -21,6 +21,89 @@
  */
 using GUPnP;
 
+/**
+ * Implementation of RygelDataSource to serve generated playlists to a client.
+ */
+internal class Rygel.PlaylistDatasource : Rygel.DataSource, Object {
+    private MediaContainer container;
+    private uint8[] data;
+    private HTTPServer server;
+    private ClientHacks hacks;
+
+    public PlaylistDatasource (MediaContainer container,
+                               HTTPServer     server,
+                               ClientHacks?   hacks) {
+        this.container = container;
+        this.server = server;
+        this.hacks = hacks;
+        this.generate_data.begin ();
+    }
+
+    public signal void data_ready ();
+
+    public void start (HTTPSeek? offsets) throws Error {
+        if (offsets != null) {
+            throw new DataSourceError.SEEK_FAILED
+                                        (_("Seeking not supported"));
+        }
+
+        if (this.data == null) {
+            this.data_ready.connect ( () => {
+                try {
+                    this.start (offsets);
+                } catch (Error error) { }
+            });
+
+            return;
+        }
+
+        Idle.add ( () => {
+            this.data_available (this.data);
+            this.done ();
+
+            return false;
+        });
+    }
+
+    public void freeze () { }
+
+    public void thaw () { }
+
+    public void stop () { }
+
+    public async void generate_data () {
+        try {
+            var sort_criteria = this.container.sort_criteria;
+            var count = this.container.child_count;
+
+            var children = yield this.container.get_children (0,
+                                                              count,
+                                                              sort_criteria,
+                                                              null);
+
+            if (children != null) {
+                var serializer = new Serializer (SerializerType.DIDL_S);
+                children.serialize (serializer, this.server, this.hacks);
+
+                var xml = serializer.get_string ();
+
+                this.data = xml.data;
+                this.data_ready ();
+            } else {
+                this.error (new DataSourceError.GENERAL
+                                        (_("Failed to generate playlist")));
+            }
+        } catch (Error error) {
+            warning ("Could not generate playlist: %s", error.message);
+            this.error (error);
+        }
+    }
+}
+
+/**
+ * RygelHTTPPlaylistHandler implements a special handler for generating XML
+ * playlists (DIDL_S format as defined by DLNA) on-the-fly.
+ */
 internal class Rygel.HTTPPlaylistHandler : Rygel.HTTPGetHandler {
     public HTTPPlaylistHandler (Cancellable? cancellable) {
         this.cancellable = cancellable;
@@ -28,12 +111,20 @@ internal class Rygel.HTTPPlaylistHandler : Rygel.HTTPGetHandler {
 
     public override HTTPResponse render_body (HTTPGet request)
                                               throws HTTPRequestError {
-        throw new HTTPRequestError.NOT_FOUND ("Not implemented yet");
+        try {
+            var source = new PlaylistDatasource
+                                        (request.object as MediaContainer,
+                                         request.http_server,
+                                         request.hack);
+
+            return new HTTPResponse (request, this, source);
+        } catch (Error error) {
+            throw new HTTPRequestError.NOT_FOUND (error.message);
+        }
     }
 
     protected override DIDLLiteResource add_resource (DIDLLiteItem didl_item,
                                                       HTTPGet      request) {
-        // TODO: Implement
         return null as DIDLLiteResource;
     }
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]