[rygel/wip/didl-s: 10/14] server: Support all objects in HTTPRequest



commit 9701fe007c1e2b471d5d4ccb73b3997048f020a8
Author: Jens Georg <jensg openismus com>
Date:   Thu Nov 1 15:32:41 2012 +0100

    server: Support all objects in HTTPRequest

 src/librygel-server/rygel-http-byte-seek.vala      |    4 +-
 src/librygel-server/rygel-http-get-handler.vala    |    4 +-
 src/librygel-server/rygel-http-get.vala            |   35 +++++++++++--------
 .../rygel-http-identity-handler.vala               |    6 ++--
 src/librygel-server/rygel-http-post.vala           |   22 +++++++------
 src/librygel-server/rygel-http-request.vala        |   11 ++++--
 src/librygel-server/rygel-http-time-seek.vala      |    8 ++--
 .../rygel-http-transcode-handler.vala              |    4 +-
 tests/rygel-http-byte-seek-test.vala               |   18 +++++++---
 tests/rygel-http-get-test.vala                     |    2 +-
 tests/rygel-http-post-test.vala                    |    7 ++--
 tests/rygel-http-time-seek-test.vala               |   17 ++++++---
 12 files changed, 79 insertions(+), 59 deletions(-)
---
diff --git a/src/librygel-server/rygel-http-byte-seek.vala b/src/librygel-server/rygel-http-byte-seek.vala
index 604e2af..9be0f36 100644
--- a/src/librygel-server/rygel-http-byte-seek.vala
+++ b/src/librygel-server/rygel-http-byte-seek.vala
@@ -34,7 +34,7 @@ internal class Rygel.HTTPByteSeek : Rygel.HTTPSeek {
         } else if (request.subtitle != null) {
             total_length = request.subtitle.size;
         } else {
-            total_length = request.item.size;
+            total_length = (request.object as MediaItem).size;
         }
         var stop = total_length - 1;
 
@@ -61,7 +61,7 @@ internal class Rygel.HTTPByteSeek : Rygel.HTTPSeek {
     }
 
     public static bool needed (HTTPGet request) {
-        return (request.item.size > 0 &&
+        return !(request.object is MediaContainer) && ((request.object as MediaItem).size > 0 &&
                 request.handler is HTTPIdentityHandler) ||
                (request.thumbnail != null &&
                 request.thumbnail.size > 0) ||
diff --git a/src/librygel-server/rygel-http-get-handler.vala b/src/librygel-server/rygel-http-get-handler.vala
index 5563d2e..cec9a09 100644
--- a/src/librygel-server/rygel-http-get-handler.vala
+++ b/src/librygel-server/rygel-http-get-handler.vala
@@ -64,9 +64,9 @@ internal abstract class Rygel.HTTPGetHandler: GLib.Object {
 
         // Handle Samsung DLNA TV proprietary subtitle headers
         if (request.msg.request_headers.get_one ("getCaptionInfo.sec") != null
-            && (request.item as VideoItem).subtitles.size > 0) {
+            && (request.object as VideoItem).subtitles.size > 0) {
                 var caption_uri = request.http_server.create_uri_for_item
-                                        (request.item,
+                                        (request.object as MediaItem,
                                          -1,
                                          0, // FIXME: offer first subtitle only?
                                          null);
diff --git a/src/librygel-server/rygel-http-get.vala b/src/librygel-server/rygel-http-get.vala
index 4a8feb1..e977cea 100644
--- a/src/librygel-server/rygel-http-get.vala
+++ b/src/librygel-server/rygel-http-get.vala
@@ -82,23 +82,28 @@ internal class Rygel.HTTPGet : HTTPRequest {
     protected override async void find_item () throws Error {
         yield base.find_item ();
 
-        if (unlikely (this.item.place_holder)) {
+        // No need to do anything here, will be done in PlaylistHandler
+        if (this.object is MediaContainer) {
+            return;
+        }
+
+        if (unlikely ((this.object as MediaItem).place_holder)) {
             throw new HTTPRequestError.NOT_FOUND ("Item '%s' is empty",
-                                                  this.item.id);
+                                                  this.object.id);
         }
 
         if (this.hack != null) {
-            this.hack.apply (item);
+            this.hack.apply (this.object as MediaItem);
         }
 
         if (this.uri.thumbnail_index >= 0) {
-            if (this.item is MusicItem) {
-                var music = this.item as MusicItem;
+            if (this.object is MusicItem) {
+                var music = this.object as MusicItem;
                 this.thumbnail = music.album_art;
 
                 return;
-            } else if (this.item is VisualItem) {
-                var visual = this.item as VisualItem;
+            } else if (this.object is VisualItem) {
+                var visual = this.object as VisualItem;
                 if (this.uri.thumbnail_index < visual.thumbnails.size) {
                     this.thumbnail = visual.thumbnails.get
                                             (this.uri.thumbnail_index);
@@ -109,11 +114,11 @@ internal class Rygel.HTTPGet : HTTPRequest {
 
             throw new HTTPRequestError.NOT_FOUND
                                         ("No Thumbnail available for item '%s",
-                                         this.item.id);
+                                         this.object.id);
         }
 
-        if (this.uri.subtitle_index >= 0 && this.item is VideoItem) {
-            var video = this.item as VideoItem;
+        if (this.uri.subtitle_index >= 0 && this.object is VideoItem) {
+            var video = this.object as VideoItem;
 
             if (this.uri.subtitle_index < video.subtitles.size) {
                 this.subtitle = video.subtitles.get (this.uri.subtitle_index);
@@ -123,7 +128,7 @@ internal class Rygel.HTTPGet : HTTPRequest {
 
             throw new HTTPRequestError.NOT_FOUND
                                         ("No subtitles available for item '%s",
-                                         this.item.id);
+                                         this.object.id);
         }
     }
 
@@ -200,15 +205,15 @@ internal class Rygel.HTTPGet : HTTPRequest {
         switch (mode) {
         case "Streaming":
             correct = this.handler is HTTPTranscodeHandler ||
-                      (this.item.streamable () &&
+                      ((this.object as MediaItem).streamable () &&
                        this.subtitle == null &&
                        this.thumbnail == null);
 
             break;
         case "Interactive":
             correct = this.handler is HTTPIdentityHandler &&
-                      ((!this.item.is_live_stream () &&
-                       !this.item.streamable ()) ||
+                      ((!(this.object as MediaItem).is_live_stream () &&
+                       !(this.object as MediaItem).streamable ()) ||
                        (this.subtitle != null ||
                         this.thumbnail != null));
 
@@ -219,7 +224,7 @@ internal class Rygel.HTTPGet : HTTPRequest {
             throw new HTTPRequestError.UNACCEPTABLE
                                         ("%s mode not supported for '%s'",
                                          mode,
-                                         this.item.id);
+                                         this.object.id);
         }
     }
 }
diff --git a/src/librygel-server/rygel-http-identity-handler.vala b/src/librygel-server/rygel-http-identity-handler.vala
index e9435f4..bdf90a8 100644
--- a/src/librygel-server/rygel-http-identity-handler.vala
+++ b/src/librygel-server/rygel-http-identity-handler.vala
@@ -42,7 +42,7 @@ internal class Rygel.HTTPIdentityHandler : Rygel.HTTPGetHandler {
                                                  request.thumbnail.mime_type);
         } else {
             request.msg.response_headers.append ("Content-Type",
-                                                 request.item.mime_type);
+                                                 (request.object as MediaItem).mime_type);
         }
 
         if (request.seek != null) {
@@ -83,7 +83,7 @@ internal class Rygel.HTTPIdentityHandler : Rygel.HTTPGetHandler {
         if (request.thumbnail != null) {
             return request.thumbnail.add_resource (didl_item, protocol);
         } else {
-            return request.item.add_resource (didl_item, null, protocol);
+            return (request.object as MediaItem).add_resource (didl_item, null, protocol);
         }
     }
 
@@ -96,7 +96,7 @@ internal class Rygel.HTTPIdentityHandler : Rygel.HTTPGetHandler {
         } else if (request.thumbnail != null) {
             src = engine.create_data_source (request.thumbnail.uri);
         } else {
-            src = request.item.create_stream_source
+            src = (request.object as MediaItem).create_stream_source
                                         (request.http_server.context.host_ip);
         }
 
diff --git a/src/librygel-server/rygel-http-post.vala b/src/librygel-server/rygel-http-post.vala
index 1ce213e..1fe63e3 100644
--- a/src/librygel-server/rygel-http-post.vala
+++ b/src/librygel-server/rygel-http-post.vala
@@ -46,29 +46,31 @@ internal class Rygel.HTTPPost : HTTPRequest {
 
     protected override async void handle () throws Error {
         var queue = ItemRemovalQueue.get_default ();
-        queue.dequeue (this.item);
+        queue.dequeue (this.object as MediaItem);
 
         try {
             yield this.handle_real ();
         } catch (Error error) {
-            yield queue.remove_now (this.item, this.cancellable);
+            yield queue.remove_now (this.object as MediaItem,
+                                    this.cancellable);
 
             throw error;
         }
     }
 
     private async void handle_real () throws Error {
-        if (!this.item.place_holder) {
+        if (!(this.object as MediaItem).place_holder) {
             var msg = _("Pushing data to non-empty item '%s' not allowed");
 
-            throw new ContentDirectoryError.INVALID_ARGS (msg, this.item.id);
+            throw new ContentDirectoryError.INVALID_ARGS (msg, this.object.id);
         }
 
-        this.file = yield this.item.get_writable (this.cancellable);
+        this.file = yield (this.object as MediaItem).get_writable
+                                        (this.cancellable);
         if (this.file == null) {
             throw new HTTPRequestError.BAD_REQUEST
                                         (_("No writable URI for %s available"),
-                                         this.item.id);
+                                         this.object.id);
         }
 
         this.dotfile = this.file.get_parent ().get_child
@@ -173,8 +175,8 @@ internal class Rygel.HTTPPost : HTTPRequest {
 
         debug ("Waiting for update signal from container '%s' after pushing" +
                " content to its child item '%s'..",
-               this.item.parent.id,
-               this.item.id);
+               this.object.parent.id,
+               this.object.id);
 
         try {
             this.dotfile.move (this.file,
@@ -193,7 +195,7 @@ internal class Rygel.HTTPPost : HTTPRequest {
             return;
         }
 
-        yield wait_for_item (this.item.parent, this.item.id, 5);
+        yield wait_for_item (this.object.parent, this.object.id, 5);
 
         this.server.unpause_message (this.msg);
         this.end (KnownStatusCode.OK);
@@ -217,7 +219,7 @@ internal class Rygel.HTTPPost : HTTPRequest {
 
     private async void remove_item () {
         var queue = ItemRemovalQueue.get_default ();
-        yield queue.remove_now (this.item, null);
+        yield queue.remove_now (this.object as MediaItem, null);
     }
 
     private void disconnect_message_signals () {
diff --git a/src/librygel-server/rygel-http-request.vala b/src/librygel-server/rygel-http-request.vala
index 92d3c10..d1830fa 100644
--- a/src/librygel-server/rygel-http-request.vala
+++ b/src/librygel-server/rygel-http-request.vala
@@ -42,9 +42,9 @@ internal abstract class Rygel.HTTPRequest : GLib.Object, Rygel.StateMachine {
     public Cancellable cancellable { get; set; }
 
     protected HTTPItemURI uri;
-    public MediaItem item;
+    public MediaObject object;
 
-    protected ClientHacks hack;
+    internal ClientHacks hack;
 
     public HTTPRequest (HTTPServer   http_server,
                         Soup.Server  server,
@@ -84,13 +84,16 @@ internal abstract class Rygel.HTTPRequest : GLib.Object, Rygel.StateMachine {
         var media_object = yield this.root_container.find_object
                                         (this.uri.item_id, null);
 
-        if (media_object == null || !(media_object is MediaItem)) {
+        if (media_object == null ||
+            !((media_object is MediaContainer &&
+               this.uri.playlist_format != null) ||
+              (media_object is MediaItem && this.uri.playlist_format == null))) {
             throw new HTTPRequestError.NOT_FOUND
                                         (_("Requested item '%s' not found"),
                                          this.uri.item_id);
         }
 
-        this.item = (MediaItem) media_object;
+        this.object = media_object;
     }
 
     protected void handle_error (Error error) {
diff --git a/src/librygel-server/rygel-http-time-seek.vala b/src/librygel-server/rygel-http-time-seek.vala
index 1cb42e5..7fed78e 100644
--- a/src/librygel-server/rygel-http-time-seek.vala
+++ b/src/librygel-server/rygel-http-time-seek.vala
@@ -28,7 +28,7 @@ internal class Rygel.HTTPTimeSeek : Rygel.HTTPSeek {
         string range;
         string[] range_tokens;
         int64 start = 0;
-        int64 duration = (request.item as AudioItem).duration * TimeSpan.SECOND;
+        int64 duration = (request.object as AudioItem).duration * TimeSpan.SECOND;
         int64 stop = duration - TimeSpan.MILLISECOND;
         int64 parsed_value = 0;
         bool parsing_start = true;
@@ -90,12 +90,12 @@ internal class Rygel.HTTPTimeSeek : Rygel.HTTPSeek {
     }
 
     public static bool needed (HTTPGet request) {
-        return request.item is AudioItem &&
-               (request.item as AudioItem).duration > 0 &&
+        return request.object is AudioItem &&
+               (request.object as AudioItem).duration > 0 &&
                (request.handler is HTTPTranscodeHandler ||
                 (request.thumbnail == null &&
                  request.subtitle == null &&
-                 request.item.is_live_stream ()));
+                 (request.object as MediaItem).is_live_stream ()));
     }
 
     public static bool requested (HTTPGet request) {
diff --git a/src/librygel-server/rygel-http-transcode-handler.vala b/src/librygel-server/rygel-http-transcode-handler.vala
index 7327672..65e088a 100644
--- a/src/librygel-server/rygel-http-transcode-handler.vala
+++ b/src/librygel-server/rygel-http-transcode-handler.vala
@@ -51,7 +51,7 @@ internal class Rygel.HTTPTranscodeHandler : HTTPGetHandler {
 
     public override HTTPResponse render_body (HTTPGet request)
                                               throws HTTPRequestError {
-        var item = request.item;
+        var item = request.object as MediaItem;
         var src = item.create_stream_source
                                         (request.http_server.context.host_ip);
         if (src == null) {
@@ -71,7 +71,7 @@ internal class Rygel.HTTPTranscodeHandler : HTTPGetHandler {
                                                       HTTPGet      request)
                                                       throws Error {
         return this.transcoder.add_resource (didl_item,
-                                             request.item,
+                                             request.object as MediaItem,
                                              request.http_server);
     }
 }
diff --git a/tests/rygel-http-byte-seek-test.vala b/tests/rygel-http-byte-seek-test.vala
index c370613..b64e09a 100644
--- a/tests/rygel-http-byte-seek-test.vala
+++ b/tests/rygel-http-byte-seek-test.vala
@@ -27,10 +27,13 @@ private errordomain Rygel.TestError {
 
 private class Rygel.HTTPIdentityHandler : GLib.Object {}
 
-private class Rygel.MediaItem : GLib.Object {
+public class Rygel.MediaObject : GLib.Object {
     public int64 size = 2048;
 }
 
+private class Rygel.MediaItem : MediaObject {
+}
+
 private class Rygel.Thumbnail : GLib.Object {
     public int64 size = 1024;
 }
@@ -39,11 +42,14 @@ private class Rygel.Subtitle : GLib.Object {
     public int64 size = 512;
 }
 
+public class Rygel.MediaContainer : MediaObject {
+}
+
 private class Rygel.HTTPGet : GLib.Object {
     public const string ITEM_URI = "http://DoesntMatterWhatThisIs";;
 
     public Soup.Message msg;
-    public MediaItem item;
+    public MediaObject object;
     public Thumbnail thumbnail;
     public Subtitle subtitle;
 
@@ -51,7 +57,7 @@ private class Rygel.HTTPGet : GLib.Object {
 
     public HTTPGet (Thumbnail? thumbnail, Subtitle? subtitle) {
         this.msg = new Soup.Message ("HTTP", ITEM_URI);
-        this.item = new MediaItem ();
+        this.object = new MediaItem ();
         this.handler = new HTTPIdentityHandler ();
         this.thumbnail = thumbnail;
         this.subtitle = subtitle;
@@ -155,7 +161,7 @@ private class Rygel.HTTPByteSeekTest : GLib.Object {
         } else if (request.subtitle != null) {
             size = request.subtitle.size;
         } else {
-            size = request.item.size;
+            size = request.object.size;
         }
 
         this.test_seek (request, 0, size - 1);
@@ -172,7 +178,7 @@ private class Rygel.HTTPByteSeekTest : GLib.Object {
         } else if (request.subtitle != null) {
             size = request.subtitle.size;
         } else {
-            size = request.item.size;
+            size = request.object.size;
         }
 
         this.test_seek (request, 128, size - 1);
@@ -214,7 +220,7 @@ private class Rygel.HTTPByteSeekTest : GLib.Object {
         } else if (request.subtitle != null) {
             assert (seek.total_length == request.subtitle.size);
         } else {
-            assert (seek.total_length == request.item.size);
+            assert (seek.total_length == request.object.size);
         }
 
         if (request.msg.request_headers.get_one ("Range") != null) {
diff --git a/tests/rygel-http-get-test.vala b/tests/rygel-http-get-test.vala
index 3eb9cda..5a8e5bc 100644
--- a/tests/rygel-http-get-test.vala
+++ b/tests/rygel-http-get-test.vala
@@ -217,7 +217,7 @@ public class Rygel.HTTPGetTest : GLib.Object {
 
             yield request.run ();
 
-            assert ((request as HTTPGet).item != null);
+            assert ((request as HTTPGet).object != null);
 
             debug ("status.code: %d", (int) msg.status_code);
             assert (msg.status_code == this.current_request.expected_code);
diff --git a/tests/rygel-http-post-test.vala b/tests/rygel-http-post-test.vala
index ffaf299..8097840 100644
--- a/tests/rygel-http-post-test.vala
+++ b/tests/rygel-http-post-test.vala
@@ -339,7 +339,6 @@ public class Rygel.MediaContainer : Rygel.MediaObject {
 
     public signal void container_updated (MediaContainer container);
 
-    public string id = "TesContainer";
     public MediaItem item;
     private bool vanish;
     private bool error;
@@ -352,6 +351,7 @@ public class Rygel.MediaContainer : Rygel.MediaObject {
         this.item = new MediaItem (ITEM_ID, this);
         this.vanish = false;
         this.error = false;
+        this.id = "TesContainer";
 
         this.monitor = this.file.monitor_file (FileMonitorFlags.NONE);
         this.monitor.changed.connect (this.on_file_changed);
@@ -414,9 +414,6 @@ public class Rygel.MediaContainer : Rygel.MediaObject {
 public class Rygel.MediaItem : Rygel.MediaObject {
     public const string URI = "file:///tmp/rygel-upload-test.wav";
 
-    public weak MediaContainer parent;
-
-    public string id;
     public long size = 1024;
     public long duration = 1024;
     public ArrayList<string> uris = new ArrayList<string> ();
@@ -502,6 +499,8 @@ public class Rygel.ItemRemovalQueue: GLib.Object {
 }
 
 public class Rygel.MediaObject : GLib.Object {
+    public string id;
+    public unowned MediaContainer parent;
     public string mime_type = "";
 }
 
diff --git a/tests/rygel-http-time-seek-test.vala b/tests/rygel-http-time-seek-test.vala
index 3e7283b..c24c2ac 100644
--- a/tests/rygel-http-time-seek-test.vala
+++ b/tests/rygel-http-time-seek-test.vala
@@ -27,9 +27,14 @@ private errordomain Rygel.TestError {
 
 private class Rygel.HTTPTranscodeHandler : GLib.Object {}
 
-private abstract class Rygel.MediaItem : GLib.Object {
+public class Rygel.MediaObject : GLib.Object {
     public int64 size = -1;
+}
+
+public class Rygel.MediaContainer : MediaObject {
+}
 
+private abstract class Rygel.MediaItem : MediaObject {
     public bool is_live_stream () {
         return true;
     }
@@ -46,7 +51,7 @@ private class Rygel.HTTPGet : GLib.Object {
     public const string ITEM_URI = "http://DoesntMatterWhatThisIs";;
 
     public Soup.Message msg;
-    public MediaItem item;
+    public MediaObject object;
     public Thumbnail thumbnail;
     public Subtitle subtitle;
 
@@ -54,7 +59,7 @@ private class Rygel.HTTPGet : GLib.Object {
 
     public HTTPGet (Thumbnail? thumbnail, Subtitle? subtitle) {
         this.msg = new Soup.Message ("HTTP", ITEM_URI);
-        this.item = new AudioItem ();
+        this.object = new AudioItem ();
         this.handler = new HTTPTranscodeHandler ();
         this.thumbnail = thumbnail;
         this.subtitle = subtitle;
@@ -164,7 +169,7 @@ private class Rygel.HTTPTimeSeekTest : GLib.Object {
     private void test_no_seek (Thumbnail? thumbnail,
                                Subtitle?  subtitle) throws HTTPSeekError {
         var request = new HTTPGet (thumbnail, subtitle);
-        var audio_item = request.item as AudioItem;
+        var audio_item = request.object as AudioItem;
         this.test_seek (request,
                         0,
                         audio_item.duration * TimeSpan.SECOND - TimeSpan.MILLISECOND);
@@ -187,7 +192,7 @@ private class Rygel.HTTPTimeSeekTest : GLib.Object {
             break;
         }
 
-        var audio_item = request.item as AudioItem;
+        var audio_item = request.object as AudioItem;
         this.test_seek (request,
                         128 * TimeSpan.SECOND,
                         audio_item.duration * TimeSpan.SECOND - TimeSpan.MILLISECOND);
@@ -264,7 +269,7 @@ private class Rygel.HTTPTimeSeekTest : GLib.Object {
         assert (seek.stop == stop);
         assert (seek.length == seek.stop + TimeSpan.MILLISECOND - seek.start);
 
-        var audio_item = request.item as AudioItem;
+        var audio_item = request.object as AudioItem;
         assert (seek.total_length == audio_item.duration * TimeSpan.SECOND);
 
         var header = request.msg.response_headers.get_one



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