}
/**
+ * Modify the model description.
+ *
+ * A longer user friendly description of the device.
+ *
+ * @param model_description is the new model description.
+ */
+ public void set_model_description (string model_description) {
+ this.set_device_element ("modelDescription", model_description);
+ }
+
+ /**
* Modify the model name.
*
* Usually the name of the software implementing this device.
}
/**
+ * Set the Unique Device Name of the device.
+ *
+ * Unique Device Name is the UUID of this particular device instance.
+ *
+ * @param udn is the Unique Device Name of the device.
+ */
+ public void set_udn (string udn) {
+ this.set_device_element ("UDN", udn);
+ }
+
+ /**
+ * Get the current UDN of the device.
+ *
+ * @return The currenly set UDN.
+ */
+ public string? get_udn () {
+ var element = Rygel.XMLUtils.get_element ((Xml.Node *) this.doc.doc,
+ "root",
+ "device",
+ "UDN");
+ if (element == null) {
+ return null;
+ }
+
+ return element->get_content ();
+ }
+
+ /**
* Set the DLNA caps of this root device and while taking the
* capabilities of the plugin into account.
*
}
}
+ public void clear_service_list () {
+ this.remove_device_element ("serviceList");
+ }
+
+ public void add_service (string device_name, ResourceInfo resource_info) {
+ var list = Rygel.XMLUtils.get_element
+ ((Xml.Node *) this.doc.doc,
+ "root",
+ "device",
+ "serviceList");
+ if (list == null) {
+ list = this.set_device_element ("serviceList", null);
+ }
+
+ Xml.Node *service_node = list->new_child (null, "service");
+
+ service_node->new_child (null, "serviceType", resource_info.upnp_type);
+ service_node->new_child (null, "serviceId", resource_info.upnp_id);
+
+ /* Now the relative (to base URL) URLs*/
+ string url = "/" + resource_info.description_path;
+ service_node->new_child (null, "SCPDURL", url);
+
+ url = "/Control/" + device_name + "/" + resource_info.type.name ();
+ service_node->new_child (null, "controlURL", url);
+
+ url = "/Event/" + device_name + "/" + resource_info.type.name ();
+ service_node->new_child (null, "eventSubURL", url);
+ }
+
+ public void clear_icon_list () {
+ this.remove_device_element ("iconList");
+ }
+
+ public void add_icon (string device_name,
+ IconInfo icon_info,
+ string url) {
+ var list = Rygel.XMLUtils.get_element
+ ((Xml.Node *) this.doc.doc,
+ "root",
+ "device",
+ "iconList");
+ if (list == null) {
+ list = this.set_device_element ("iconList", null);
+ }
+
+ Xml.Node *icon_node = list->new_child (null, "icon");
+
+ string width = icon_info.width.to_string ();
+ string height = icon_info.height.to_string ();
+ string depth = icon_info.depth.to_string ();
+
+ icon_node->new_child (null, "mimetype", icon_info.mime_type);
+ icon_node->new_child (null, "width", width);
+ icon_node->new_child (null, "height", height);
+ icon_node->new_child (null, "depth", depth);
+ icon_node->new_child (null, "url", url);
+ }
/**
* Change the type of a service.
*
* @param element below /root/device to be set.
* @param new_value is the new content of that element.
+ *
+ * @returns the element that was modified (or created) or null
*/
- private void set_device_element (string element,
- string new_value,
- string? ns = null) {
+ private Xml.Node* set_device_element (string element,
+ string? new_value,
+ string? ns = null) {
var xml_element = Rygel.XMLUtils.get_element
((Xml.Node *) this.doc.doc,
"root",
element);
if (xml_element != null) {
xml_element->set_content (new_value);
- return;
+ return xml_element;
}
// Element not found: create it
"device",
device_elements[index]);
if (sibling != null) {
- sibling->add_next_sibling (xml_element);
+ xml_element = sibling->add_next_sibling (xml_element);
break;
}
// Set as first child
sibling = device_element->first_element_child ();
if (sibling != null) {
- sibling->add_prev_sibling (xml_element);
+ xml_element = sibling->add_prev_sibling (xml_element);
}
}
}
+
+ return xml_element;
}
/**
var doc = this.get_latest_doc (desc_path, template_path);
/* Modify description to include Plugin-specific stuff */
- this.prepare_desc_for_plugin (doc, plugin);
var file = new DescriptionFile.from_xml_document (doc);
- file.set_dlna_caps (plugin.capabilities);
- file.save (desc_path);
-
- return doc;
- }
-
- private void prepare_desc_for_plugin (XMLDoc doc, Plugin plugin) {
- Xml.Node *device_element;
- device_element = XMLUtils.get_element ((Xml.Node *) doc.doc,
- "root",
- "device",
- null);
- if (device_element == null) {
- warning (_("XML node '%s' not found."), "/root/device");
-
- return;
- }
-
- /* First, set the Friendly name and UDN */
- this.set_friendly_name_and_udn (device_element,
- plugin.name,
- plugin.title);
+ this.add_services_to_desc (file, plugin);
+ this.add_icons_to_desc (file, plugin);
+ file.set_friendly_name (this.get_friendly_name (plugin));
+ file.set_dlna_caps (plugin.capabilities);
if (plugin.description != null) {
- this.set_description (device_element, plugin.description);
+ file.set_model_description (plugin.description);
+ }
+ var udn = file.get_udn ();
+ if (udn == null || udn == "") {
+ file.set_udn (this.generate_random_udn ());
}
- /* Then list each icon */
- this.add_icons_to_desc (device_element, plugin);
+ file.save (desc_path);
- /* Then list each service */
- this.add_services_to_desc (device_element, plugin);
+ return doc;
}
- /**
- * Fills the description doc @doc with a friendly name, and UDN from gconf.
- * If these keys are not present in gconf, they are set with default values.
- */
- private void set_friendly_name_and_udn (Xml.Node *device_element,
- string plugin_name,
- string plugin_title) {
- /* friendlyName */
- Xml.Node *element = XMLUtils.get_element (device_element,
- "friendlyName",
- null);
- if (element == null) {
- warning (_("XML node '%s' not found."),
- "/root/device/friendlyName");
-
- return;
- }
-
+ private string get_friendly_name (Plugin plugin) {
string title;
try {
- title = this.config.get_title (plugin_name);
+ title = this.config.get_title (plugin.name);
} catch (GLib.Error err) {
- title = plugin_title;
+ title = plugin.title;
}
title = title.replace ("@REALNAME@", Environment.get_real_name ());
title = title.replace ("@USERNAME@", Environment.get_user_name ());
title = title.replace ("@HOSTNAME@", Environment.get_host_name ());
- element->set_content (title);
-
- /* UDN */
- element = XMLUtils.get_element (device_element, "UDN");
- if (element == null) {
- warning (_("XML node '%s' not found."), "/root/device/UDN");
-
- return;
- }
-
- var udn = element->get_content ();
- if (udn == null || udn == "") {
- udn = this.generate_random_udn ();
-
- element->set_content (udn);
- }
- }
-
- private void set_description (Xml.Node *device_element,
- string description) {
- Xml.Node *element = XMLUtils.get_element (device_element,
- "modelDescription",
- null);
- if (element == null) {
- device_element->new_child (null, "modelDescription", description);
- }
-
- element->set_content (description);
+ return title;
}
- private void add_services_to_desc (Xml.Node *device_element,
- Plugin plugin) {
- Xml.Node *service_list_node = XMLUtils.get_element (device_element,
- "serviceList",
- null);
- if (service_list_node == null) {
- warning (_("XML node '%s' not found."), "/root/device/serviceList");
-
- return;
- }
-
- // Clear the existing service list first
- service_list_node->set_content ("");
-
+ private void add_services_to_desc (DescriptionFile file,
+ Plugin plugin) {
+ file.clear_service_list ();
foreach (ResourceInfo resource_info in plugin.resource_infos) {
// FIXME: We only support plugable services for now
if (resource_info.type.is_a (typeof (Service))) {
- this.add_service_to_desc (service_list_node,
- plugin.name,
- resource_info);
+ file.add_service (plugin.name, resource_info);
}
}
}
- private void add_service_to_desc (Xml.Node *service_list_node,
- string plugin_name,
- ResourceInfo resource_info) {
- // Now create the service node
- Xml.Node *service_node = service_list_node->new_child (null, "service");
-
- service_node->new_child (null, "serviceType", resource_info.upnp_type);
- service_node->new_child (null, "serviceId", resource_info.upnp_id);
-
- /* Now the relative (to base URL) URLs*/
- string url = "/" + resource_info.description_path;
- service_node->new_child (null, "SCPDURL", url);
-
- url = "/Event/" + plugin_name + "/" + resource_info.type.name ();
- service_node->new_child (null, "eventSubURL", url);
-
- url = "/Control/" + plugin_name + "/" + resource_info.type.name ();
- service_node->new_child (null, "controlURL", url);
- }
-
- private void add_icons_to_desc (Xml.Node *device_element,
- Plugin plugin) {
+ private void add_icons_to_desc (DescriptionFile file,
+ Plugin plugin) {
var icons = plugin.icon_infos;
if (icons == null || icons.size == 0) {
icons = plugin.default_icons;
}
- Xml.Node *icon_list_node = XMLUtils.get_element (device_element,
- "iconList",
- null);
- if (icon_list_node == null) {
- icon_list_node = device_element->new_child (null, "iconList", null);
- } else {
- // Clear the existing icon list first
- icon_list_node->set_content ("");
- }
-
+ file.clear_icon_list ();
foreach (var icon in icons) {
- add_icon_to_desc (icon_list_node, icon, plugin);
+ var remote_path = this.get_icon_remote_path (icon, plugin);
+ if (icon.uri.has_prefix ("file://")) {
+ var local_path = icon.uri.substring (7);
+ this.context.host_path (local_path, remote_path);
+ }
+
+ file.add_icon (plugin.name, icon, remote_path);
}
}
- private void add_icon_to_desc (Xml.Node *icon_list_node,
- IconInfo icon_info,
- Plugin plugin) {
- // Create the service node
- Xml.Node *icon_node = icon_list_node->new_child (null, "icon");
-
- string width = icon_info.width.to_string ();
- string height = icon_info.height.to_string ();
- string depth = icon_info.depth.to_string ();
-
- icon_node->new_child (null, "mimetype", icon_info.mime_type);
- icon_node->new_child (null, "width", width);
- icon_node->new_child (null, "height", height);
- icon_node->new_child (null, "depth", depth);
-
- var uri = icon_info.uri;
-
- if (uri.has_prefix ("file://")) {
+ private string get_icon_remote_path (IconInfo icon_info,
+ Plugin plugin) {
+ if (icon_info.uri.has_prefix ("file://")) {
// /PLUGIN_NAME-WIDTHxHEIGHTxDEPTH.png
- var remote_path = "/" + plugin.name + "-" +
- width + "x" +
- height + "x" +
- depth + "." + icon_info.file_extension;
- var local_path = uri.substring (7);
-
- this.context.host_path (local_path, remote_path);
- icon_node->new_child (null, "url", remote_path);
+ return "/" + plugin.name + "-" +
+ icon_info.width.to_string () + "x" +
+ icon_info.height.to_string () + "x" +
+ icon_info.depth.to_string () + "." +
+ icon_info.file_extension;
} else {
- uri = uri.replace ("@ADDRESS@", this.context.host_ip);
- icon_node->new_child (null, "url", uri);
+ var uri = icon_info.uri;
+ uri.replace ("@ADDRESS@", this.context.host_ip);
+ return uri;
}
}