~ubuntu-branches/ubuntu/quantal/zeitgeist/quantal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/* fts.vala
 *
 * Copyright © 2011 Seif Lotfy <seif@lotfy.com>
 * Copyright © 2011 Canonical Ltd.
 *             By Michal Hruby <michal.hruby@canonical.com>
 *
 * This program 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.1 of the License, or
 * (at your option) any later version.
 *
 * This program 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 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, see <http://www.gnu.org/licenses/>.
 *
 */

namespace Zeitgeist
{
    [DBus (name = "org.gnome.zeitgeist.Index")]
    public interface RemoteSearchEngine: Object
    {
        [DBus (signature = "a(asaasay)u")]
        public abstract async Variant search (
            string query_string,
            [DBus (signature = "(xx)")] Variant time_range,
            [DBus (signature = "a(asaasay)")] Variant filter_templates,
            uint offset, uint count, uint result_type,
            [DBus (signature = "a(asaasay)")] out Variant events) throws Error;
    }

    /* Because of a Vala bug we have to define the proxy interface outside of
     * [ModuleInit] source */
    /*
    [DBus (name = "org.gnome.zeitgeist.SimpleIndexer")]
    public interface RemoteSimpleIndexer : Object
    {
        [DBus (signature = "a(asaasay)u")]
        public abstract async Variant search (
            string query_string,
            [DBus (signature = "(xx)")] Variant time_range,
            [DBus (signature = "a(asaasay)")] Variant filter_templates,
            uint offset, uint count, uint result_type) throws Error;
    }
    */

    class SearchEngine: Extension, RemoteSearchEngine
    {

        private RemoteSimpleIndexer siin;
        private uint registration_id;

        SearchEngine ()
        {
            Object ();
        }

        construct
        {
            try
            {
                var connection = Bus.get_sync (BusType.SESSION, null);
                registration_id = connection.register_object<RemoteSearchEngine> (
                    "/org/gnome/zeitgeist/index/activity", this);

                // FIXME: shouldn't we delay this to next idle callback?
                // Get SimpleIndexer
                Bus.watch_name_on_connection (connection,
                    "org.gnome.zeitgeist.SimpleIndexer",
                    BusNameWatcherFlags.AUTO_START,
                    (conn) =>
                    {
                        if (siin != null) return;
                        conn.get_proxy.begin<RemoteSimpleIndexer> (
                            "org.gnome.zeitgeist.SimpleIndexer",
                            "/org/gnome/zeitgeist/index/activity",
                            0, null, this.proxy_acquired);
                    },
                    () => {});
            }
            catch (Error err)
            {
                warning ("%s", err.message);
            }
        }

        private void proxy_acquired (Object? obj, AsyncResult res)
        {
            var conn = obj as DBusConnection;
            try
            {
                siin = conn.get_proxy.end<RemoteSimpleIndexer> (res);
            }
            catch (IOError err)
            {
                warning ("%s", err.message);
            }
        }

        /* This whole method is one huge workaround for an issue with Vala
         * enclosing all out/return parameters in a TUPLE variant */
        public async Variant search (string query_string, Variant time_range,
            Variant filter_templates, uint offset, uint count, uint result_type,
            out Variant events) throws Error
        {
            debug ("Performing search for %s", query_string);
            if (siin == null || !(siin is DBusProxy))
            {
                // FIXME: queue until we have the proxy
                throw new EngineError.DATABASE_ERROR (
                    "Not connected to SimpleIndexer");
            }
            var timer = new Timer ();
            DBusProxy proxy = (DBusProxy) siin;
            var b = new VariantBuilder (new VariantType ("(s(xx)a(asaasay)uuu)"));
            b.add ("s", query_string);
            b.add_value (time_range);
            b.add_value (filter_templates);
            b.add ("u", offset);
            b.add ("u", count);
            b.add ("u", result_type);
            var result = yield proxy.call ("Search", b.end (), 0, -1, null);
            events = result.get_child_value (0);
            /* FIXME: this somehow doesn't work :(
             *   but it's fixable in a similar way as this method's signature
             *   is done */
            /*
            var result = yield siin.search (query_string, time_range,
                filter_templates, offset, count, result_type);
            */
            debug ("Got %u results from indexer (in %f seconds)",
                (uint) events.n_children (), timer.elapsed ());
            return result.get_child_value (1);
        }

    }

    [ModuleInit]
#if BUILTIN_EXTENSIONS
    public static Type fts_init (TypeModule module)
    {
#else
    public static Type extension_register (TypeModule module)
    {
#endif
        return typeof (SearchEngine);
    }
}

// vim:expandtab:ts=4:sw=4