[rygel] external: Fetch items on demand
- From: Zeeshan Ali Khattak <zeeshanak src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [rygel] external: Fetch items on demand
- Date: Mon, 14 Sep 2009 15:43:33 +0000 (UTC)
commit 22d1b33c61a51d1d87c917c6b9dc927a310fd45d
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date: Mon Sep 14 18:34:29 2009 +0300
external: Fetch items on demand
src/plugins/external/rygel-external-container.vala | 115 +++++++++++++-------
src/plugins/external/rygel-external-item.vala | 28 ++++-
2 files changed, 97 insertions(+), 46 deletions(-)
---
diff --git a/src/plugins/external/rygel-external-container.vala b/src/plugins/external/rygel-external-container.vala
index b1e4dd9..9946eb5 100644
--- a/src/plugins/external/rygel-external-container.vala
+++ b/src/plugins/external/rygel-external-container.vala
@@ -44,7 +44,7 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer {
public string service_name;
private string object_path;
- private ArrayList<MediaObject> media_objects;
+ private ArrayList<ExternalContainer> containers;
public ExternalContainer (string id,
string service_name,
@@ -57,7 +57,7 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer {
this.object_path = object_path;
this.host_ip = host_ip;
- this.media_objects = new ArrayList<MediaObject> ();
+ this.containers = new ArrayList<ExternalContainer> ();
try {
DBus.Connection connection = DBus.Bus.get (DBus.BusType.SESSION);
@@ -75,12 +75,13 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer {
object_path,
CONTAINER_IFACE);
- this.fetch_media_objects ();
+ this.update_container ();
this.actual_container.Updated += this.on_container_updated;
- } catch (DBus.Error error) {
- critical ("Failed to fetch root media objects: %s\n",
- error.message);
+ } catch (GLib.Error err) {
+ critical ("Failed to fetch information about container '%s': %s\n",
+ this.id,
+ err.message);
}
}
@@ -88,14 +89,40 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer {
uint max_count,
Cancellable? cancellable,
AsyncReadyCallback callback) {
- uint stop = offset + max_count;
+ var media_objects = new ArrayList <MediaObject> ();
+
+ // First add the child containers
+ media_objects.add_all (this.containers);
+
+ // Then get and add the child items
+ Value value;
+ this.props.Get (CONTAINER_IFACE, "Items", out value);
+ unowned PtrArray obj_paths = (PtrArray) value.get_boxed ();
+ if (obj_paths.len > 0) {
+ for (var i = 0; i < obj_paths.len; i++) {
+ var obj_path = (ObjectPath) obj_paths.pdata[i];
+
+ try {
+ var item = new ExternalItem.for_path (obj_path, this);
+
+ media_objects.add (item);
+ } catch (GLib.Error err) {
+ warning ("Error initializable item at '%s': %s. Ignoring..",
+ obj_path,
+ err.message);
+ }
+ }
+ }
+
+ uint stop = offset + max_count;
stop = stop.clamp (0, this.child_count);
- var containers = this.media_objects.slice ((int) offset, (int) stop);
+
+ var children = media_objects.slice ((int) offset, (int) stop);
var res = new Rygel.SimpleAsyncResult<Gee.List<MediaObject>>
(this, callback);
- res.data = containers;
+ res.data = children;
res.complete_in_idle ();
}
@@ -109,10 +136,17 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer {
public override void find_object (string id,
Cancellable? cancellable,
AsyncReadyCallback callback) {
- MediaObject media_object = find_object_sync (id);
-
var res = new Rygel.SimpleAsyncResult<MediaObject> (this, callback);
+ MediaObject media_object = find_container (id);
+ if (media_object == null && ExternalItem.id_valid (id)) {
+ try {
+ media_object = new ExternalItem.for_id (id, this);
+ } catch (GLib.Error err) {
+ res.error = err;
+ }
+ }
+
res.data = media_object;
res.complete_in_idle ();
}
@@ -120,7 +154,12 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer {
public override MediaObject? find_object_finish (AsyncResult res)
throws GLib.Error {
var simple_res = (Rygel.SimpleAsyncResult<MediaObject>) res;
- return simple_res.data;
+
+ if (simple_res.error != null) {
+ throw simple_res.error;
+ } else {
+ return simple_res.data;
+ }
}
public string substitute_keywords (string title) {
@@ -135,32 +174,31 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer {
}
// Private methods
- private MediaObject? find_object_sync (string id) {
- MediaObject obj = null;
+ private MediaContainer? find_container (string id) {
+ MediaContainer container = null;
- foreach (var tmp in this.media_objects) {
+ foreach (var tmp in this.containers) {
if (id == tmp.id) {
- obj = tmp;
- } else if (tmp is ExternalContainer) {
+ container = tmp;
+ } else {
// Check it's children
- var container = (ExternalContainer) tmp;
-
- obj = container.find_object_sync (id);
+ container = tmp.find_container (id);
}
- if (obj != null) {
+ if (container != null) {
break;
}
}
- return obj;
+ return container;
}
- private void fetch_media_objects () throws GLib.Error {
- HashTable<string,Value?> all_props =
- this.props.GetAll (CONTAINER_IFACE);
+ private void update_container () throws GLib.Error {
+ this.containers.clear ();
+
+ Value value;
+ this.props.Get (CONTAINER_IFACE, "Containers", out value);
- var value = all_props.lookup ("Containers");
unowned PtrArray obj_paths = (PtrArray) value.get_boxed ();
if (obj_paths.len > 0) {
for (var i = 0; i < obj_paths.len; i++) {
@@ -171,30 +209,23 @@ public class Rygel.ExternalContainer : Rygel.MediaContainer {
obj_path,
this.host_ip,
this);
- this.media_objects.add (container);
- }
- }
-
- value = all_props.lookup ("Items");
- obj_paths = (PtrArray) value.get_boxed ();
- if (obj_paths.len > 0) {
- for (var i = 0; i < obj_paths.len; i++) {
- var obj_path = (ObjectPath) obj_paths.pdata[i];
- this.media_objects.add (new ExternalItem (obj_path,
- this));
+ this.containers.add (container);
}
}
- this.child_count = this.media_objects.size;
+ this.child_count = this.containers.size;
+ this.props.Get (CONTAINER_IFACE, "ItemCount", out value);
+ this.child_count = value.get_int ();
}
private void on_container_updated (dynamic DBus.Object actual_container) {
- // Re-fetch the objects
- this.media_objects.clear ();
try {
- this.fetch_media_objects ();
+ // Update our information about the container
+ this.update_container ();
} catch (GLib.Error err) {
- warning ("Failed to re-fetch media objects: %s\n", err.message);
+ warning ("Failed to update information about container '%s': %s\n",
+ this.id,
+ err.message);
}
// and signal the clients
diff --git a/src/plugins/external/rygel-external-item.vala b/src/plugins/external/rygel-external-item.vala
index fe5131e..9f078e3 100644
--- a/src/plugins/external/rygel-external-item.vala
+++ b/src/plugins/external/rygel-external-item.vala
@@ -33,10 +33,26 @@ public class Rygel.ExternalItem : Rygel.MediaItem {
private static string OBJECT_IFACE = "org.gnome.UPnP.MediaObject1";
private static string ITEM_IFACE = "org.gnome.UPnP.MediaItem1";
- public ExternalItem (string object_path,
- ExternalContainer parent)
- throws GLib.Error {
- base ("item:" + object_path,
+ public ExternalItem.for_path (string object_path,
+ ExternalContainer parent) throws GLib.Error {
+ this ("item:" + object_path, object_path, parent);
+ }
+
+ public ExternalItem.for_id (string id,
+ ExternalContainer parent) throws GLib.Error {
+ var object_path = id.str ("/");
+ if (object_path == null) {
+ throw new ContentDirectoryError.NO_SUCH_OBJECT ("No such object");
+ }
+
+ this (id, object_path, parent);
+ }
+
+ private ExternalItem (string id,
+ string object_path,
+ ExternalContainer parent)
+ throws GLib.Error {
+ base (id,
parent,
"Unknown", /* Title Unknown at this point */
"Unknown"); /* UPnP Class Unknown at this point */
@@ -152,5 +168,9 @@ public class Rygel.ExternalItem : Rygel.MediaItem {
this.color_depth = value.get_int ();
}
}
+
+ public static bool id_valid (string id) {
+ return id.has_prefix ("item:/");
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]