[rygel] core: Separate V1 hacks from XBox 360 hacks



commit 3ae63aa2471393230872b47ef9b1966ba3dc326d
Author: Jens Georg <mail jensge org>
Date:   Thu Nov 24 13:07:22 2011 +0100

    core: Separate V1 hacks from XBox 360 hacks

 TODO                                     |    1 -
 src/rygel/Makefile.am                    |    1 +
 src/rygel/rygel-root-device-factory.vala |    3 +
 src/rygel/rygel-v1-hacks.vala            |  121 ++++++++++++++++++++++++++++++
 src/rygel/rygel-xbox-hacks.vala          |    2 +-
 5 files changed, 126 insertions(+), 2 deletions(-)
---
diff --git a/TODO b/TODO
index d8ac9ca..1f1b336 100644
--- a/TODO
+++ b/TODO
@@ -65,7 +65,6 @@
     * Remove relavent code from UI code.
 
   * XBox hacks:
-    * Split in XBox hacks and ContentDirectory:1 hacks
     * Config for device hacks user-agent.
 
   * Transcoding:
diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am
index aa66c82..7c30625 100644
--- a/src/rygel/Makefile.am
+++ b/src/rygel/Makefile.am
@@ -87,6 +87,7 @@ VAPI_SOURCE_FILES = \
 	rygel-xbox-hacks.vala \
 	rygel-panasonic-hacks.vala \
 	rygel-xbmc-hacks.vala \
+	rygel-v1-hacks.vala \
 	rygel-import-resource.vala \
 	rygel-item-creator.vala \
 	rygel-item-destroyer.vala \
diff --git a/src/rygel/rygel-root-device-factory.vala b/src/rygel/rygel-root-device-factory.vala
index b3ba821..e95a604 100644
--- a/src/rygel/rygel-root-device-factory.vala
+++ b/src/rygel/rygel-root-device-factory.vala
@@ -79,6 +79,9 @@ internal class Rygel.RootDeviceFactory {
         var xbox_hacks = new XBoxHacks ();
         xbox_hacks.apply_on_device (device, desc_path);
 
+        var v1_hacks = new V1Hacks ();
+        v1_hacks.apply_on_device (device, desc_path);
+
         return device;
     }
 
diff --git a/src/rygel/rygel-v1-hacks.vala b/src/rygel/rygel-v1-hacks.vala
new file mode 100644
index 0000000..d8c9d46
--- /dev/null
+++ b/src/rygel/rygel-v1-hacks.vala
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2011 Nokia 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 Soup;
+using GUPnP;
+
+/**
+ * Various devices that need a downgrade to MediaServer:1 and
+ * ContentDirectory:1 because they ignore that higher versions are
+ * backwards-compatible.
+ */
+internal class Rygel.V1Hacks : ClientHacks {
+    private const string AGENT = ".*Allegro-Software-WebClient.*|.*SEC_HHP_Galaxy S/1\\.0.*";
+    private const string DMS = "urn:schemas-upnp-org:device:MediaServer";
+    private const string DMS_V1 = DMS + ":1";
+
+    public V1Hacks () throws ClientHacksError, RegexError {
+        base (AGENT);
+    }
+
+    public V1Hacks.for_action (ServiceAction action)
+                                 throws ClientHacksError {
+        unowned MessageHeaders headers = action.get_message ().request_headers;
+        this.for_headers (headers);
+    }
+
+    public V1Hacks.for_headers (MessageHeaders headers)
+                                  throws ClientHacksError {
+        base (AGENT, headers);
+    }
+
+    public void apply_on_device (RootDevice device,
+                                 string     template_path) throws Error {
+        if (!device.get_device_type ().has_prefix (DMS)) {
+            return;
+        }
+
+        var doc = new XMLDoc.from_path (template_path);
+        this.modify_dms_desc (doc.doc);
+
+        var desc_path = template_path.replace (".xml", "-v1.xml");
+        this.save_modified_desc (doc, desc_path);
+
+        var server_path = "/" + device.get_relative_location ();
+        device.context.host_path_for_agent (desc_path,
+                                            server_path,
+                                            this.agent_regex);
+    }
+
+    private void modify_dms_desc (Xml.Doc doc) {
+        Xml.Node *element = XMLUtils.get_element ((Xml.Node *) doc,
+                                                  "root",
+                                                  "device",
+                                                  "deviceType");
+        assert (element != null);
+        element->set_content (DMS_V1);
+
+        this.modify_service_list (doc);
+    }
+
+    private void modify_service_list (Xml.Node *doc_node) {
+        Xml.Node *element = XMLUtils.get_element (doc_node,
+                                                  "root",
+                                                  "device",
+                                                  "serviceList");
+        assert (element != null && element->children != null);
+
+        for (var service_node = element->children;
+             service_node != null;
+             service_node = service_node->next) {
+            for (var type_node = service_node->children;
+                 type_node != null;
+                 type_node = type_node->next) {
+                if (type_node->name == "serviceType") {
+                    switch (type_node->get_content ()) {
+                        case ContentDirectory.UPNP_TYPE:
+                            type_node->set_content
+                                        (ContentDirectory.UPNP_TYPE_V1);
+                            break;
+                        default:
+                            break;
+                    }
+                }
+            }
+        }
+    }
+
+    private void save_modified_desc (XMLDoc doc,
+                                     string desc_path) throws GLib.Error {
+        FileStream f = FileStream.open (desc_path, "w+");
+        int res = -1;
+
+        if (f != null)
+            res = doc.doc.dump (f);
+
+        if (f == null || res == -1) {
+            var message = _("Failed to write modified description to %s.");
+
+            throw new IOError.FAILED (message, desc_path);
+        }
+    }
+}
diff --git a/src/rygel/rygel-xbox-hacks.vala b/src/rygel/rygel-xbox-hacks.vala
index 4030b30..d81cbe9 100644
--- a/src/rygel/rygel-xbox-hacks.vala
+++ b/src/rygel/rygel-xbox-hacks.vala
@@ -26,7 +26,7 @@ using GUPnP;
 
 internal class Rygel.XBoxHacks : ClientHacks {
     private const string AGENT =
-        ".*Xbox.*|.*Allegro-Software-WebClient.*|.*SEC_HHP_Galaxy S/1\\.0.*";
+        ".*Xbox.*";
     private const string DMS = "urn:schemas-upnp-org:device:MediaServer";
     private const string DMS_V1 = DMS + ":1";
     private const string FRIENDLY_NAME_POSTFIX = ":";



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