[rygel/wip/track-changes: 15/21] wip: Add automatic change tracking



commit 00c9b9c9a4dcda84b72af47b817a5b0d95566d19
Author: Jens Georg <jensg openismus com>
Date:   Sat Oct 20 21:54:05 2012 +0200

    wip: Add automatic change tracking

 src/librygel-server/rygel-content-directory.vala   |    8 ++-
 src/librygel-server/rygel-media-container.vala     |    2 +
 src/librygel-server/rygel-trackable-container.vala |   70 ++++++++++++++++++++
 src/plugins/mediathek/rygel-mediathek-plugin.vala  |    5 +-
 .../mediathek/rygel-mediathek-root-container.vala  |   10 ++-
 .../mediathek/rygel-mediathek-rss-container.vala   |   12 ++-
 6 files changed, 98 insertions(+), 9 deletions(-)
---
diff --git a/src/librygel-server/rygel-content-directory.vala b/src/librygel-server/rygel-content-directory.vala
index bfa3f7c..123d321 100644
--- a/src/librygel-server/rygel-content-directory.vala
+++ b/src/librygel-server/rygel-content-directory.vala
@@ -400,7 +400,13 @@ internal class Rygel.ContentDirectory: Service {
                                        bool sub_tree_update) {
         this.add_last_change_entry (object, event_type, sub_tree_update);
         this.system_update_id++;
-        updated_container.update_id = this.system_update_id++;
+
+        if (event_type == ObjectEventType.ADDED ||
+            event_type == ObjectEventType.DELETED) {
+            updated_container.update_id = this.system_update_id;
+        } else {
+            object.object_update_id = this.system_update_id;
+        }
 
         if (this.clear_updated_containers) {
             this.updated_containers.clear ();
diff --git a/src/librygel-server/rygel-media-container.vala b/src/librygel-server/rygel-media-container.vala
index 8aeee09..34917e9 100644
--- a/src/librygel-server/rygel-media-container.vala
+++ b/src/librygel-server/rygel-media-container.vala
@@ -200,6 +200,8 @@ public abstract class Rygel.MediaContainer : MediaObject {
         didl_container.upnp_class = this.upnp_class;
         didl_container.searchable = this is SearchableContainer;
         didl_container.storage_used = this.storage_used;
+            didl_container.container_update_id = this.update_id;
+            didl_container.update_id = this.object_update_id;
 
         if (this.parent == null && (this is SearchableContainer)) {
             (this as SearchableContainer).serialize_search_parameters
diff --git a/src/librygel-server/rygel-trackable-container.vala b/src/librygel-server/rygel-trackable-container.vala
new file mode 100644
index 0000000..952d7a4
--- /dev/null
+++ b/src/librygel-server/rygel-trackable-container.vala
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Author: Jens Georg <jensg openismus come
+ *
+ * Rygel is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Rygel is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+public interface Rygel.TrackableContainer : Rygel.MediaContainer {
+    public async void clear () {
+        try {
+            var children = yield this.get_children (0, 0, "", null);
+            if (children == null) {
+                return;
+            }
+
+            foreach (var child in children) {
+                yield this.remove_child_tracked (child);
+            }
+        } catch (Error error) {
+        }
+    }
+
+    public abstract async void add_child (MediaObject object);
+
+    public async void add_child_tracked (MediaObject object) {
+        yield this.add_child (object);
+
+        this.updated (object, ObjectEventType.ADDED);
+        this.updated ();
+        if (object is TrackableContainer) {
+            var trackable = object as TrackableContainer;
+
+            // Release the events that might have accumulated
+            trackable.thaw_events ();
+        }
+    }
+
+    public abstract async void remove_child (MediaObject object);
+
+    public async void remove_child_tracked (MediaObject object) {
+        // We need to descend into this to get the proper events
+        if (object is TrackableContainer) {
+            var trackable = object as TrackableContainer;
+            yield trackable.clear ();
+        }
+
+        yield this.remove_child (object);
+
+        this.updated (object, ObjectEventType.DELETED);
+        this.total_deleted_child_count++;
+        this.updated ();
+    }
+
+    private void thaw_events () {
+        // Forward events.
+    }
+}
diff --git a/src/plugins/mediathek/rygel-mediathek-plugin.vala b/src/plugins/mediathek/rygel-mediathek-plugin.vala
index 1a37335..e9d4313 100644
--- a/src/plugins/mediathek/rygel-mediathek-plugin.vala
+++ b/src/plugins/mediathek/rygel-mediathek-plugin.vala
@@ -45,6 +45,9 @@ public class Rygel.Mediathek.Plugin : Rygel.MediaServerPlugin {
     public const string NAME = "ZDFMediathek";
 
     public Plugin () {
-        base (RootContainer.get_instance (), Plugin.NAME);
+        base (RootContainer.get_instance (),
+              Plugin.NAME,
+              null,
+              PluginCapabilities.TRACK_CHANGES);
     }
 }
diff --git a/src/plugins/mediathek/rygel-mediathek-root-container.vala b/src/plugins/mediathek/rygel-mediathek-root-container.vala
index e324895..1534565 100644
--- a/src/plugins/mediathek/rygel-mediathek-root-container.vala
+++ b/src/plugins/mediathek/rygel-mediathek-root-container.vala
@@ -32,7 +32,7 @@ public class Rygel.Mediathek.RootContainer : Rygel.TrackableContainer,
     public static RootContainer get_instance () {
         if (RootContainer.instance == null) {
             RootContainer.instance = new RootContainer ();
-            RootContainer.instance.init ();
+            RootContainer.instance.init.begin ();
         }
 
         return instance;
@@ -47,7 +47,7 @@ public class Rygel.Mediathek.RootContainer : Rygel.TrackableContainer,
         this.session = new Soup.SessionAsync ();
     }
 
-    private void init () {
+    private async void init () {
         Gee.ArrayList<int> feeds = null;
         int update_interval = DEFAULT_UPDATE_INTERVAL;
 
@@ -73,7 +73,7 @@ public class Rygel.Mediathek.RootContainer : Rygel.TrackableContainer,
         }
 
         foreach (int id in feeds) {
-            this.add_child_container (new RssContainer (this, id));
+            yield this.add_child_tracked (new RssContainer (this, id));
         }
 
         Timeout.add_seconds (update_interval, () => {
@@ -86,4 +86,8 @@ public class Rygel.Mediathek.RootContainer : Rygel.TrackableContainer,
             return true;
         });
     }
+
+    public async void add_child (MediaObject object) {
+        this.add_child_container (object as MediaContainer);
+    }
 }
diff --git a/src/plugins/mediathek/rygel-mediathek-rss-container.vala b/src/plugins/mediathek/rygel-mediathek-rss-container.vala
index ff9905a..b0b744a 100644
--- a/src/plugins/mediathek/rygel-mediathek-rss-container.vala
+++ b/src/plugins/mediathek/rygel-mediathek-rss-container.vala
@@ -24,7 +24,8 @@ using Gee;
 using Soup;
 using Xml;
 
-public class Rygel.Mediathek.RssContainer : Rygel.SimpleContainer {
+public class Rygel.Mediathek.RssContainer : Rygel.TrackableContainer,
+                                            Rygel.SimpleContainer {
     private const string uri_template = "http://www.zdf.de/ZDFmediathek/"; +
                                         "content/%u?view=rss";
     private uint content_id;
@@ -103,14 +104,14 @@ public class Rygel.Mediathek.RssContainer : Rygel.SimpleContainer {
             return false;
         }
 
-        this.children.clear ();
+        yield this.clear ();
         this.child_count = 0;
         for (int i = 0; i < xpath_object->nodesetval->length (); i++) {
             var node = xpath_object->nodesetval->item (i);
             try {
                 var item = yield factory.create (this, node);
                 if (item != null) {
-                    this.add_child_item (item);
+                    yield this.add_child_tracked (item);
                 }
             } catch (VideoItemError error) {
                 debug ("Could not create video item: %s, skipping",
@@ -119,7 +120,6 @@ public class Rygel.Mediathek.RssContainer : Rygel.SimpleContainer {
         }
 
         xpath_free_object (xpath_object);
-        this.updated ();
 
         return this.child_count > 0;
     }
@@ -135,4 +135,8 @@ public class Rygel.Mediathek.RssContainer : Rygel.SimpleContainer {
 
         return message;
     }
+
+    public async void add_child (MediaObject object) {
+        this.add_child_item (object as MediaItem);
+    }
 }



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