[rygel] core: Dummy Search implementation



commit 2d266a90cae00dfa506298af3cdf5207b70ab56e
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Thu Oct 29 02:46:50 2009 +0200

    core: Dummy Search implementation
    
    Right now it just parses the 'in' arguments and provides an empty list
    as the result.

 src/rygel/Makefile.am                  |    1 +
 src/rygel/rygel-content-directory.vala |    9 ++
 src/rygel/rygel-search.vala            |  168 ++++++++++++++++++++++++++++++++
 3 files changed, 178 insertions(+), 0 deletions(-)
---
diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am
index 30de752..108f7f6 100644
--- a/src/rygel/Makefile.am
+++ b/src/rygel/Makefile.am
@@ -71,6 +71,7 @@ VAPI_SOURCE_FILES = rygel-configuration.vala \
 		    rygel-thumbnail.vala \
 		    rygel-thumbnailer.vala \
 		    rygel-browse.vala \
+		    rygel-search.vala \
 		    rygel-didl-lite-writer.vala \
 		    rygel-transcoder.vala \
 		    rygel-mp2ts-transcoder.vala \
diff --git a/src/rygel/rygel-content-directory.vala b/src/rygel/rygel-content-directory.vala
index 5fe230d..6f9b5cc 100644
--- a/src/rygel/rygel-content-directory.vala
+++ b/src/rygel/rygel-content-directory.vala
@@ -95,6 +95,7 @@ public class Rygel.ContentDirectory: Service {
         this.sort_caps = "";
 
         this.action_invoked["Browse"] += this.browse_cb;
+        this.action_invoked["Search"] += this.search_cb;
 
         /* Connect SystemUpdateID related signals */
         this.action_invoked["GetSystemUpdateID"] +=
@@ -135,6 +136,14 @@ public class Rygel.ContentDirectory: Service {
         browse.run.begin ();
     }
 
+    /* Search action implementation */
+    private virtual void search_cb (ContentDirectory    content_dir,
+                                    owned ServiceAction action) {
+        var search = new Search (this, action);
+
+        search.run.begin ();
+    }
+
     /* GetSystemUpdateID action implementation */
     private void get_system_update_id_cb (ContentDirectory    content_dir,
                                           owned ServiceAction action) {
diff --git a/src/rygel/rygel-search.vala b/src/rygel/rygel-search.vala
new file mode 100644
index 0000000..900a3c4
--- /dev/null
+++ b/src/rygel/rygel-search.vala
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2008 Nokia Corporation.
+ * Copyright (C) 2008 Zeeshan Ali (Khattak) <zeeshanak gnome org>.
+ *
+ * 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 GUPnP;
+using Gee;
+using Soup;
+
+/**
+ * Search action implementation.
+ */
+internal class Rygel.Search: GLib.Object, Rygel.StateMachine {
+    // 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;
+
+    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);
+    }
+
+    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);
+
+        try {
+            if (this.container_id == null) {
+                // Sorry we can't do anything without ContainerID
+                throw new ContentDirectoryError.NO_SUCH_OBJECT (
+                                        "No such container");
+            }
+
+            var container = yield this.fetch_container ();
+            var results = yield this.fetch_results (container);
+
+            // Serialize results
+            foreach (var result in results) {
+                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;
+        }
+
+        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.");
+        }
+
+        return media_object as MediaContainer;
+    }
+
+    private async ArrayList<MediaObject> fetch_results (
+                                        MediaContainer container) throws Error {
+        this.update_id = container.update_id;
+
+        var results = new ArrayList<MediaObject> ();
+        this.number_returned = this.total_matches = 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) {
+        if (error is ContentDirectoryError) {
+            warning ("Failed to search in '%s': %s\n",
+                     this.container_id,
+                     error.message);
+            this.action.return_error (error.code, error.message);
+        } else {
+            warning ("Failed to browse '%s': %s\n",
+                     this.container_id,
+                     error.message);
+            this.action.return_error (701, error.message);
+        }
+
+        this.completed ();
+    }
+}
+



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