[rygel/wip/track-changes: 127/128] WIP



commit 05be6576ac485f290beedba1b1e5d94eda20f3c5
Author: Jens Georg <jensg openismus com>
Date:   Tue Oct 16 16:38:59 2012 +0200

    WIP

 src/librygel-core/rygel-plugin.vala                |    2 +
 src/librygel-server/rygel-content-directory.vala   |    8 +-
 src/plugins/mediathek/rygel-mediathek-plugin.vala  |    1 +
 .../mediathek/rygel-mediathek-root-container.vala  |    4 +-
 .../mediathek/rygel-mediathek-rss-container.vala   |   14 ++-
 tests/Makefile.am                                  |    6 +
 tests/data/reference/cds-event-v1.xsd              |   73 ++++++++++++
 tests/rygel-last-change-test.vala                  |  120 ++++++++++++++++++++
 8 files changed, 223 insertions(+), 5 deletions(-)
---
diff --git a/src/librygel-core/rygel-plugin.vala b/src/librygel-core/rygel-plugin.vala
index 7e7dd64..70b49af 100644
--- a/src/librygel-core/rygel-plugin.vala
+++ b/src/librygel-core/rygel-plugin.vala
@@ -1,8 +1,10 @@
 /*
  * Copyright (C) 2008 Nokia Corporation.
+ * Copyright (C) 2012 Intel Corporation.
  *
  * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
  *                               <zeeshan ali nokia com>
+ *         Jens Georg <jensg openismus com>
  *
  * This file is part of Rygel.
  *
diff --git a/src/librygel-server/rygel-content-directory.vala b/src/librygel-server/rygel-content-directory.vala
index 9af86c6..fada40e 100644
--- a/src/librygel-server/rygel-content-directory.vala
+++ b/src/librygel-server/rygel-content-directory.vala
@@ -397,7 +397,7 @@ internal class Rygel.ContentDirectory: Service {
                                        ObjectEventType event_type,
                                        bool sub_tree_update) {
         this.add_last_change_entry (object, event_type, sub_tree_update);
-        this.system_update_id++;
+        //this.system_update_id++;
         updated_container.update_id = this.system_update_id++;
 
         if (this.clear_updated_containers) {
@@ -431,6 +431,10 @@ internal class Rygel.ContentDirectory: Service {
         this.notify ("SystemUpdateID", typeof (uint32), this.system_update_id);
         this.notify ("LastChange", typeof (string), this.last_change.get_log ());
 
+        debug ("%llu Running update_notify: %s",
+               get_real_time (),
+               this.last_change.get_log ());
+
         this.clear_updated_containers = true;
         this.update_notify_id = 0;
         this.last_change.clear_on_new_event ();
@@ -520,7 +524,7 @@ internal class Rygel.ContentDirectory: Service {
     {
         LastChangeEntry entry;
 
-        this.system_update_id++;
+        //this.system_update_id++;
         switch (event_type) {
         case ObjectEventType.ADDED:
             entry = new LastChangeObjAdd (object.id,
diff --git a/src/plugins/mediathek/rygel-mediathek-plugin.vala b/src/plugins/mediathek/rygel-mediathek-plugin.vala
index 1a37335..cc87b96 100644
--- a/src/plugins/mediathek/rygel-mediathek-plugin.vala
+++ b/src/plugins/mediathek/rygel-mediathek-plugin.vala
@@ -46,5 +46,6 @@ public class Rygel.Mediathek.Plugin : Rygel.MediaServerPlugin {
 
     public Plugin () {
         base (RootContainer.get_instance (), Plugin.NAME);
+        this.capabilities |= PluginCapabilities.TRACK_CHANGES;
     }
 }
diff --git a/src/plugins/mediathek/rygel-mediathek-root-container.vala b/src/plugins/mediathek/rygel-mediathek-root-container.vala
index 1cb8a8c..04c9233 100644
--- a/src/plugins/mediathek/rygel-mediathek-root-container.vala
+++ b/src/plugins/mediathek/rygel-mediathek-root-container.vala
@@ -72,7 +72,9 @@ public class Rygel.Mediathek.RootContainer : Rygel.SimpleContainer {
         }
 
         foreach (int id in feeds) {
-            this.add_child_container (new RssContainer (this, id));
+            var container = new RssContainer (this, id);
+            this.add_child_container (container);
+            this.updated (container,ObjectEventType.ADDED, false);
         }
 
         Timeout.add_seconds (update_interval, () => {
diff --git a/src/plugins/mediathek/rygel-mediathek-rss-container.vala b/src/plugins/mediathek/rygel-mediathek-rss-container.vala
index 8bc5b65..c2b9bae 100644
--- a/src/plugins/mediathek/rygel-mediathek-rss-container.vala
+++ b/src/plugins/mediathek/rygel-mediathek-rss-container.vala
@@ -39,7 +39,9 @@ public class Rygel.Mediathek.RssContainer : Rygel.SimpleContainer {
         this.content_id = id;
         this.feed_uri = uri_template.printf (id);
         this.sort_criteria = "-dc:date,+dc:title";
-        this.update.begin ();
+        Timeout.add_seconds (40, () => { this.update.begin (); return false;
+                });
+        // this.update.begin ();
     }
 
     public async void update () {
@@ -103,20 +105,28 @@ public class Rygel.Mediathek.RssContainer : Rygel.SimpleContainer {
             return false;
         }
 
-        this.children.clear ();
         this.child_count = 0;
+        this.updated (this, ObjectEventType.MODIFIED, true);
+        foreach (var child in this.children) {
+            this.updated (child, ObjectEventType.DELETED, true);
+        }
+
+        this.children.clear ();
+
         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);
+                    this.updated (item, ObjectEventType.ADDED, true);
                 }
             } catch (VideoItemError error) {
                 debug ("Could not create video item: %s, skipping",
                        error.message);
             }
         }
+        this.sub_tree_updates_finished (this);
 
         xpath_free_object (xpath_object);
         //this.updated ();
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2928eac..02d5ffa 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -34,6 +34,7 @@ AM_VALAFLAGS = --disable-warnings \
                --pkg uuid --vapidir=$(top_srcdir)/src/librygel-core -g \
 	       $(COVERAGE_VALAFLAGS)
 
+noinst_PROGRAMS = rygel-last-change-test
 check_PROGRAMS = rygel-http-item-uri-test \
 		 rygel-http-response-test \
 		 rygel-http-byte-seek-test \
@@ -160,6 +161,11 @@ rygel_media_engine_test_LDADD = \
 	$(top_builddir)/src/librygel-server/librygel-server-2.0.la \
 	$(top_builddir)/src/librygel-core/librygel-core-2.0.la
 
+rygel_last_change_test_SOURCES = rygel-last-change-test.vala
+rygel_last_change_test_CFLAGS = $(AM_CFLAGS) \
+	-DTEST_DATA_FOLDER='"$(abs_srcdir)/data"'
+rygel_last_change_test_VALAFLAGS = --pkg gupnp-1.0 --pkg libxml-2.0
+
 if HAVE_GSTREAMER
 check_PROGRAMS += \
 	rygel-playbin-renderer-test \
diff --git a/tests/data/reference/cds-event-v1.xsd b/tests/data/reference/cds-event-v1.xsd
new file mode 100644
index 0000000..929e4df
--- /dev/null
+++ b/tests/data/reference/cds-event-v1.xsd
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema targetNamespace="urn:schemas-upnp-org:av:cds-event"
+  xmlns:cds-event="urn:schemas-upnp-org:av:cds-event"
+  xmlns:av="urn:schemas-upnp-org:av:av"
+  xmlns:xsd="http://www.w3.org/2001/XMLSchema";
+  elementFormDefault="qualified"
+  attributeFormDefault="unqualified"
+  version="1-20080930">
+  <xsd:annotation>
+    <xsd:documentation xml:lang="en">
+		For UPnP A/V ContentDirectory Service events
+	</xsd:documentation>
+  </xsd:annotation>
+  <xsd:import namespace="http://www.w3.org/XML/1998/namespace"; schemaLocation="http://www.w3.org/2005/08/xml.xsd"; />
+  <xsd:import namespace="urn:schemas-upnp-org:av:av" schemaLocation="http://www.upnp.org/schemas/av/av.xsd"; />
+  <!--===========================================================
+		'Event' is the root element of a CDSevent document.
+	============================================================-->
+  <xsd:element name="StateEvent">
+    <xsd:complexType>
+      <xsd:choice minOccurs="0" maxOccurs="unbounded">
+        <xsd:element name="objAdd">
+          <xsd:complexType>
+            <xsd:attribute name="objID" type="av:_id.type" use="required" />
+            <xsd:attribute name="updateID" type="av:stateUpdateID.type" use="required" />
+            <xsd:attribute name="stUpdate" type="xsd:boolean" use="required" />
+            <xsd:attribute name="objParentID" type="av:_id.type" use="required" />
+            <xsd:attribute name="objClass" type="av:_classNameBase.type" use="required" />
+            <xsd:attributeGroup ref="cds-event:event.extensions.attributes" />
+          </xsd:complexType>
+        </xsd:element>
+        <xsd:element name="objMod">
+          <xsd:complexType>
+            <xsd:attribute name="objID" type="av:_id.type" use="required" />
+            <xsd:attribute name="updateID" type="av:stateUpdateID.type" use="required" />
+            <xsd:attribute name="stUpdate" type="xsd:boolean" use="required" />
+            <xsd:attributeGroup ref="cds-event:event.extensions.attributes" />
+          </xsd:complexType>
+        </xsd:element>
+        <xsd:element name="objDel">
+          <xsd:complexType>
+            <xsd:attribute name="objID" type="av:_id.type" use="required" />
+            <xsd:attribute name="updateID" type="av:stateUpdateID.type" use="required" />
+            <xsd:attribute name="stUpdate" type="xsd:boolean" use="required" />
+            <xsd:attributeGroup ref="cds-event:event.extensions.attributes" />
+          </xsd:complexType>
+        </xsd:element>
+        <xsd:element name="stDone">
+          <xsd:complexType>
+            <xsd:attribute name="objID" type="av:_id.type" use="required" />
+            <xsd:attribute name="updateID" type="av:stateUpdateID.type" use="required" />
+            <xsd:attributeGroup ref="cds-event:event.extensions.attributes" />
+          </xsd:complexType>
+        </xsd:element>
+        <xsd:group ref="cds-event:events.vx.group" />
+      </xsd:choice>
+    </xsd:complexType>
+  </xsd:element>
+  <!--========================================================================================
+
+  Extension Component Datatypes
+
+  ========================================================================================-->
+  <xsd:attributeGroup name="event.extensions.attributes">
+    <xsd:attributeGroup ref="av:extensions.attributes.any" />
+  </xsd:attributeGroup>
+
+  <xsd:group name="events.vx.group">
+    <xsd:choice>
+      <xsd:any namespace="##other" />
+    </xsd:choice>
+  </xsd:group>
+</xsd:schema>
diff --git a/tests/rygel-last-change-test.vala b/tests/rygel-last-change-test.vala
new file mode 100644
index 0000000..9f38380
--- /dev/null
+++ b/tests/rygel-last-change-test.vala
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.
+ *
+ * Author: Jens Georg <jensg openismus com>
+ *
+ * This file is part of Rygel.
+ *
+ * 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.
+ */
+
+using GUPnP;
+using Xml;
+
+[CCode (cname="TEST_DATA_FOLDER")]
+extern const string TEST_DATA_FOLDER;
+
+static const string TARGET =
+    "urn:schemas-upnp-org:service:ContentDirectory:3";
+
+public class LastChangeTest : Object {
+    private MainLoop loop;
+    private ControlPoint cp;
+    private ServiceProxy proxy;
+    private uint timeout;
+    private string lastchange_xsd_file;
+    private SchemaValidCtxt *valid_ctxt;
+    private Schema *schema;
+
+    ~LastChangeTest () {
+        delete this.valid_ctxt;
+        delete this.schema;
+    }
+
+    private void on_last_change (ServiceProxy p, string variable, Value value) {
+        assert (variable == "LastChange");
+        var content = value.get_string ();
+        var doc = Parser.read_memory (content, content.length);
+        assert (doc != null);
+        assert (this.valid_ctxt->validate_doc (doc) == 0);
+        debug (content);
+    }
+
+    private void on_sp_available (ServiceProxy p) {
+        this.proxy = p;
+        Source.remove (this.timeout);
+        debug ("====> Got proxy: %llu", get_real_time ());
+        try {
+            // Check if the service offers the LastChange state variable
+            var last_change = false;
+            var introspection = p.get_introspection ();
+            unowned List<string> names =
+                                    introspection.list_state_variable_names ();
+            foreach (var name in names) {
+                if (name == "LastChange") {
+                    last_change = true;
+
+                    break;
+                }
+            }
+            assert (last_change);
+            this.proxy.add_notify ("LastChange",
+                                   typeof (string),
+                                   this.on_last_change);
+            this.proxy.subscribed = true;
+        } catch (GLib.Error error) {
+            assert_not_reached ();
+        }
+    }
+
+    private void on_sp_unavailable (ServiceProxy p) {
+        if (this.proxy == p) {
+            warning ("Proxy disappeared while running the test!");
+            assert_not_reached ();
+        }
+    }
+
+    public int run () {
+        this.loop = new MainLoop ();
+        this.lastchange_xsd_file = Path.build_filename (TEST_DATA_FOLDER,
+                                                        "reference",
+                                                        "cds-event-v1.xsd");
+        this.schema = new SchemaParserCtxt (this.lastchange_xsd_file).parse ();
+        this.valid_ctxt = new SchemaValidCtxt (schema);
+        try {
+            var context = new Context (null, "lo", 0);
+            this.cp = new ControlPoint (context, TARGET);
+            this.cp.service_proxy_available.connect (on_sp_available);
+            this.cp.service_proxy_unavailable.connect (on_sp_unavailable);
+            this.cp.active = true;
+            this.timeout = Timeout.add_seconds (10, () => {
+                warning ("No suitable server found!");
+//                assert_not_reached ();
+                return false;
+            });
+            this.loop.run ();
+
+            return 0;
+        } catch (GLib.Error error) {
+            print ("Failed to create context: %s\n", error.message);
+            assert_not_reached ();
+        }
+    }
+
+    public static int main (string[] args) {
+        var test = new LastChangeTest ();
+        return test.run ();
+    }
+}



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