[rygel] core: Refactor Search and Browse
- From: Zeeshan Ali Khattak <zeeshanak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rygel] core: Refactor Search and Browse
- Date: Thu, 22 Jul 2010 16:07:47 +0000 (UTC)
commit 67809c2296e8d14a899b340509c28edf916d0491
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date: Wed Jul 21 17:22:29 2010 +0300
core: Refactor Search and Browse
Move common code/logic between Search and Browse into a separate base
class: MediaQueryAction.
po/POTFILES.in | 1 +
src/rygel/Makefile.am | 1 +
src/rygel/rygel-browse.vala | 164 +++-----------------------
src/rygel/rygel-media-query-action.vala | 197 +++++++++++++++++++++++++++++++
src/rygel/rygel-search.vala | 149 +++---------------------
5 files changed, 231 insertions(+), 281 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0891c9c..7e33929 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -75,6 +75,7 @@ src/plugins/tracker/rygel-tracker-tags.vala
src/plugins/tracker/rygel-tracker-video-item-factory.vala
src/plugins/tracker/rygel-tracker-videos.vala
src/plugins/tracker/rygel-tracker-years.vala
+src/rygel/rygel-media-query-action.vala
src/rygel/rygel-browse.vala
src/rygel/rygel-cmdline-config.vala
src/rygel/rygel-configuration.vala
diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am
index 87a3633..9978ed3 100644
--- a/src/rygel/Makefile.am
+++ b/src/rygel/Makefile.am
@@ -78,6 +78,7 @@ VAPI_SOURCE_FILES = rygel-configuration.vala \
rygel-media-art-store.vala \
rygel-subtitle.vala \
rygel-subtitle-manager.vala \
+ rygel-media-query-action.vala \
rygel-browse.vala \
rygel-search.vala \
rygel-xbox-hacks.vala \
diff --git a/src/rygel/rygel-browse.vala b/src/rygel/rygel-browse.vala
index 33c9ab5..b89b428 100644
--- a/src/rygel/rygel-browse.vala
+++ b/src/rygel/rygel-browse.vala
@@ -31,83 +31,22 @@ using Soup;
* associated with the Browse action handling that exists to make asynchronous
* handling of Browse action possible.
*/
-internal class Rygel.Browse: GLib.Object, Rygel.StateMachine {
- // In arguments
- public string object_id;
- public string browse_flag;
- public string filter;
- public uint index; // Starting index
- public uint requested_count;
- public string sort_criteria;
-
- // Out arguments
- public uint number_returned;
- public uint total_matches;
- public uint update_id;
-
+internal class Rygel.Browse: Rygel.MediaQueryAction {
// The media object corresponding to object_id
private bool fetch_metadata;
- private MediaContainer root_container;
- private uint32 system_update_id;
- private ServiceAction action;
- private Rygel.DIDLLiteWriter didl_writer;
- private XBoxHacks xbox_hacks;
-
- public Cancellable cancellable { get; set; }
-
public Browse (ContentDirectory content_dir,
owned ServiceAction action) {
- this.root_container = content_dir.root_container;
- this.system_update_id = content_dir.system_update_id;
- this.cancellable = content_dir.cancellable;
- this.action = (owned) action;
-
- this.didl_writer = new Rygel.DIDLLiteWriter (content_dir.http_server);
-
- try {
- this.xbox_hacks = new XBoxHacks.for_action (this.action);
- } catch { /* This just means we are not dealing with Xbox, yay! */ }
+ base (content_dir,
+ action,
+ "ObjectID",
+ _("Failed to browse '%s': %s\n"));
}
- public async void run () {
- try {
- this.parse_args ();
-
- var media_object = yield this.fetch_media_object ();
-
- Gee.List<MediaObject> results;
- if (this.fetch_metadata) {
- // BrowseMetadata
- results = this.handle_metadata_request (media_object);
- } else {
- // BrowseDirectChildren
- results = yield this.handle_children_request (media_object);
- }
-
- foreach (var result in results) {
- if (result is MediaItem && this.xbox_hacks != null) {
- this.xbox_hacks.apply (result as MediaItem);
- }
-
- this.didl_writer.serialize (result);
- }
-
- // Conclude the successful Browse action
- this.conclude ();
- } catch (Error err) {
- this.handle_error (err);
- }
- }
+ protected override void parse_args () throws Error {
+ base.parse_args ();
- private async void parse_args () throws Error {
- /* Start by parsing the 'in' arguments */
- this.action.get ("ObjectID", typeof (string), out this.object_id,
- "BrowseFlag", typeof (string), out this.browse_flag,
- "Filter", typeof (string), out this.filter,
- "StartingIndex", typeof (uint), out this.index,
- "RequestedCount", typeof (uint), out this.requested_count,
- "SortCriteria", typeof (string), out this.sort_criteria);
+ this.action.get ("BrowseFlag", typeof (string), out this.browse_flag);
/* BrowseFlag */
if (this.browse_flag != null &&
@@ -120,56 +59,22 @@ internal class Rygel.Browse: GLib.Object, Rygel.StateMachine {
throw new ContentDirectoryError.INVALID_ARGS (
_("Invalid Arguments"));
}
-
- /* ObjectID */
- if (this.object_id == null) {
- /* Stupid Xbox */
- this.action.get ("ContainerID",
- typeof (string),
- out this.object_id);
- // Map some special browse requests to browse on the root folder
- if (this.object_id == "15" ||
- this.object_id == "14" ||
- this.object_id == "16") {
- this.object_id = "0";
- }
- }
-
- if (this.object_id == null) {
- // Sorry we can't do anything without ObjectID
- throw new ContentDirectoryError.NO_SUCH_OBJECT (
- _("No such object"));
- }
}
- private async MediaObject fetch_media_object () throws Error {
- if (this.object_id == this.root_container.id) {
- return this.root_container;
+ protected override async Gee.List<MediaObject> fetch_results (
+ MediaObject media_object) throws Error {
+ if (this.fetch_metadata) {
+ // BrowseMetadata
+ return this.handle_metadata_request (media_object);
} else {
- debug ("searching for object '%s'..", this.object_id);
- var media_object = yield this.root_container.find_object (
- this.object_id,
- this.cancellable);
- if (media_object == null) {
- throw new ContentDirectoryError.NO_SUCH_OBJECT (
- _("No such object"));
- }
- debug ("object '%s' found.", this.object_id);
-
- return media_object;
+ // BrowseDirectChildren
+ return yield this.handle_children_request (media_object);
}
}
private Gee.List<MediaObject> handle_metadata_request (
MediaObject media_object)
throws Error {
- if (media_object is MediaContainer) {
- this.update_id = ((MediaContainer) media_object).update_id;
- } else {
- this.update_id = uint32.MAX;
- }
-
- this.number_returned = 1;
this.total_matches = 1;
var results = new ArrayList<MediaObject> ();
@@ -188,7 +93,6 @@ internal class Rygel.Browse: GLib.Object, Rygel.StateMachine {
var container = (MediaContainer) media_object;
this.total_matches = container.child_count;
- this.update_id = container.update_id;
if (this.requested_count == 0) {
// No max count requested, try to fetch all children
@@ -202,7 +106,6 @@ internal class Rygel.Browse: GLib.Object, Rygel.StateMachine {
var children = yield container.get_children (this.index,
this.requested_count,
this.cancellable);
- this.number_returned = children.size;
debug ("Fetched %u children of container '%s' from index %u.",
this.requested_count,
this.object_id,
@@ -210,42 +113,5 @@ internal class Rygel.Browse: GLib.Object, Rygel.StateMachine {
return children;
}
-
- private void conclude () {
- // Apply the filter from the client
- this.didl_writer.filter (this.filter);
-
- /* Retrieve generated string */
- string didl = this.didl_writer.get_string ();
-
- if (this.update_id == uint32.MAX) {
- this.update_id = this.system_update_id;
- }
-
- /* Set action return arguments */
- this.action.set ("Result", typeof (string), didl,
- "NumberReturned", typeof (uint), this.number_returned,
- "TotalMatches", typeof (uint), this.total_matches,
- "UpdateID", typeof (uint), this.update_id);
-
- this.action.return ();
- this.completed ();
- }
-
- private void handle_error (Error error) {
- if (error is ContentDirectoryError) {
- warning (_("Failed to browse '%s': %s\n"),
- this.object_id,
- error.message);
- this.action.return_error (error.code, error.message);
- } else {
- warning (_("Failed to browse '%s': %s\n"),
- this.object_id,
- error.message);
- this.action.return_error (701, error.message);
- }
-
- this.completed ();
- }
}
diff --git a/src/rygel/rygel-media-query-action.vala b/src/rygel/rygel-media-query-action.vala
new file mode 100644
index 0000000..266950c
--- /dev/null
+++ b/src/rygel/rygel-media-query-action.vala
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali <zeenix gmail 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 Gee;
+
+/**
+ * Base class of Browse and Search actions.
+ */
+internal abstract class Rygel.MediaQueryAction : GLib.Object, StateMachine {
+ // In arguments
+ public string object_id;
+ public string browse_flag;
+ public string filter;
+ public uint index; // Starting index
+ public uint requested_count;
+ public string sort_criteria;
+
+ // Out arguments
+ public uint number_returned;
+ public uint total_matches;
+ public uint update_id;
+
+ public Cancellable cancellable { get; set; }
+
+ protected MediaContainer root_container;
+ protected uint32 system_update_id;
+ protected ServiceAction action;
+ protected Rygel.DIDLLiteWriter didl_writer;
+ protected XBoxHacks xbox_hacks;
+
+ private string object_id_arg;
+ private string error_message;
+
+ protected MediaQueryAction (ContentDirectory content_dir,
+ owned ServiceAction action,
+ string object_id_arg,
+ string error_message) {
+ this.root_container = content_dir.root_container;
+ this.system_update_id = content_dir.system_update_id;
+ this.cancellable = content_dir.cancellable;
+ this.action = (owned) action;
+ this.object_id_arg = object_id_arg;
+ this.error_message = error_message;
+
+ this.didl_writer = new Rygel.DIDLLiteWriter (content_dir.http_server);
+
+ try {
+ this.xbox_hacks = new XBoxHacks.for_action (this.action);
+ } catch { /* This just means we are not dealing with Xbox, yay! */ }
+ }
+
+ public async void run () {
+ try {
+ this.parse_args ();
+
+ var media_object = yield this.fetch_media_object ();
+ var results = yield this.fetch_results (media_object);
+
+ this.number_returned = results.size;
+ if (media_object is MediaContainer) {
+ this.update_id = ((MediaContainer) media_object).update_id;
+ } else {
+ this.update_id = uint32.MAX;
+ }
+
+ foreach (var result in results) {
+ if (result is MediaItem && this.xbox_hacks != null) {
+ this.xbox_hacks.apply (result as MediaItem);
+ }
+
+ this.didl_writer.serialize (result);
+ }
+
+ // Conclude the successful Browse/Search action
+ this.conclude ();
+ } catch (Error err) {
+ this.handle_error (err);
+ }
+ }
+
+ protected virtual void parse_args () throws Error {
+ this.action.get (this.object_id_arg,
+ typeof (string),
+ out this.object_id,
+ "Filter",
+ typeof (string),
+ out this.filter,
+ "StartingIndex",
+ typeof (uint),
+ out this.index,
+ "RequestedCount",
+ typeof (uint),
+ out this.requested_count,
+ "SortCriteria",
+ typeof (string),
+ out this.sort_criteria);
+
+ if (this.object_id == null) {
+ /* Stupid Xbox */
+ this.action.get ("ContainerID",
+ typeof (string),
+ out this.object_id);
+ }
+
+ if (this.object_id == null) {
+ // Sorry we can't do anything without ObjectID
+ throw new ContentDirectoryError.NO_SUCH_OBJECT (
+ _("No such object"));
+ }
+
+ if (this.xbox_hacks != null) {
+ this.xbox_hacks.translate_container_id (ref this.object_id);
+ }
+ }
+
+ protected abstract async Gee.List<MediaObject> fetch_results (
+ MediaObject media_object) throws Error;
+
+ private async MediaObject fetch_media_object () throws Error {
+ if (this.object_id == this.root_container.id) {
+ return this.root_container;
+ } else {
+ debug ("searching for object '%s'..", this.object_id);
+ var media_object = yield this.root_container.find_object (
+ this.object_id,
+ this.cancellable);
+ if (media_object == null) {
+ throw new ContentDirectoryError.NO_SUCH_OBJECT (
+ _("No such object"));
+ }
+ debug ("object '%s' found.", this.object_id);
+
+ return media_object;
+ }
+ }
+
+ private void conclude () {
+ // Apply the filter from the client
+ this.didl_writer.filter (this.filter);
+
+ /* Retrieve generated string */
+ string didl = this.didl_writer.get_string ();
+
+ if (this.update_id == uint32.MAX) {
+ this.update_id = this.system_update_id;
+ }
+
+ /* Set action return arguments */
+ this.action.set ("Result",
+ typeof (string),
+ didl,
+ "NumberReturned",
+ typeof (uint),
+ this.number_returned,
+ "TotalMatches",
+ typeof (uint),
+ this.total_matches,
+ "UpdateID",
+ typeof (uint),
+ this.update_id);
+
+ this.action.return ();
+ this.completed ();
+ }
+
+ private void handle_error (Error error) {
+ warning (this.error_message, this.object_id, error.message);
+
+ if (error is ContentDirectoryError) {
+ this.action.return_error (error.code, error.message);
+ } else {
+ this.action.return_error (701, error.message);
+ }
+
+ this.completed ();
+ }
+}
diff --git a/src/rygel/rygel-search.vala b/src/rygel/rygel-search.vala
index 10eeae8..e05b780 100644
--- a/src/rygel/rygel-search.vala
+++ b/src/rygel/rygel-search.vala
@@ -28,114 +28,36 @@ using Soup;
/**
* Search action implementation.
*/
-internal class Rygel.Search: GLib.Object, Rygel.StateMachine {
+internal class Rygel.Search: Rygel.MediaQueryAction {
// In arguments
- public string container_id;
public string search_criteria;
- public string filter;
- public uint index; // Starting index
- public uint requested_count;
- public string sort_criteria;
-
- // Out arguments
- public uint number_returned;
- public uint total_matches;
- public uint update_id;
-
- private MediaContainer root_container;
- private uint32 system_update_id;
- private ServiceAction action;
- private Rygel.DIDLLiteWriter didl_writer;
- private XBoxHacks xbox_hacks;
-
- public Cancellable cancellable { get; set; }
public Search (ContentDirectory content_dir,
owned ServiceAction action) {
- this.root_container = content_dir.root_container;
- this.system_update_id = content_dir.system_update_id;
- this.cancellable = content_dir.cancellable;
- this.action = (owned) action;
-
- this.didl_writer = new Rygel.DIDLLiteWriter (content_dir.http_server);
-
- try {
- this.xbox_hacks = new XBoxHacks.for_action (this.action);
- } catch { /* This just means we are not dealing with Xbox, yay! */ }
+ base (content_dir,
+ action,
+ "ContainerID",
+ _("Failed to search in '%s': %s"));
}
- public async void run () {
- // Start by parsing the 'in' arguments
- this.action.get ("ContainerID",
- typeof (string),
- out this.container_id,
- "SearchCriteria",
- typeof (string),
- out this.search_criteria,
- "Filter",
- typeof (string),
- out this.filter,
- "StartingIndex",
- typeof (uint),
- out this.index,
- "RequestedCount",
- typeof (uint),
- out this.requested_count,
- "SortCriteria",
- typeof (string),
- out this.sort_criteria);
+ protected override void parse_args () throws Error {
+ base.parse_args ();
- try {
- if (this.container_id == null || this.search_criteria == null) {
- // Sorry we can't do anything without these two parameters
- throw new ContentDirectoryError.NO_SUCH_OBJECT (
- _("No such container"));
- }
-
- debug (_("Executing search request: %s"), this.search_criteria);
-
- if (this.xbox_hacks != null) {
- this.xbox_hacks.translate_container_id (ref this.container_id);
- }
-
- var container = yield this.fetch_container ();
- var results = yield this.fetch_results (container);
-
- // Serialize results
- foreach (var result in results) {
- if (result is MediaItem && this.xbox_hacks != null) {
- this.xbox_hacks.apply (result as MediaItem);
- }
-
- this.didl_writer.serialize (result);
- }
-
- this.conclude ();
- } catch (Error err) {
- this.handle_error (err);
- }
- }
-
- private async MediaContainer fetch_container () throws Error {
- if (this.container_id == this.root_container.id) {
- return this.root_container;
- }
+ this.action.get ("SearchCriteria",
+ typeof (string),
+ out this.search_criteria);
- var media_object = yield this.root_container.find_object (
- this.container_id,
- this.cancellable);
- if (media_object == null || !(media_object is MediaContainer)) {
- throw new ContentDirectoryError.NO_SUCH_OBJECT (
- _("Specified container does not exist."));
+ if (this.search_criteria == null) {
+ throw new ContentDirectoryError.INVALID_ARGS (
+ "No search criteria given");
}
- return media_object as MediaContainer;
+ debug (_("Executing search request: %s"), this.search_criteria);
}
- private async Gee.List<MediaObject> fetch_results (
- MediaContainer container)
- throws Error {
- this.update_id = container.update_id;
+ protected override async Gee.List<MediaObject> fetch_results (
+ MediaObject media_object) throws Error {
+ var container = media_object as MediaContainer;
var parser = new Rygel.SearchCriteriaParser (this.search_criteria);
yield parser.run ();
@@ -155,44 +77,7 @@ internal class Rygel.Search: GLib.Object, Rygel.StateMachine {
throw new ContentDirectoryError.CANT_PROCESS (message);
}
- this.number_returned = results.size;
-
return results;
}
-
- private void conclude () {
- // Apply the filter from the client
- this.didl_writer.filter (this.filter);
-
- // Retrieve generated string
- string didl = this.didl_writer.get_string ();
-
- if (this.update_id == uint32.MAX) {
- this.update_id = this.system_update_id;
- }
-
- // Set action return arguments
- this.action.set ("Result", typeof (string), didl,
- "NumberReturned", typeof (uint), this.number_returned,
- "TotalMatches", typeof (uint), this.total_matches,
- "UpdateID", typeof (uint), this.update_id);
-
- this.action.return ();
- this.completed ();
- }
-
- private void handle_error (Error error) {
- warning (_("Failed to search in '%s': %s"),
- this.container_id,
- error.message);
-
- if (error is ContentDirectoryError) {
- this.action.return_error (error.code, error.message);
- } else {
- this.action.return_error (701, error.message);
- }
-
- this.completed ();
- }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]