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 \
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";
}
--- /dev/null
+/*
+ * 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"));
+ }
+ }
+}
}
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;
return;
}
- } catch (XBoxHacksError error) {}
+ } catch (ClientHacksError error) {}
if (this.uri.thumbnail_index >= 0) {
if (this.item is MusicItem) {
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);
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,
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 () {
results.serialize (this.didl_writer,
this.http_server,
- this.xbox_hacks);
+ this.hacks);
// Conclude the successful Browse/Search action
this.conclude ();
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);
}
}
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,
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";
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)) {
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" ||
}
}
- 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") {
}
}
- 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,