[rygel] core: Add base class for client hacks
- From: Jens Georg <jensgeorg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel] core: Add base class for client hacks
- Date: Wed, 19 Oct 2011 07:30:00 +0000 (UTC)
commit 2d7ce8a4f421572f8c570c9146e774e49d655e7b
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date: Mon Oct 17 01:12:49 2011 +0300
core: Add base class for client hacks
A new abstract base class for client-side hacks from which XBoxHacks
derives.
https://bugzilla.gnome.org/show_bug.cgi?id=661336
src/rygel/Makefile.am | 1 +
src/rygel/rygel-browse.vala | 4 +-
src/rygel/rygel-client-hacks.vala | 106 +++++++++++++++++++++++++++++++
src/rygel/rygel-http-get.vala | 5 +-
src/rygel/rygel-media-objects.vala | 6 +-
src/rygel/rygel-media-query-action.vala | 12 ++--
src/rygel/rygel-search.vala | 14 ++--
src/rygel/rygel-xbox-hacks.vala | 70 +++++++--------------
8 files changed, 151 insertions(+), 67 deletions(-)
---
diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am
index aec85e1..2ae265e 100644
--- a/src/rygel/Makefile.am
+++ b/src/rygel/Makefile.am
@@ -83,6 +83,7 @@ VAPI_SOURCE_FILES = \
rygel-media-query-action.vala \
rygel-browse.vala \
rygel-search.vala \
+ rygel-client-hacks.vala \
rygel-xbox-hacks.vala \
rygel-import-resource.vala \
rygel-item-creator.vala \
diff --git a/src/rygel/rygel-browse.vala b/src/rygel/rygel-browse.vala
index b45f5d0..2682cbf 100644
--- a/src/rygel/rygel-browse.vala
+++ b/src/rygel/rygel-browse.vala
@@ -39,8 +39,8 @@ internal class Rygel.Browse: Rygel.MediaQueryAction {
owned ServiceAction action) {
base (content_dir, action);
- if (this.xbox_hacks != null) {
- this.object_id_arg = this.xbox_hacks.object_id;
+ if (this.hacks != null) {
+ this.object_id_arg = this.hacks.object_id;
} else {
this.object_id_arg = "ObjectID";
}
diff --git a/src/rygel/rygel-client-hacks.vala b/src/rygel/rygel-client-hacks.vala
new file mode 100644
index 0000000..ae7c725
--- /dev/null
+++ b/src/rygel/rygel-client-hacks.vala
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2011 Red Hat, Inc.
+ * Copyright (C) 2010 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ *
+ * 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;
+
+internal errordomain Rygel.ClientHacksError {
+ NA
+}
+
+internal abstract class Rygel.ClientHacks : GLib.Object {
+ private static string OBJECT_ID = "ObjectID";
+
+ public unowned string object_id { get; protected set; }
+
+ protected Regex agent_regex;
+
+ public static ClientHacks create_for_action (ServiceAction action)
+ throws ClientHacksError {
+ return new XBoxHacks.for_action (action);
+ }
+
+ public static ClientHacks create_for_headers (MessageHeaders headers)
+ throws ClientHacksError {
+ return new XBoxHacks.for_headers (headers);
+ }
+
+ protected ClientHacks (string agent_pattern, MessageHeaders? headers = null)
+ throws ClientHacksError {
+ try {
+ this.agent_regex = new Regex (agent_pattern,
+ RegexCompileFlags.CASELESS,
+ 0);
+ } catch (RegexError error) {
+ // This means subclasses did not provide a proper regular expression
+ assert_not_reached ();
+ }
+
+ if (headers != null) {
+ this.check_headers (headers);
+ }
+
+ this.object_id = OBJECT_ID;
+ }
+
+ public bool is_album_art_request (Soup.Message message) {
+ unowned string query = message.get_uri ().query;
+
+ if (query == null) {
+ return false;
+ }
+
+ var params = Soup.Form.decode (query);
+ var album_art = params.lookup ("albumArt");
+
+ return (album_art != null) && bool.parse (album_art);
+ }
+
+ public virtual void translate_container_id (MediaQueryAction action,
+ ref string container_id) {}
+
+ public virtual void apply (MediaItem item) {}
+
+ public virtual async MediaObjects? search
+ (SearchableContainer container,
+ SearchExpression? expression,
+ uint offset,
+ uint max_count,
+ out uint total_matches,
+ Cancellable? cancellable)
+ throws Error {
+ return yield container.search (expression,
+ offset,
+ max_count,
+ out total_matches,
+ cancellable);
+ }
+
+ private void check_headers (MessageHeaders headers)
+ throws ClientHacksError {
+ var agent = headers.get_one ("User-Agent");
+ if (agent == null || !(this.agent_regex.match (agent))) {
+ throw new ClientHacksError.NA (_("Not Applicable"));
+ }
+ }
+}
diff --git a/src/rygel/rygel-http-get.vala b/src/rygel/rygel-http-get.vala
index 0ea407c..c830483 100644
--- a/src/rygel/rygel-http-get.vala
+++ b/src/rygel/rygel-http-get.vala
@@ -84,7 +84,8 @@ internal class Rygel.HTTPGet : HTTPRequest {
}
try {
- var hack = new XBoxHacks.for_headers (this.msg.request_headers);
+ var hack = ClientHacks.create_for_headers
+ (this.msg.request_headers);
if (hack.is_album_art_request (this.msg) &&
this.item is VisualItem) {
var visual_item = this.item as VisualItem;
@@ -100,7 +101,7 @@ internal class Rygel.HTTPGet : HTTPRequest {
return;
}
- } catch (XBoxHacksError error) {}
+ } catch (ClientHacksError error) {}
if (this.uri.thumbnail_index >= 0) {
if (this.item is MusicItem) {
diff --git a/src/rygel/rygel-media-objects.vala b/src/rygel/rygel-media-objects.vala
index 40fb535..9cf657c 100644
--- a/src/rygel/rygel-media-objects.vala
+++ b/src/rygel/rygel-media-objects.vala
@@ -56,10 +56,10 @@ public class Rygel.MediaObjects : ArrayList<MediaObject> {
internal void serialize (DIDLLiteWriter didl_writer,
HTTPServer http_server,
- XBoxHacks? xbox_hacks) throws Error {
+ ClientHacks? hacks) throws Error {
foreach (var result in this) {
- if (result is MediaItem && xbox_hacks != null) {
- xbox_hacks.apply (result as MediaItem);
+ if (result is MediaItem && hacks != null) {
+ hacks.apply (result as MediaItem);
}
result.serialize (didl_writer, http_server);
diff --git a/src/rygel/rygel-media-query-action.vala b/src/rygel/rygel-media-query-action.vala
index 5a615a8..1db1236 100644
--- a/src/rygel/rygel-media-query-action.vala
+++ b/src/rygel/rygel-media-query-action.vala
@@ -49,7 +49,7 @@ internal abstract class Rygel.MediaQueryAction : GLib.Object, StateMachine {
protected uint32 system_update_id;
protected ServiceAction action;
protected DIDLLiteWriter didl_writer;
- protected XBoxHacks xbox_hacks;
+ protected ClientHacks hacks;
protected string object_id_arg;
protected MediaQueryAction (ContentDirectory content_dir,
@@ -63,8 +63,8 @@ internal abstract class Rygel.MediaQueryAction : GLib.Object, StateMachine {
this.didl_writer = new DIDLLiteWriter (null);
try {
- this.xbox_hacks = new XBoxHacks.for_action (this.action);
- } catch { /* This just means we are not dealing with Xbox, yay! */ }
+ this.hacks = ClientHacks.create_for_action (this.action);
+ } catch { /* This just means we need no hacks, yay! */ }
}
public async void run () {
@@ -85,7 +85,7 @@ internal abstract class Rygel.MediaQueryAction : GLib.Object, StateMachine {
results.serialize (this.didl_writer,
this.http_server,
- this.xbox_hacks);
+ this.hacks);
// Conclude the successful Browse/Search action
this.conclude ();
@@ -132,8 +132,8 @@ internal abstract class Rygel.MediaQueryAction : GLib.Object, StateMachine {
this.validate_sort_criteria ();
- if (this.xbox_hacks != null) {
- this.xbox_hacks.translate_container_id (this, ref this.object_id);
+ if (this.hacks != null) {
+ this.hacks.translate_container_id (this, ref this.object_id);
}
}
diff --git a/src/rygel/rygel-search.vala b/src/rygel/rygel-search.vala
index dd5231e..1d5e66a 100644
--- a/src/rygel/rygel-search.vala
+++ b/src/rygel/rygel-search.vala
@@ -69,13 +69,13 @@ internal class Rygel.Search: Rygel.MediaQueryAction {
throw parser.err;
}
- if (this.xbox_hacks != null) {
- return yield this.xbox_hacks.search (container,
- parser.expression,
- this.index,
- this.requested_count,
- out this.total_matches,
- this.cancellable);
+ if (this.hacks != null) {
+ return yield this.hacks.search (container,
+ parser.expression,
+ this.index,
+ this.requested_count,
+ out this.total_matches,
+ this.cancellable);
} else {
return yield container.search (parser.expression,
this.index,
diff --git a/src/rygel/rygel-xbox-hacks.vala b/src/rygel/rygel-xbox-hacks.vala
index 9407321..2d61326 100644
--- a/src/rygel/rygel-xbox-hacks.vala
+++ b/src/rygel/rygel-xbox-hacks.vala
@@ -24,11 +24,7 @@
using Soup;
using GUPnP;
-internal errordomain Rygel.XBoxHacksError {
- NA
-}
-
-internal class Rygel.XBoxHacks : GLib.Object {
+internal class Rygel.XBoxHacks : ClientHacks {
private static string AGENT =
".*Xbox.*|.*Allegro-Software-WebClient.*|.*SEC_HHP_Galaxy S/1\\.0.*";
private static string DMS = "urn:schemas-upnp-org:device:MediaServer";
@@ -37,49 +33,26 @@ internal class Rygel.XBoxHacks : GLib.Object {
private static string MODEL_NAME = "Windows Media Player Sharing";
private static string MODEL_VERSION = "11";
private static string CONTAINER_ID = "ContainerID";
- private static string OBJECT_ID = "ObjectID";
- public unowned string object_id { get; private set; }
+ public XBoxHacks () throws ClientHacksError {
+ base (AGENT);
+ }
- public XBoxHacks.for_action (ServiceAction action) throws XBoxHacksError {
+ public XBoxHacks.for_action (ServiceAction action) throws ClientHacksError {
unowned MessageHeaders headers = action.get_message ().request_headers;
- this.check_headers (headers);
+ this.for_headers (headers);
}
public XBoxHacks.for_headers (MessageHeaders headers)
- throws XBoxHacksError {
- this.check_headers (headers);
- }
+ throws ClientHacksError {
+ base (AGENT, headers);
- private void check_headers (MessageHeaders headers) throws XBoxHacksError {
var agent = headers.get_one ("User-Agent");
- if (agent == null ||
- !(agent.contains ("Xbox")) &&
- !(agent.contains ("Allegro-Software-WebClient")) &&
- !(agent.contains ("SEC_HHP_Galaxy S/1.0"))) {
- throw new XBoxHacksError.NA (_("Not Applicable"));
- }
-
if (agent.contains ("Xbox")) {
this.object_id = CONTAINER_ID;
- } else {
- this.object_id = OBJECT_ID;
}
}
- public bool is_album_art_request (Soup.Message message) {
- unowned string query = message.get_uri ().query;
-
- if (query == null) {
- return false;
- }
-
- var params = Soup.Form.decode (query);
- var album_art = params.lookup ("albumArt");
-
- return (album_art != null) && bool.parse (album_art);
- }
-
public void apply_on_device (RootDevice device,
string template_path) throws Error {
if (!device.get_device_type ().has_prefix (DMS)) {
@@ -92,13 +65,15 @@ internal class Rygel.XBoxHacks : GLib.Object {
var desc_path = template_path.replace (".xml", "-xbox.xml");
this.save_modified_desc (doc, desc_path);
- var regex = new Regex (AGENT, RegexCompileFlags.CASELESS, 0);
var server_path = "/" + device.get_relative_location ();
- device.context.host_path_for_agent (desc_path, server_path, regex);
+ device.context.host_path_for_agent (desc_path,
+ server_path,
+ this.agent_regex);
}
- public void translate_container_id (MediaQueryAction action,
- ref string container_id) {
+ public override void translate_container_id
+ (MediaQueryAction action,
+ ref string container_id) {
if (action is Search &&
(container_id == "1" ||
container_id == "4" ||
@@ -114,7 +89,7 @@ internal class Rygel.XBoxHacks : GLib.Object {
}
}
- public void apply (MediaItem item) {
+ public override void apply (MediaItem item) {
if (item.mime_type == "video/x-msvideo") {
item.mime_type = "video/avi";
} else if (item.mime_type == "video/mpeg") {
@@ -123,13 +98,14 @@ internal class Rygel.XBoxHacks : GLib.Object {
}
}
- public async MediaObjects? search (SearchableContainer container,
- SearchExpression? expression,
- uint offset,
- uint max_count,
- out uint total_matches,
- Cancellable? cancellable)
- throws Error {
+ public override async MediaObjects? search
+ (SearchableContainer container,
+ SearchExpression? expression,
+ uint offset,
+ uint max_count,
+ out uint total_matches,
+ Cancellable? cancellable)
+ throws Error {
var results = yield container.search (expression,
offset,
max_count,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]