Logo Search packages:      
Sourcecode: kazehakase version File versions

estsearch.c

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/*
 *  Copyright (C) 2004 Hiroyuki Ikezoe
 *
 *  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 <ctype.h>
#include <glib/gi18n.h>

#include "kazehakase.h"
#include "utils/utils.h"
#include "glib-utils.h"
#include "estsearch.h"
#include "egg-pixbuf-thumbnail.h"


#define ESTRAIER_URI "http://estraier.sourceforge.net/"
#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\">Estraier</a> version %s\n" \
            "</div>\n"

static gboolean
execute_search_command(const gchar *search_text, gint *standard_output)
{
      gboolean ret;
      const gchar *estxview = "estxview";
      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;

      split = g_strsplit(search_text, "+", -1);
      if (split)
      {
            join = g_strjoinv(" ", split);
            g_strfreev(split);
      }

      KZ_CONF_GET("History", "num_summary", num_summary, INT);
      KZ_CONF_GET("History", "max_results", max_results, INT);
      command = g_strdup_printf("%s -snum %d -max %d %s%s %s",
                          estxview, num_summary, max_results, 
                            g_get_home_dir(), HISTORY_INDEX,
                            join);
      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 *
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 *estversion = NULL;
      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 (!strncmp(line, "<document", 9))
            {
            }
            else if (!strncmp(line, "</document>", 11))
            {
                  gchar *thumb_filename, *thumb_uri;
                  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(thumb_filename);
                  g_free(thumb_uri);
            }
            else if (!strncmp(line, "<uri>", 5))
            {
                  gchar *dirname, *orig_uri;
                  gchar *link;
                  size_t len;
                  link = xml_get_content(line);
                  cache_link = g_strconcat("file://",
                                     link,
                                     NULL);
                  dirname = g_strconcat(g_get_home_dir(), 
                                    HISTORY_DIR,
                                    NULL);
                  len = strlen(dirname);
                  orig_uri = create_uri_from_filename(link + len);
                  uri = url_decode(orig_uri);
                  g_free(orig_uri);             
                  g_free(dirname);
                  g_free(link);
            }
            else if (!strncmp(line, "<title>", 7))
            {
                  title = xml_get_content(line);
            }
            else if (!strncmp(line, "<date>", 6))
            {
                  date = xml_get_content(line);
            }
            else if (!strncmp(line, "<estxview", 9))
            {
                  estversion = xml_get_attr(line, "version");
            }
            else if (!strncmp(line, "<summary", 8))
            {
                  desc = xml_get_content(line);
            }
            g_free(line);
      }
      g_io_channel_unref(io);
      g_string_append_printf(html, FOOTER, ESTRAIER_URI, estversion);
      g_string_append(html, "</body></html>");

      if (estversion)
            g_free(estversion);
      return g_string_free(html, FALSE);
}


gchar *
estsearch_get_search_result (const gchar *text)
{
      gint out;

      if (!text) return NULL;
      if (!exists_estindex) return NULL;

      if (!execute_search_command(text, &out))
            return NULL;

      return create_search_result_html(out, text);
}

gboolean
estsearch_update_index (gpointer data)
{
      const gchar *estindex = "estindex register -list - -hsuf \"*\" ";
      const gchar *estrelate = "estindex relate ";
      gchar *command;
      gchar *filename;
      gint in;
      gint argc;
      gchar **argv = NULL;
      GSpawnFlags flags;
      GPid pid;
      GIOChannel *io;

      command = g_strconcat(estindex, 
                        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_with_pipes(NULL,
                               argv,
                         NULL,
                         flags,
                               NULL,
                               NULL,
                               &pid,
                         &in,
                         NULL,
                         NULL,
                               NULL);
      g_strfreev(argv);
      g_free(command);

      /* set filename to add index */
      filename = g_strconcat((gchar*)data, "\n", NULL);     
      io = g_io_channel_unix_new(in);
      g_io_channel_set_encoding(io, NULL, NULL);
      g_io_channel_write_chars(io, filename, strlen(filename), NULL, NULL);
      g_io_channel_shutdown(io, TRUE, NULL);
      g_io_channel_unref(io);

      g_free(filename);
      g_free(data);
      
      flags = G_SPAWN_SEARCH_PATH |
            G_SPAWN_STDOUT_TO_DEV_NULL;
      
      /* score information process */
      command = g_strconcat(estrelate, 
                        g_get_home_dir(), HISTORY_INDEX,
                        NULL);

      g_shell_parse_argv(command,
                     &argc,
                     &argv,
                     NULL);

      g_spawn_async(NULL,
                  argv,
                  NULL,
                  flags,
                  NULL,
                  NULL,
                  &pid,
                  NULL);
      g_strfreev(argv);
      g_free(command);

      return FALSE;
}


gboolean
estsearch_purge_index (gchar **files)
{
      const gchar *estpurge = "estindex purge ";
      gchar *command;
      gint argc, in, i = 0;
      gchar **argv = NULL;
      GSpawnFlags flags;
      GPid pid;
      GIOChannel *io;
      gboolean listflag = FALSE;

      listflag = (g_ascii_strcasecmp(estversion, "1.2.18") >= 0);
      
      /* purge index */
      flags = G_SPAWN_SEARCH_PATH |
            G_SPAWN_STDOUT_TO_DEV_NULL;
      if (listflag)
      {
            command = g_strconcat(estpurge, "-list - ",
                              g_get_home_dir(), HISTORY_INDEX,
                              NULL);
      }
      else
      {
            command = g_strconcat(estpurge,
                              g_get_home_dir(), HISTORY_INDEX,
                              NULL);
      }

      g_shell_parse_argv(command,
                     &argc,
                     &argv,
                     NULL);

      g_spawn_async_with_pipes(NULL,
                               argv,
                         NULL,
                         flags,
                               NULL,
                               NULL,
                               &pid,
                         &in,
                         NULL,
                         NULL,
                               NULL);
      g_strfreev(argv);
      g_free(command);

      /* set filename to add index */
      if (listflag && !files)
      {
            while (files[i])
            {
                  io = g_io_channel_unix_new(in);
                  g_io_channel_set_encoding(io, NULL, NULL);
                  g_io_channel_write_chars(io,
                                     files[i], g_strlen(files[i]),
                                     NULL, NULL);
                  g_io_channel_shutdown(io, TRUE, NULL);
                  g_io_channel_unref(io);
                  i++;
            }
      }

      return FALSE;
}

GPid
estsearch_optimize_index (void)
{
      const gchar *estoptimize = "estindex 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;
}

gchar *
estsearch_get_version (void)
{
      gchar *version, *find;
      const gchar *estsiutil = "estsiutil version";
      gint argc;
      gchar **argv = NULL;
      GSpawnFlags flags;
      GPid pid;
      gint out, err;
      gboolean ret;
      GIOChannel *io;
      gsize length;

      find = g_find_program_in_path("estsiutil");
      if (!find) return NULL;
      g_free(find);

      g_shell_parse_argv(estsiutil,
                     &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 *
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 (!strncmp(line, "<document", 9))
            {
            }
            else if (!strncmp(line, "</document>", 11))
            {
                  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 (!strncmp(line, "<uri>", 5))
            {
                  gchar *dirname, *orig_uri;
                  gchar *link;
                  size_t len;
                  link = xml_get_content(line);
                  dirname = g_strconcat(g_get_home_dir(), 
                                    HISTORY_DIR,
                                    NULL);
                  len = strlen(dirname);
                  orig_uri = create_uri_from_filename(link + len);
                  uri = url_decode(orig_uri);
                  g_free(orig_uri);             
                  g_free(dirname);
                  g_free(link);
            }
            else if (!strncmp(line, "<title>", 7))
            {
                  title = xml_get_content(line);
            }
            else if (!strncmp(line, "<summary", 8))
            {
                  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 *
estsearch_get_search_result_bookmark (const gchar *text)
{
      gint out;

      if (!text) return NULL;
      if (!exists_estindex) return NULL;

      if (!execute_search_command(text, &out))
            return NULL;

      return create_search_result_bookmark(out, text);
}


Generated by  Doxygen 1.6.0   Back to index