[Kazehakase-cvs] CVS update: kazehakase/src/utils

Back to archive index

Ryo SHIMIZU furyo****@users*****
Thu Feb 23 22:29:03 JST 2006


Index: kazehakase/src/utils/rast-search.c
diff -u /dev/null kazehakase/src/utils/rast-search.c:1.1
--- /dev/null	Thu Feb 23 22:29:03 2006
+++ kazehakase/src/utils/rast-search.c	Thu Feb 23 22:29:03 2006
@@ -0,0 +1,542 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Copyright (C) 2006 Ryo SHIMIZU
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, 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 General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <ctype.h>
+#include <glib/gi18n.h>
+
+#include "kazehakase.h"
+#include "utils/utils.h"
+#include "glib-utils.h"
+#include "rast-search.h"
+#include "egg-pixbuf-thumbnail.h"
+
+
+#define RAST_URI "http://projects.netlab.jp/rast/"
+#define DTD   "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">"
+#define HEAD  "<head>\n" \
+	      "  <title>Full-text search in history</title>\n" \
+	      "  <link rel=\"stylesheet\" type=\"text/css\" href=\"history-search:?css=search-result.css\">\n" \
+	      "</head>\n"
+#define HEADER  ""
+#define CONTENT "<div class=\"content\">\n" \
+	        "  <div class=\"header\"><span class=\"title\"><a href=\"%s\">%s</a></span></div>\n" \
+		"    <div class=\"summary\"><img src=\"%s\" class=\"thumbnail\">\n" \
+		"    <span class=\"sentence\">%s</span>\n" \
+		"  </div>\n" \
+		"  <div class=\"footer\">\n" \
+		"    <span class=\"uri\">%s</span>\n" \
+		"    <span class=\"cache\"><a href=\"%s\">cache</a></span>\n" \
+		"    <span class=\"date\">%s</span>\n" \
+		"  </div>\n" \
+		"</div>\n"
+#define FOOTER  "<div class=\"footer\">\n" \
+	        "Powered by <a href=\"%s\">Rast</a> version %s\n" \
+		"</div>\n"
+
+static gchar *rast_get_version (void);
+gchar *get_value (const gchar *line);
+
+static gboolean
+rast_execute_search_command(const gchar *search_text, gint *standard_output)
+{
+	gboolean ret;
+	const gchar *rast_cmd = "rast search ";
+	gchar *command;
+	gint argc;
+	gchar **argv = NULL;
+	GSpawnFlags flags;
+	GPid pid;
+	gint err;
+	gchar **split = NULL;
+	gchar *join = NULL;
+	gint max_results = 20, num_summary = 128;
+	gchar *except_word;
+	gchar **except_keywords = NULL;
+
+	KZ_CONF_GET("History", "num_summary", num_summary, INT);
+	KZ_CONF_GET("History", "max_results", max_results, INT);
+
+	split = g_strsplit(search_text, " ", -1);
+	if (split)
+	{
+		join = g_strjoinv(" & ", split);
+		g_strfreev(split);
+	}
+
+	except_word = KZ_CONF_GET_STR("History", "except_keyword");
+	if (except_word && *except_word)
+	{
+		except_keywords = g_strsplit(except_word, ",", -1);
+		g_free(except_word);
+		except_word = g_strjoinv(" - ", except_keywords);
+		g_strfreev(except_keywords);
+
+		command = g_strdup_printf("%s --num-items %d --summary-nchars %d '%s - %s' %s%s ",
+					  rast_cmd,
+					  max_results, 
+					  num_summary,
+					  join,
+					  except_word,
+					  g_get_home_dir(),
+					  HISTORY_INDEX);
+		g_free(except_word);
+	}
+	else
+	{
+		command = g_strdup_printf("%s --num-items %d --summary-nchars %d '%s' %s%s",
+					  rast_cmd,
+					  max_results, 
+					  num_summary,
+					  join,
+					  g_get_home_dir(),
+					  HISTORY_INDEX" ");
+	}
+
+	if (join)
+		g_free(join);
+
+	g_shell_parse_argv(command,
+			   &argc,
+			   &argv,
+			   NULL);
+
+	flags = G_SPAWN_SEARCH_PATH; 
+	ret = g_spawn_async_with_pipes(NULL,
+				       argv,
+				       NULL,
+				       flags,
+				       NULL,
+				       NULL,
+				       &pid,
+				       NULL,
+				       standard_output,
+				       &err,
+				       NULL);
+	g_strfreev(argv);
+	g_free(command);
+
+	return ret;
+}
+
+
+static gchar *
+rast_create_search_result_html (gint out, const gchar *text)
+{
+	GIOChannel *io;
+	gchar *line;
+	gsize length;
+	gchar *title = NULL, *uri = NULL, *date = NULL, *desc = NULL;
+	gchar *cache_link = NULL;
+	gchar *rastversion = rast_get_version();
+	GString *html;
+
+	io = g_io_channel_unix_new(out);
+	g_io_channel_set_encoding(io, NULL, NULL);
+	
+	html = g_string_sized_new(0);
+
+	g_string_append(html, DTD"\n");
+	g_string_append(html, "<html>\n");
+	g_string_append(html, HEAD);
+	g_string_append(html, "<body>\n");
+
+	g_string_append_printf(html, "<h1>Search results for %s</h1>",
+			       text);
+
+	while (g_io_channel_read_line(io, &line, &length, NULL, NULL) == G_IO_STATUS_NORMAL)
+	{
+		if (g_str_has_prefix(line, "uri :"))
+		{
+			size_t len;
+			gchar *dirname = g_strconcat(g_get_home_dir(), 
+						     HISTORY_DIR,
+						     NULL);
+			len = strlen(dirname);
+
+			cache_link = get_value(line);
+			g_print("%s\n", cache_link);
+			g_print("%s\n", dirname);
+			uri = create_uri_from_filename(cache_link + 
+						       strlen("file://") + 
+						       len);
+			g_free(dirname);
+		}
+		else if (g_str_has_prefix(line, "summary :"))
+		{
+			gchar *thumb_filename, *thumb_uri;
+			gchar *summary = get_value(line);
+
+			desc = remove_tag(summary, g_strlen(summary));
+			thumb_filename = egg_pixbuf_get_thumb_filename(uri,
+								       EGG_PIXBUF_THUMB_LARGE);
+			thumb_uri = g_strdup_printf("history-search:?image=%s",
+						    thumb_filename);
+			g_string_append_printf(html,
+					       CONTENT,
+					       uri,
+					       title,
+					       thumb_uri, /* thumbnail */
+					       desc,
+					       uri,
+					       cache_link,
+					       date);
+
+			g_free(desc);
+			g_free(title);
+			g_free(uri);
+			g_free(date);
+			g_free(cache_link);
+			g_free(summary);
+			g_free(thumb_filename);
+			g_free(thumb_uri);
+		}
+		else if (g_str_has_prefix(line, "title :"))
+		{
+			title = get_value(line);
+		}
+		else if (g_str_has_prefix(line, "last_modified :"))
+		{
+			date = get_value(line);
+		}
+		g_free(line);
+	}
+	g_io_channel_unref(io);
+	g_string_append_printf(html, FOOTER, RAST_URI, rastversion);
+	g_string_append(html, "</body></html>");
+
+	if (rastversion)
+		g_free(rastversion);
+	return g_string_free(html, FALSE);
+}
+
+
+gchar *
+rast_get_search_result (const gchar *text)
+{
+	gint out;
+
+	if (!text) return NULL;
+	if (!exists_search_cmd) return NULL;
+
+	if (!rast_execute_search_command(text, &out))
+		return NULL;
+
+	return rast_create_search_result_html(out, text);
+}
+
+gboolean
+rast_update_index (gpointer data)
+{
+	const gchar *rast_register = "rast register ";
+	gchar *index_dir;
+	gchar *command;
+	gint argc;
+	gchar **argv = NULL;
+	GSpawnFlags flags;
+	GPid pid;
+
+	index_dir = g_strconcat(g_get_home_dir(), HISTORY_INDEX, NULL);
+
+	command = g_strconcat(rast_register,
+			      index_dir,
+			      " ",
+			      (gchar*)data,
+			      NULL);
+	g_free(index_dir);
+
+	g_shell_parse_argv(command,
+			   &argc,
+			   &argv,
+			   NULL);
+
+	flags = G_SPAWN_SEARCH_PATH |
+		G_SPAWN_STDOUT_TO_DEV_NULL;
+	g_spawn_async(NULL,
+		      argv,
+		      NULL,
+		      flags,
+		      NULL,
+		      NULL,
+		      &pid,
+		      NULL);
+	g_strfreev(argv);
+	g_free(command);
+
+	g_free(data);
+	
+	return FALSE;
+}
+
+
+gboolean
+rast_purge_index (void)
+{
+	const gchar *estpurge = "rast delete";
+	gchar *command;
+	gint argc;
+	gchar **argv = NULL;
+	GSpawnFlags flags;
+	GPid pid;
+
+	/* purge index */
+	flags = G_SPAWN_SEARCH_PATH |
+		G_SPAWN_STDOUT_TO_DEV_NULL;
+	command = g_strconcat(estpurge,
+			      g_get_home_dir(),
+			      HISTORY_INDEX,
+			      NULL);
+
+	g_shell_parse_argv(command,
+			   &argc,
+			   &argv,
+			   NULL);
+	flags = G_SPAWN_SEARCH_PATH |
+		G_SPAWN_STDOUT_TO_DEV_NULL;
+	
+	g_spawn_async(NULL,
+		      argv,
+		      NULL,
+		      flags,
+		      NULL,
+		      NULL,
+		      &pid,
+		      NULL);
+
+	g_strfreev(argv);
+	g_free(command);
+
+	return FALSE;
+}
+
+GPid
+rast_optimize_index (void)
+{
+	const gchar *estoptimize = "rast optimize "; 
+	gchar *command;
+	gint argc;
+	gchar **argv = NULL;
+	GSpawnFlags flags;
+	GPid pid;
+	
+	/* optimize index process */
+	command = g_strconcat(estoptimize, 
+			      g_get_home_dir(), 
+			      HISTORY_INDEX,
+			      NULL);
+
+	g_shell_parse_argv(command,
+			   &argc,
+			   &argv,
+			   NULL);
+	flags = G_SPAWN_SEARCH_PATH |
+		G_SPAWN_STDOUT_TO_DEV_NULL;
+	
+	g_spawn_async(NULL,
+		      argv,
+		      NULL,
+		      flags,
+		      NULL,
+		      NULL,
+		      &pid,
+		      NULL);
+	g_strfreev(argv);
+	g_free(command);
+
+	return pid;
+}
+
+static gchar*
+rast_get_version (void)
+{
+	gchar *version;
+	const gchar *rastversion = "rast-config --version";
+	gint argc;
+	gchar **argv = NULL;
+	GSpawnFlags flags;
+	GPid pid;
+	gint out, err;
+	gboolean ret;
+	GIOChannel *io;
+	gsize length;
+
+	if (!exists_search_cmd) return NULL;
+	
+	g_shell_parse_argv(rastversion,
+			   &argc,
+			   &argv,
+			   NULL);
+
+	flags = G_SPAWN_SEARCH_PATH; 
+	ret = g_spawn_async_with_pipes(NULL,
+				       argv,
+				       NULL,
+				       flags,
+				       NULL,
+				       NULL,
+				       &pid,
+				       NULL,
+				       &out,
+				       &err,
+				       NULL);
+	g_strfreev(argv);
+	if (!ret) return NULL;
+
+	io = g_io_channel_unix_new(out);
+	g_io_channel_set_encoding(io, NULL, NULL);
+	g_io_channel_read_line(io, &version, &length, NULL, NULL);
+	g_io_channel_shutdown(io, TRUE, NULL);
+	g_io_channel_unref(io);
+
+	return version;
+}
+
+static KzBookmark *
+rast_create_search_result_bookmark (gint out, const gchar *text)
+{
+	GIOChannel *io;
+	gchar *line;
+	gsize length;
+	gchar *title = NULL, *uri = NULL, *desc = NULL;
+	KzBookmark *result;
+
+	io = g_io_channel_unix_new(out);
+	g_io_channel_set_encoding(io, NULL, NULL);
+
+	result = kz_bookmark_pure_folder_new();
+	
+	while (g_io_channel_read_line(io, &line, &length, NULL, NULL) == G_IO_STATUS_NORMAL)
+	{
+		if (g_str_has_prefix(line, "</document>"))
+		{
+			KzBookmark *child;
+			child = kz_bookmark_new_with_attrs(title, uri, desc);
+			kz_bookmark_append(result, child);
+			g_object_unref(child);
+			g_free(desc);
+			g_free(title);
+			g_free(uri);
+		}
+		else if (g_str_has_prefix(line, "<uri>"))
+		{
+			gchar *dirname, *orig_uri;
+			gchar *link;
+			size_t len;
+			link = xml_get_attr(line, "uri");
+			dirname = g_strconcat(g_get_home_dir(), 
+					      HISTORY_DIR,
+					      NULL);
+			len = strlen(dirname);
+			orig_uri = create_uri_from_filename(link + strlen("file://") + len);
+			uri = url_decode(orig_uri);
+			g_free(orig_uri);			
+			g_free(dirname);
+			g_free(link);
+		}
+		else if (g_str_has_prefix(line, "<title>"))
+		{
+			title = xml_get_content(line);
+		}
+		else if (g_str_has_prefix(line, "<summary"))
+		{
+			gchar *summary = xml_get_content(line);
+			desc = remove_tag(summary, g_strlen(summary));
+			g_free(summary);
+		}
+		g_free(line);
+	}
+	g_io_channel_unref(io);
+
+	return result;
+}
+
+KzBookmark *
+rast_get_search_result_bookmark (const gchar *text)
+{
+	gint out;
+
+	if (!text) return NULL;
+	if (!exists_search_cmd) return NULL;
+
+	if (!rast_execute_search_command(text, &out))
+		return NULL;
+
+	return rast_create_search_result_bookmark(out, text);
+}
+
+void
+rast_make_index(void)
+{
+	const gchar *rast_create = "rast create --preserve-text --property=title:string:search "; 
+	gchar *command;
+	gint argc;
+	gchar **argv = NULL;
+	GSpawnFlags flags;
+	GPid pid;
+	
+	command = g_strconcat(rast_create, 
+			      g_get_home_dir(),
+			      HISTORY_INDEX" ",
+			      g_get_home_dir(),
+			      HISTORY_DIR,
+			      NULL);
+
+	g_shell_parse_argv(command,
+			   &argc,
+			   &argv,
+			   NULL);
+	flags = G_SPAWN_SEARCH_PATH |
+		G_SPAWN_STDOUT_TO_DEV_NULL;
+	
+	g_spawn_async(NULL,
+		      argv,
+		      NULL,
+		      flags,
+		      NULL,
+		      NULL,
+		      &pid,
+		      NULL);
+	g_strfreev(argv);
+	g_free(command);
+}
+
+gboolean
+rast_exist_index_dir(void)
+{
+	gchar *index_dir;
+	gboolean exist = FALSE;
+
+	index_dir = g_build_filename(g_get_home_dir(),
+			HISTORY_INDEX, NULL);
+	exist = g_file_test(index_dir, G_FILE_TEST_IS_DIR);
+	g_free(index_dir);
+
+	return exist;
+}
+
+gchar *get_value (const gchar *line)
+{
+	gchar *p;
+
+	p = strchr(line, ':');
+	p += 2;
+
+	return g_strchomp(g_strdup(p));
+}
Index: kazehakase/src/utils/rast-search.h
diff -u /dev/null kazehakase/src/utils/rast-search.h:1.1
--- /dev/null	Thu Feb 23 22:29:03 2006
+++ kazehakase/src/utils/rast-search.h	Thu Feb 23 22:29:03 2006
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Copyright (C) 2006 Ryo SHIMIZU
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, 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 General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __RASTSEARCH_H__
+#define __RASTSEARCH_H__
+
+#include <glib.h>
+#include <kz-bookmark.h>
+
+G_BEGIN_DECLS
+
+gchar      *rast_get_search_result (const gchar* text);
+
+KzBookmark *rast_get_search_result_bookmark (const gchar* text);
+
+gboolean    rast_update_index      (gpointer data);
+gboolean    rast_purge_index       (void);
+GPid        rast_optimize_index    (void);
+void        rast_make_index              (void);
+gboolean    rast_exist_index_dir         (void);
+
+G_END_DECLS
+
+#endif /* __RASTSEARCH_H__ */


More information about the Kazehakase-cvs mailing list
Back to archive index