~elementary-apps/slingshot/synapse-desktop-only

« back to all changes in this revision

Viewing changes to lib/synapse-plugins/locate-plugin.vala

  • Committer: Tom Beckmann
  • Date: 2014-06-12 09:14:57 UTC
  • Revision ID: tomjonabc@gmail.com-20140612091457-1spb2qtytxybnvkg
Remove all plugins but desktop-file and command one, fix code style

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2010 Michal Hruby <michal.mhr@gmail.com>
3
 
 *
4
 
 * This program is free software; you can redistribute it and/or modify
5
 
 * it under the terms of the GNU General Public License as published by
6
 
 * the Free Software Foundation; either version 2 of the License, or
7
 
 * (at your option) any later version.
8
 
 *
9
 
 * This program is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
 * GNU General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU General Public License
15
 
 * along with this program; if not, write to the Free Software
16
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
17
 
 *
18
 
 * Authored by Michal Hruby <michal.mhr@gmail.com>
19
 
 *
20
 
 */
21
 
 
22
 
namespace Synapse
23
 
{
24
 
  public class LocatePlugin: Object, Activatable, ActionProvider
25
 
  {
26
 
    public bool enabled { get; set; default = true; }
27
 
 
28
 
    public void activate ()
29
 
    {
30
 
      
31
 
    }
32
 
 
33
 
    public void deactivate ()
34
 
    {
35
 
      
36
 
    }
37
 
 
38
 
    private class MatchObject: Object, Match, UriMatch
39
 
    {
40
 
      // for Match interface
41
 
      public string title { get; construct set; }
42
 
      public string description { get; set; default = ""; }
43
 
      public string icon_name { get; construct set; default = ""; }
44
 
      public bool has_thumbnail { get; construct set; default = false; }
45
 
      public string thumbnail_path { get; construct set; }
46
 
      public MatchType match_type { get; construct set; }
47
 
 
48
 
      // for FileMatch
49
 
      public string uri { get; set; }
50
 
      public QueryFlags file_type { get; set; }
51
 
      public string mime_type { get; set; }
52
 
 
53
 
      public MatchObject (string? thumbnail_path, string? icon)
54
 
      {
55
 
        Object (match_type: MatchType.GENERIC_URI,
56
 
                has_thumbnail: thumbnail_path != null,
57
 
                icon_name: icon ?? "",
58
 
                thumbnail_path: thumbnail_path ?? "");
59
 
      }
60
 
    }
61
 
 
62
 
    private class LocateItem: Object, SearchProvider, Match, SearchMatch
63
 
    {
64
 
      // for Match interface
65
 
      public string title { get; construct set; }
66
 
      public string description { get; set; default = ""; }
67
 
      public string icon_name { get; construct set; default = ""; }
68
 
      public bool has_thumbnail { get; construct set; default = false; }
69
 
      public string thumbnail_path { get; construct set; }
70
 
      public MatchType match_type { get; construct set; }
71
 
 
72
 
      public int default_relevancy { get; set; default = Match.Score.INCREMENT_SMALL; }
73
 
      // for SearchMatch interface
74
 
      public Match search_source { get; set; }
75
 
      public async Gee.List<Match> search (string query,
76
 
                                           QueryFlags flags,
77
 
                                           ResultSet? dest_result_set,
78
 
                                           Cancellable? cancellable = null) throws SearchError
79
 
      {
80
 
        var q = Query (0, query, flags);
81
 
        q.cancellable = cancellable;
82
 
        ResultSet? results = yield plugin.locate (q);
83
 
        dest_result_set.add_all (results);
84
 
 
85
 
        return dest_result_set.get_sorted_list ();
86
 
      }
87
 
 
88
 
      private unowned LocatePlugin plugin;
89
 
 
90
 
      public LocateItem (LocatePlugin plugin)
91
 
      {
92
 
        Object (match_type: MatchType.SEARCH,
93
 
                has_thumbnail: false,
94
 
                icon_name: "search",
95
 
                title: _ ("Locate"),
96
 
                description: _ ("Locate files with this name on the filesystem"));
97
 
        this.plugin = plugin;
98
 
      }
99
 
    }
100
 
 
101
 
    static void register_plugin ()
102
 
    {
103
 
      DataSink.PluginRegistry.get_default ().register_plugin (
104
 
        typeof (LocatePlugin),
105
 
        _ ("Locate"),
106
 
        _ ("Runs locate command to find files on the filesystem."),
107
 
        "search",
108
 
        register_plugin,
109
 
        Environment.find_program_in_path ("locate") != null,
110
 
        _ ("Unable to find \"locate\" binary")
111
 
      );
112
 
    }
113
 
 
114
 
    static construct
115
 
    {
116
 
      register_plugin ();
117
 
    }
118
 
 
119
 
    LocateItem action;
120
 
 
121
 
    construct
122
 
    {
123
 
      action = new LocateItem (this);
124
 
    }
125
 
 
126
 
    public bool handles_unknown ()
127
 
    {
128
 
      return true;
129
 
    }
130
 
 
131
 
    public async ResultSet? locate (Query q) throws SearchError
132
 
    {
133
 
      var our_results = QueryFlags.AUDIO | QueryFlags.DOCUMENTS
134
 
        | QueryFlags.IMAGES | QueryFlags.UNCATEGORIZED | QueryFlags.VIDEO;
135
 
 
136
 
      var common_flags = q.query_type & our_results;
137
 
      // strip query
138
 
      q.query_string = q.query_string.strip ();
139
 
      // ignore short searches
140
 
      if (common_flags == 0 || q.query_string.length <= 1) return null;
141
 
 
142
 
      q.check_cancellable ();
143
 
 
144
 
      q.max_results = 256;
145
 
      string regex = Regex.escape_string (q.query_string);
146
 
      // FIXME: split pattern into words and search using --regexp?
147
 
      string[] argv = {"locate", "-i", "-l", "%u".printf (q.max_results),
148
 
                       "*%s*".printf (regex.replace (" ", "*"))};
149
 
 
150
 
      Gee.Set<string> uris = new Gee.HashSet<string> ();
151
 
 
152
 
      try
153
 
      {
154
 
        Pid pid;
155
 
        int read_fd;
156
 
 
157
 
        // FIXME: fork on every letter... yey!
158
 
        Process.spawn_async_with_pipes (null, argv, null,
159
 
                                        SpawnFlags.SEARCH_PATH,
160
 
                                        null, out pid, null, out read_fd);
161
 
 
162
 
        UnixInputStream read_stream = new UnixInputStream (read_fd, true);
163
 
        DataInputStream locate_output = new DataInputStream (read_stream);
164
 
        string? line = null;
165
 
 
166
 
        Regex filter_re = new Regex ("/\\."); // hidden file/directory
167
 
        do
168
 
        {
169
 
          line = yield locate_output.read_line_async (Priority.DEFAULT_IDLE, q.cancellable);
170
 
          if (line != null)
171
 
          {
172
 
            if (filter_re.match (line)) continue;
173
 
            var file = File.new_for_path (line);
174
 
            uris.add (file.get_uri ());
175
 
          }
176
 
        } while (line != null);
177
 
      }
178
 
      catch (Error err)
179
 
      {
180
 
        if (!q.is_cancelled ()) warning ("%s", err.message);
181
 
      }
182
 
 
183
 
      q.check_cancellable ();
184
 
 
185
 
      var result = new ResultSet ();
186
 
 
187
 
      foreach (string s in uris)
188
 
      {
189
 
        var fi = new Utils.FileInfo (s, typeof (MatchObject));
190
 
        yield fi.initialize ();
191
 
        if (fi.match_obj != null && fi.file_type in q.query_type)
192
 
        {
193
 
          int relevancy = Match.Score.INCREMENT_SMALL; // FIXME: relevancy
194
 
          if (fi.uri.has_prefix ("file:///home/")) relevancy += Match.Score.INCREMENT_MINOR;
195
 
          result.add (fi.match_obj, relevancy);
196
 
        }
197
 
        q.check_cancellable ();
198
 
      }
199
 
 
200
 
      return result;
201
 
    }
202
 
 
203
 
    public ResultSet? find_for_match (ref Query q, Match match)
204
 
    {
205
 
      var our_results = QueryFlags.AUDIO | QueryFlags.DOCUMENTS
206
 
        | QueryFlags.IMAGES | QueryFlags.UNCATEGORIZED | QueryFlags.VIDEO;
207
 
 
208
 
      var common_flags = q.query_type & our_results;
209
 
      // ignore short searches
210
 
      if (common_flags == 0 || match.match_type != MatchType.UNKNOWN) return null;
211
 
 
212
 
      // strip query
213
 
      q.query_string = q.query_string.strip ();
214
 
      bool query_empty = q.query_string == "";
215
 
      var results = new ResultSet ();
216
 
 
217
 
      if (query_empty)
218
 
      {
219
 
        results.add (action, action.default_relevancy);
220
 
      }
221
 
      else
222
 
      {
223
 
        var matchers = Query.get_matchers_for_query (q.query_string, 0,
224
 
          RegexCompileFlags.CASELESS);
225
 
        foreach (var matcher in matchers)
226
 
        {
227
 
          if (matcher.key.match (action.title))
228
 
          {
229
 
            results.add (action, matcher.value);
230
 
            break;
231
 
          }
232
 
        }
233
 
      }
234
 
 
235
 
      return results;
236
 
    }
237
 
  }
238
 
}