Desarrollar y descargar software de código abierto

Browse Subversion Repository

Contents of /kazehakase/trunk/module/search/rast-search.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3433 - (show annotations) (download) (as text)
Sun Mar 2 17:49:26 2008 UTC (16 years, 2 months ago) by pal_gene
File MIME type: text/x-csrc
File size: 11909 byte(s)
Move old-rast support file to module/search.

1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /*
4 * Copyright (C) 2006 Ryo SHIMIZU
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #include <string.h>
22 #include <ctype.h>
23 #include <glib/gi18n.h>
24
25 #include "kazehakase.h"
26 #include "utils/utils.h"
27 #include "glib-utils.h"
28 #include "rast-search.h"
29 #include "egg-pixbuf-thumbnail.h"
30
31 #define HISTORY_INDEX "/."PACKAGE"/history_index.rast"
32
33 #define RAST_URI "http://projects.netlab.jp/rast/"
34 #define DTD "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">"
35 #define HEAD "<head>\n" \
36 " <title>Full-text search in history</title>\n" \
37 " <link rel=\"stylesheet\" type=\"text/css\" href=\"history-search:?css=search-result.css\">\n" \
38 "</head>\n"
39 #define HEADER ""
40 #define CONTENT "<div class=\"content\">\n" \
41 " <div class=\"header\"><span class=\"title\"><a href=\"%s\">%s</a></span></div>\n" \
42 " <div class=\"summary\"><img src=\"%s\" class=\"thumbnail\">\n" \
43 " <span class=\"sentence\">%s</span>\n" \
44 " </div>\n" \
45 " <div class=\"footer\">\n" \
46 " <span class=\"uri\">%s</span>\n" \
47 " <span class=\"cache\"><a href=\"%s\">cache</a></span>\n" \
48 " <span class=\"date\">%s</span>\n" \
49 " </div>\n" \
50 "</div>\n"
51 #define FOOTER "<div class=\"footer\">\n" \
52 "Powered by <a href=\"%s\">Rast</a> version %s\n" \
53 "</div>\n"
54
55 static gchar *rast_get_version (void);
56 gchar *get_value (const gchar *line);
57
58 static gboolean
59 rast_execute_search_command(const gchar *search_text, gint *standard_output)
60 {
61 gboolean ret;
62 const gchar *rast_cmd = "rast search ";
63 gchar *command;
64 gint argc;
65 gchar **argv = NULL;
66 GSpawnFlags flags;
67 GPid pid;
68 gint err;
69 gchar **split = NULL;
70 gchar *join = NULL;
71 gint max_results = 20, num_summary = 128;
72 gchar *except_word;
73 gchar **except_keywords = NULL;
74
75 KZ_CONF_GET("History", "num_summary", num_summary, INT);
76 KZ_CONF_GET("History", "max_results", max_results, INT);
77
78 split = g_strsplit(search_text, " ", -1);
79 if (split)
80 {
81 join = g_strjoinv(" & ", split);
82 g_strfreev(split);
83 }
84
85 except_word = KZ_CONF_GET_STR("History", "except_keyword");
86 if (except_word && *except_word)
87 {
88 except_keywords = g_strsplit(except_word, ",", -1);
89 g_free(except_word);
90 except_word = g_strjoinv(" - ", except_keywords);
91 g_strfreev(except_keywords);
92
93 command = g_strdup_printf("%s --num-items %d --summary-nchars %d '%s - %s' %s%s ",
94 rast_cmd,
95 max_results,
96 num_summary,
97 join,
98 except_word,
99 g_get_home_dir(),
100 HISTORY_INDEX);
101 g_free(except_word);
102 }
103 else
104 {
105 command = g_strdup_printf("%s --num-items %d --summary-nchars %d '%s' %s%s",
106 rast_cmd,
107 max_results,
108 num_summary,
109 join,
110 g_get_home_dir(),
111 HISTORY_INDEX" ");
112 }
113
114 if (join)
115 g_free(join);
116
117 g_shell_parse_argv(command,
118 &argc,
119 &argv,
120 NULL);
121
122 flags = G_SPAWN_SEARCH_PATH;
123 ret = g_spawn_async_with_pipes(NULL,
124 argv,
125 NULL,
126 flags,
127 NULL,
128 NULL,
129 &pid,
130 NULL,
131 standard_output,
132 &err,
133 NULL);
134 g_strfreev(argv);
135 g_free(command);
136
137 return ret;
138 }
139
140
141 static gchar *
142 rast_create_search_result_html (gint out, const gchar *text)
143 {
144 GIOChannel *io;
145 gchar *line;
146 gsize length;
147 gchar *title = NULL, *uri = NULL, *date = NULL, *desc = NULL;
148 gchar *cache_link = NULL;
149 gchar *rastversion = rast_get_version();
150 GString *html;
151
152 io = g_io_channel_unix_new(out);
153 g_io_channel_set_encoding(io, NULL, NULL);
154
155 html = g_string_sized_new(0);
156
157 g_string_append(html, DTD"\n");
158 g_string_append(html, "<html>\n");
159 g_string_append(html, HEAD);
160 g_string_append(html, "<body>\n");
161
162 g_string_append_printf(html, "<h1>Search results for %s</h1>",
163 text);
164
165 while (g_io_channel_read_line(io, &line, &length, NULL, NULL) == G_IO_STATUS_NORMAL)
166 {
167 if (g_str_has_prefix(line, "uri :"))
168 {
169 size_t len;
170 gchar *dirname = g_strconcat(g_get_home_dir(),
171 HISTORY_DIR,
172 NULL);
173 len = strlen(dirname);
174
175 cache_link = get_value(line);
176 g_print("%s\n", cache_link);
177 g_print("%s\n", dirname);
178 uri = create_uri_from_filename(cache_link +
179 strlen("file://") +
180 len);
181 g_free(dirname);
182 }
183 else if (g_str_has_prefix(line, "summary :"))
184 {
185 gchar *thumb_filename, *thumb_uri;
186 gchar *summary = get_value(line);
187
188 desc = remove_tag(summary, g_strlen(summary));
189 thumb_filename = egg_pixbuf_get_thumb_filename(uri,
190 EGG_PIXBUF_THUMB_LARGE);
191 thumb_uri = g_strdup_printf("history-search:?image=%s",
192 thumb_filename);
193 g_string_append_printf(html,
194 CONTENT,
195 uri,
196 title,
197 thumb_uri, /* thumbnail */
198 desc,
199 uri,
200 cache_link,
201 date);
202
203 g_free(desc);
204 g_free(title);
205 g_free(uri);
206 g_free(date);
207 g_free(cache_link);
208 g_free(summary);
209 g_free(thumb_filename);
210 g_free(thumb_uri);
211 }
212 else if (g_str_has_prefix(line, "title :"))
213 {
214 title = get_value(line);
215 }
216 else if (g_str_has_prefix(line, "last_modified :"))
217 {
218 date = get_value(line);
219 }
220 g_free(line);
221 }
222 g_io_channel_unref(io);
223 g_string_append_printf(html, FOOTER, RAST_URI, rastversion);
224 g_string_append(html, "</body></html>");
225
226 if (rastversion)
227 g_free(rastversion);
228 return g_string_free(html, FALSE);
229 }
230
231
232 gchar *
233 rast_get_search_result (const gchar *text)
234 {
235 gint out;
236
237 if (!text) return NULL;
238 if (!exists_search_cmd) return NULL;
239
240 if (!rast_execute_search_command(text, &out))
241 return NULL;
242
243 return rast_create_search_result_html(out, text);
244 }
245
246 gboolean
247 rast_update_index (gpointer data)
248 {
249 const gchar *rast_register = "rast register ";
250 gchar *index_dir;
251 gchar *command;
252 gint argc;
253 gchar **argv = NULL;
254 GSpawnFlags flags;
255 GPid pid;
256
257 index_dir = g_strconcat(g_get_home_dir(), HISTORY_INDEX, NULL);
258
259 command = g_strconcat(rast_register,
260 index_dir,
261 " ",
262 (gchar*)data,
263 NULL);
264 g_free(index_dir);
265
266 g_shell_parse_argv(command,
267 &argc,
268 &argv,
269 NULL);
270
271 flags = G_SPAWN_SEARCH_PATH |
272 G_SPAWN_STDOUT_TO_DEV_NULL;
273 g_spawn_async(NULL,
274 argv,
275 NULL,
276 flags,
277 NULL,
278 NULL,
279 &pid,
280 NULL);
281 g_strfreev(argv);
282 g_free(command);
283
284 g_free(data);
285
286 return FALSE;
287 }
288
289
290 gboolean
291 rast_purge_index (void)
292 {
293 const gchar *estpurge = "rast delete";
294 gchar *command;
295 gint argc;
296 gchar **argv = NULL;
297 GSpawnFlags flags;
298 GPid pid;
299
300 /* purge index */
301 flags = G_SPAWN_SEARCH_PATH |
302 G_SPAWN_STDOUT_TO_DEV_NULL;
303 command = g_strconcat(estpurge,
304 g_get_home_dir(),
305 HISTORY_INDEX,
306 NULL);
307
308 g_shell_parse_argv(command,
309 &argc,
310 &argv,
311 NULL);
312 flags = G_SPAWN_SEARCH_PATH |
313 G_SPAWN_STDOUT_TO_DEV_NULL;
314
315 g_spawn_async(NULL,
316 argv,
317 NULL,
318 flags,
319 NULL,
320 NULL,
321 &pid,
322 NULL);
323
324 g_strfreev(argv);
325 g_free(command);
326
327 return FALSE;
328 }
329
330 GPid
331 rast_optimize_index (void)
332 {
333 const gchar *estoptimize = "rast optimize ";
334 gchar *command;
335 gint argc;
336 gchar **argv = NULL;
337 GSpawnFlags flags;
338 GPid pid;
339
340 /* optimize index process */
341 command = g_strconcat(estoptimize,
342 g_get_home_dir(),
343 HISTORY_INDEX,
344 NULL);
345
346 g_shell_parse_argv(command,
347 &argc,
348 &argv,
349 NULL);
350 flags = G_SPAWN_SEARCH_PATH |
351 G_SPAWN_STDOUT_TO_DEV_NULL;
352
353 g_spawn_async(NULL,
354 argv,
355 NULL,
356 flags,
357 NULL,
358 NULL,
359 &pid,
360 NULL);
361 g_strfreev(argv);
362 g_free(command);
363
364 return pid;
365 }
366
367 static gchar*
368 rast_get_version (void)
369 {
370 gchar *version;
371 const gchar *rastversion = "rast-config --version";
372 gint argc;
373 gchar **argv = NULL;
374 GSpawnFlags flags;
375 GPid pid;
376 gint out, err;
377 gboolean ret;
378 GIOChannel *io;
379 gsize length;
380
381 if (!exists_search_cmd) return NULL;
382
383 g_shell_parse_argv(rastversion,
384 &argc,
385 &argv,
386 NULL);
387
388 flags = G_SPAWN_SEARCH_PATH;
389 ret = g_spawn_async_with_pipes(NULL,
390 argv,
391 NULL,
392 flags,
393 NULL,
394 NULL,
395 &pid,
396 NULL,
397 &out,
398 &err,
399 NULL);
400 g_strfreev(argv);
401 if (!ret) return NULL;
402
403 io = g_io_channel_unix_new(out);
404 g_io_channel_set_encoding(io, NULL, NULL);
405 g_io_channel_read_line(io, &version, &length, NULL, NULL);
406 g_io_channel_shutdown(io, TRUE, NULL);
407 g_io_channel_unref(io);
408
409 return version;
410 }
411
412 static KzBookmark *
413 rast_create_search_result_bookmark (gint out, const gchar *text)
414 {
415 GIOChannel *io;
416 gchar *line;
417 gsize length;
418 gchar *title = NULL, *uri = NULL, *desc = NULL;
419 KzBookmark *result;
420
421 io = g_io_channel_unix_new(out);
422 g_io_channel_set_encoding(io, NULL, NULL);
423
424 result = kz_bookmark_pure_folder_new();
425
426 while (g_io_channel_read_line(io, &line, &length, NULL, NULL) == G_IO_STATUS_NORMAL)
427 {
428 if (g_str_has_prefix(line, "</document>"))
429 {
430 KzBookmark *child;
431 child = kz_bookmark_new_with_attrs(title, uri, desc);
432 kz_bookmark_append(result, child);
433 g_object_unref(child);
434 g_free(desc);
435 g_free(title);
436 g_free(uri);
437 }
438 else if (g_str_has_prefix(line, "<uri>"))
439 {
440 gchar *dirname, *orig_uri;
441 gchar *link;
442 size_t len;
443 link = xml_get_attr(line, "uri");
444 dirname = g_strconcat(g_get_home_dir(),
445 HISTORY_DIR,
446 NULL);
447 len = strlen(dirname);
448 orig_uri = create_uri_from_filename(link + strlen("file://") + len);
449 uri = url_decode(orig_uri);
450 g_free(orig_uri);
451 g_free(dirname);
452 g_free(link);
453 }
454 else if (g_str_has_prefix(line, "<title>"))
455 {
456 title = xml_get_content(line);
457 }
458 else if (g_str_has_prefix(line, "<summary"))
459 {
460 gchar *summary = xml_get_content(line);
461 desc = remove_tag(summary, g_strlen(summary));
462 g_free(summary);
463 }
464 g_free(line);
465 }
466 g_io_channel_unref(io);
467
468 return result;
469 }
470
471 KzBookmark *
472 rast_get_search_result_bookmark (const gchar *text)
473 {
474 gint out;
475
476 if (!text) return NULL;
477 if (!exists_search_cmd) return NULL;
478
479 if (!rast_execute_search_command(text, &out))
480 return NULL;
481
482 return rast_create_search_result_bookmark(out, text);
483 }
484
485 void
486 rast_make_index(void)
487 {
488 const gchar *rast_create = "rast create --preserve-text --property=title:string:search ";
489 gchar *command;
490 gint argc;
491 gchar **argv = NULL;
492 GSpawnFlags flags;
493 GPid pid;
494
495 command = g_strconcat(rast_create,
496 g_get_home_dir(),
497 HISTORY_INDEX" ",
498 g_get_home_dir(),
499 HISTORY_DIR,
500 NULL);
501
502 g_shell_parse_argv(command,
503 &argc,
504 &argv,
505 NULL);
506 flags = G_SPAWN_SEARCH_PATH |
507 G_SPAWN_STDOUT_TO_DEV_NULL;
508
509 g_spawn_async(NULL,
510 argv,
511 NULL,
512 flags,
513 NULL,
514 NULL,
515 &pid,
516 NULL);
517 g_strfreev(argv);
518 g_free(command);
519 }
520
521 gboolean
522 rast_exist_index_dir(void)
523 {
524 gchar *index_dir;
525 gboolean exist = FALSE;
526
527 index_dir = g_build_filename(g_get_home_dir(),
528 HISTORY_INDEX, NULL);
529 exist = g_file_test(index_dir, G_FILE_TEST_IS_DIR);
530 g_free(index_dir);
531
532 return exist;
533 }
534
535 gchar *get_value (const gchar *line)
536 {
537 gchar *p;
538
539 p = strchr(line, ':');
540 p += 2;
541
542 return g_strchomp(g_strdup(p));
543 }

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26