Compute lucene-style scores for our hits.
[beagle.git] / tools / Query.cs
blob3a9f24d37b28889108f98319bbbf7cb9bb16d8c2
1 //
2 // Query.cs
3 //
4 // Copyright (C) 2004-2005 Novell, Inc.
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
27 using System;
28 using System.Collections;
29 using System.Threading;
30 using System.Text;
32 using Gtk;
34 using Beagle;
35 using BU = Beagle.Util;
37 class QueryTool {
39 static int count = 0;
40 static Query query = null;
41 static DateTime queryStartTime;
42 static DateTime lastQueryTime = DateTime.Now;
44 // CLI args
45 static bool keepRunning = false;
46 static bool verbose = false;
47 static bool display_hits = true;
48 static bool flood = false;
50 static void OnHitsAdded (HitsAddedResponse response)
52 lastQueryTime = DateTime.Now;
54 if (count == 0 && verbose) {
55 Console.WriteLine ("First hit returned in {0:0.000}s",
56 (lastQueryTime - queryStartTime).TotalSeconds);
59 if (! display_hits) {
60 count += response.Hits.Count;
61 return;
64 foreach (Hit hit in response.Hits) {
65 if (verbose)
66 Console.WriteLine (" Uri: {0}", hit.Uri);
67 else
68 Console.WriteLine (hit.Uri);
70 if (verbose) {
71 SnippetRequest sreq = new SnippetRequest (query.Text, hit);
72 SnippetResponse sresp = (SnippetResponse) sreq.Send ();
73 Console.WriteLine ("PaUri: {0}", hit.ParentUri != null ? hit.ParentUri.ToString () : "(null)");
74 Console.WriteLine (" Snip: {0}", sresp.Snippet != null ? sresp.Snippet : "(null)");
75 Console.WriteLine (" Type: {0}", hit.Type);
76 Console.WriteLine ("MimeT: {0}", hit.MimeType == null ? "(null)" : hit.MimeType);
77 Console.WriteLine (" Src: {0}", hit.Source);
78 Console.WriteLine ("Score: {0}", hit.Score);
79 if (hit.ValidTimestamp)
80 Console.WriteLine (" Time: {0}", hit.Timestamp);
82 foreach (Property prop in hit.Properties)
83 Console.WriteLine (" {0} = {1}", prop.Key, prop.Value);
85 Console.WriteLine ();
88 ++count;
92 static void OnHitsSubtracted (HitsSubtractedResponse response)
94 lastQueryTime = DateTime.Now;
96 if (! display_hits)
97 return;
99 foreach (Uri uri in response.Uris) {
100 Console.WriteLine ("Subtracted Uri '{0}'", uri);
101 Console.WriteLine ();
103 --count;
107 static void OnFinished (FinishedResponse response)
109 if (verbose) {
110 Console.WriteLine ("Elapsed time: {0:0.000}s",
111 (DateTime.Now - queryStartTime).TotalSeconds);
112 Console.WriteLine ("Total hits: {0}", count);
115 if (flood)
116 SendQuery ();
117 else
118 Gtk.Application.Quit ();
121 public static void PrintUsageAndExit ()
123 string usage =
124 "beagle-query: Command-line interface to the Beagle search system.\n" +
125 "Web page: http://www.gnome.org/projects/beagle\n" +
126 "Copyright (C) 2004 Novell, Inc.\n\n";
127 usage +=
128 "Usage: beagle-query [OPTIONS] <query string>\n\n" +
129 "Options:\n" +
130 " --verbose\t\t\tPrint detailed information about each hit.\n" +
131 " --mime <mime type>\t\tConstrain search results to the specified mime\n" +
132 " \t\ttype. Can be used multiply.\n" +
133 " --type <hit type>\t\tConstrain search results to the specified hit\n" +
134 " \t\ttype. Can be used multiply.\n" +
135 " --source <source>\t\tConstrain query to the specified source.\n" +
136 " \t\tSources list available from beagle-status.\n" +
137 " --live-query\t\t\tRun continuously, printing notifications if a\n" +
138 " \t\t\tquery changes.\n" +
139 " --stats-only\t\t\tOnly display statistics about the query, not\n" +
140 " \t\t\tthe actual results.\n" +
141 " --max-hits\t\t\tLimit number of search results per backend\n" +
142 " \t\t\t(default = 100, max = 100)\n" +
143 " --flood\t\t\tExecute the query over and over again. Don't do that.\n" +
144 " --help\t\t\tPrint this usage message.\n";
146 Console.WriteLine (usage);
148 System.Environment.Exit (0);
151 static void OnClosed ()
153 if (flood)
154 SendQuery ();
155 else
156 Gtk.Application.Quit ();
159 static int query_counter = 0;
160 static void SendQuery ()
162 ++query_counter;
163 if (flood) {
164 if (query_counter > 1)
165 Console.WriteLine ();
166 Console.WriteLine ("Sending query #{0}", query_counter);
169 queryStartTime = DateTime.Now;
170 try {
171 query.SendAsync ();
172 } catch (Exception ex) {
173 Console.WriteLine ("Could not connect to the Beagle daemon. The daemon probably isn't running.");
174 Console.WriteLine (ex);
175 System.Environment.Exit (-1);
179 static void Main (string[] args)
181 Gtk.Application.InitCheck ("beagle-query", ref args);
183 if (args.Length == 0 || Array.IndexOf (args, "--help") > -1 || Array.IndexOf (args, "--usage") > -1)
184 PrintUsageAndExit ();
186 query = new Query ();
188 StringBuilder query_str = new StringBuilder ();
190 // Parse args
191 int i = 0;
192 while (i < args.Length) {
193 switch (args [i]) {
195 case "--mime":
196 if (++i >= args.Length) PrintUsageAndExit ();
197 query.AddMimeType (args [i]);
198 break;
199 case "--type":
200 if (++i >= args.Length) PrintUsageAndExit ();
201 query.AddHitType (args [i]);
202 break;
203 case "--source":
204 if (++i >= args.Length) PrintUsageAndExit ();
205 query.AddSource (args [i]);
206 break;
207 case "--live-query":
208 keepRunning = true;
209 break;
210 case "--verbose":
211 verbose = true;
212 break;
213 case "--stats-only":
214 verbose = true;
215 display_hits = false;
216 break;
217 case "--max-hits":
218 if (++i >= args.Length) PrintUsageAndExit ();
219 query.MaxHits = Int32.Parse (args[i]);
220 break;
221 case "--flood":
222 flood = true;
223 break;
225 default:
226 if (query_str.Length > 0)
227 query_str.Append (' ');
228 query_str.Append (args [i]);
229 break;
232 ++i;
235 if (query_str.Length > 0)
236 query.AddText (query_str.ToString ());
238 query.HitsAddedEvent += OnHitsAdded;
239 query.HitsSubtractedEvent += OnHitsSubtracted;
242 if (! keepRunning)
243 query.FinishedEvent += OnFinished;
244 else
245 query.ClosedEvent += OnClosed;
247 SendQuery ();
249 Gtk.Application.Run ();