Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
  3.  *
  4.  * This file is part of NetSurf, http://www.netsurf-browser.org/
  5.  *
  6.  * NetSurf 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; version 2 of the License.
  9.  *
  10.  * NetSurf is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  */
  18.  
  19.  /** \file
  20.  * web search (core)
  21.  */
  22. #include "utils/config.h"
  23.  
  24. #include <ctype.h>
  25. #include <string.h>
  26. #include "content/content.h"
  27. #include "content/hlcache.h"
  28. #include "desktop/browser.h"
  29. #include "desktop/gui.h"
  30. #include "desktop/options.h"
  31. #include "desktop/searchweb.h"
  32. #include "utils/config.h"
  33. #include "utils/log.h"
  34. #include "utils/messages.h"
  35. #include "utils/url.h"
  36. #include "utils/utils.h"
  37.  
  38. static struct search_provider {
  39.         char *name; /**< readable name such as 'google', 'yahoo', etc */
  40.         char *hostname; /**< host address such as www.google.com */
  41.         char *searchstring; /** < such as "www.google.com?search=%s" */
  42.         char *ico; /** < location of domain's favicon */
  43. } current_search_provider;
  44.  
  45. static hlcache_handle *search_ico = NULL;
  46. char *search_engines_file_location;
  47. char *search_default_ico_location;
  48.  
  49. #ifdef WITH_BMP
  50. static nserror search_web_ico_callback(hlcache_handle *ico,
  51.                 const hlcache_event *event, void *pw);
  52. #endif
  53.  
  54. /**
  55.  * creates a new browser window according to the search term
  56.  * \param searchterm such as "my search term"
  57.  */
  58.  
  59. bool search_web_new_window(struct browser_window *bw, const char *searchterm)
  60. {
  61.         char *encsearchterm;
  62.         char *url;
  63.         if (url_escape(searchterm,0, true, NULL, &encsearchterm) !=
  64.                         URL_FUNC_OK)
  65.                 return false;
  66.         url = search_web_get_url(encsearchterm);
  67.         free(encsearchterm);
  68.         browser_window_create(url, bw, NULL, true, true);
  69.         free(url);
  70.         return true;
  71. }
  72.  
  73. /** simplistic way of checking whether an entry from the url bar is an
  74.  * url / a search; could be improved to properly test terms
  75.  */
  76.  
  77. bool search_is_url(const char *url)
  78. {
  79.         /** \todo Implement this properly */
  80.  
  81.         /* For now, everything is an URL */
  82.         return true;
  83. }
  84.  
  85. /**
  86.  * caches the details of the current web search provider
  87.  * \param reference the enum value of the provider
  88.  * browser init code [as well as changing preferences code] should call
  89.  * search_web_provider_details(option_search_provider)
  90.  */
  91.  
  92. void search_web_provider_details(int reference)
  93. {
  94.         char buf[300];
  95.         int ref = 0;
  96.         FILE *f;
  97.         if (search_engines_file_location == NULL)
  98.                 return;
  99.         f = fopen(search_engines_file_location, "r");
  100.         if (f == NULL)
  101.                 return;
  102.         while (fgets(buf, sizeof(buf), f) != NULL) {
  103.                 if (buf[0] == '\0')
  104.                         continue;
  105.                 buf[strlen(buf)-1] = '\0';
  106.                 if (ref++ == (int)reference)
  107.                         break;
  108.         }
  109.         fclose(f);
  110.         if (current_search_provider.name != NULL)
  111.                 free(current_search_provider.name);
  112.         current_search_provider.name = strdup(strtok(buf, "|"));
  113.         if (current_search_provider.hostname != NULL)
  114.                 free(current_search_provider.hostname);
  115.         current_search_provider.hostname = strdup(strtok(NULL, "|"));
  116.         if (current_search_provider.searchstring != NULL)
  117.                 free(current_search_provider.searchstring);
  118.         current_search_provider.searchstring = strdup(strtok(NULL, "|"));
  119.         if (current_search_provider.ico != NULL)
  120.                 free(current_search_provider.ico);
  121.         current_search_provider.ico = strdup(strtok(NULL, "|"));
  122.         return;
  123. }
  124.  
  125. /**
  126.  * escapes a search term then creates the appropriate url from it
  127.  */
  128.  
  129. char *search_web_from_term(const char *searchterm)
  130. {
  131.         char *encsearchterm, *url;
  132.         if (url_escape(searchterm, 0, true, NULL, &encsearchterm)
  133.                         != URL_FUNC_OK)
  134.                 return strdup(searchterm);
  135.         url = search_web_get_url(encsearchterm);
  136.         free(encsearchterm);
  137.         return url;
  138. }
  139.  
  140. /** accessor for global search provider name */
  141.  
  142. char *search_web_provider_name(void)
  143. {
  144.         if (current_search_provider.name)
  145.                 return strdup(current_search_provider.name);
  146.         return strdup("google");
  147. }
  148.  
  149. /** accessor for global search provider hostname */
  150.  
  151. char *search_web_provider_host(void)
  152. {
  153.         if (current_search_provider.hostname)
  154.                 return strdup(current_search_provider.hostname);
  155.         return strdup("www.google.com");
  156. }
  157.  
  158. /** accessor for global search provider ico name */
  159.  
  160. char *search_web_ico_name(void)
  161. {
  162.         if (current_search_provider.ico)
  163.                 return strdup(current_search_provider.ico);
  164.         return strdup("http://www.google.com/favicon.ico");
  165. }
  166.  
  167. /**
  168.  * creates a full url from an encoded search term
  169.  */
  170.  
  171. char *search_web_get_url(const char *encsearchterm)
  172. {
  173.         char *pref, *ret;
  174.         int len;
  175.         if (current_search_provider.searchstring)
  176.                 pref = strdup(current_search_provider.searchstring);
  177.         else
  178.                 pref = strdup("http://www.google.com/search?q=%s");
  179.         if (pref == NULL) {
  180.                 warn_user(messages_get("NoMemory"), 0);
  181.                 return NULL;
  182.         }
  183.         len = strlen(encsearchterm) + strlen(pref);
  184.         ret = malloc(len -1); /* + '\0' - "%s" */
  185.         if (ret == NULL) {
  186.                 warn_user(messages_get("NoMemory"), 0);
  187.                 free(pref);
  188.                 return NULL;
  189.         }
  190.         snprintf(ret, len-1, pref, encsearchterm);
  191.         free(pref);
  192.         return ret;
  193. }
  194.  
  195. /**
  196.  * function to retrieve the search web ico, from cache / from local
  197.  * filesystem / from the web
  198.  * \param localdefault true when there is no appropriate favicon
  199.  * update the search_ico cache else delay until fetcher callback
  200.  */
  201.  
  202. void search_web_retrieve_ico(bool localdefault)
  203. {
  204. #if !defined(WITH_BMP)
  205.         /* This function is of limited use when no BMP support
  206.          * is enabled, given the icons it is fetching are BMPs
  207.          * more often than not.  This also avoids an issue where
  208.          * all this code goes mad if BMP support is not enabled.
  209.          */
  210.         return;
  211. #else
  212.         content_type accept = CONTENT_IMAGE;
  213.         char *url;
  214.         nserror error;
  215.         nsurl *icon_nsurl;
  216.  
  217.         if (localdefault) {
  218.                 if (search_default_ico_location == NULL)
  219.                         return;
  220.                 url = malloc(SLEN("file://") + strlen(
  221.                                 search_default_ico_location) + 1);
  222.                 if (url == NULL) {
  223.                         warn_user(messages_get("NoMemory"), 0);
  224.                         return;
  225.                 }
  226.                 strcpy(url, "file://");
  227.                 strcat(url, search_default_ico_location);
  228.         } else {
  229.                 url = search_web_ico_name();
  230.         }
  231.  
  232.         if (url == NULL) {
  233.                 warn_user(messages_get("NoMemory"), 0);
  234.                 return;
  235.         }
  236.  
  237.         error = nsurl_create(url, &icon_nsurl);
  238.         if (error != NSERROR_OK) {
  239.                 free(url);
  240.                 search_ico = NULL;
  241.                 return;
  242.         }
  243.  
  244.         error = hlcache_handle_retrieve(icon_nsurl, 0, NULL, NULL,
  245.                         search_web_ico_callback, NULL, NULL, accept,
  246.                         &search_ico);
  247.  
  248.         nsurl_unref(icon_nsurl);
  249.  
  250.         if (error != NSERROR_OK)
  251.                 search_ico = NULL;
  252.  
  253.         free(url);
  254. #endif /* WITH_BMP */
  255. }
  256.  
  257. /**
  258.  * returns a reference to the static global search_ico [ / NULL]
  259.  * caller may adjust ico's settings; clearing / free()ing is the core's
  260.  * responsibility
  261.  */
  262.  
  263. hlcache_handle *search_web_ico(void)
  264. {
  265.         return search_ico;
  266. }
  267.  
  268. /**
  269.  * Cleans up any remaining resources during shutdown.
  270.  */
  271. void search_web_cleanup(void)
  272. {
  273.         if (search_ico != NULL) {
  274.                 hlcache_handle_release(search_ico);
  275.                 search_ico = NULL;
  276.         }
  277. }
  278.  
  279. /**
  280.  * callback function to cache ico then notify front when successful
  281.  * else retry default from local file system
  282.  */
  283.  
  284. #ifdef WITH_BMP
  285. nserror search_web_ico_callback(hlcache_handle *ico,
  286.                 const hlcache_event *event, void *pw)
  287. {
  288.         switch (event->type) {
  289.         case CONTENT_MSG_LOADING:
  290.         case CONTENT_MSG_READY:
  291.                 break;
  292.  
  293.         case CONTENT_MSG_DONE:
  294.                 LOG(("got favicon '%s'", nsurl_access(hlcache_handle_get_url(ico))));
  295.                 gui_window_set_search_ico(search_ico);
  296.                 break;
  297.  
  298.         case CONTENT_MSG_ERROR:
  299.                 LOG(("favicon %s error: %s",
  300.                                 nsurl_access(hlcache_handle_get_url(ico)),
  301.                                 event->data.error));
  302.                 hlcache_handle_release(search_ico);
  303.                 search_ico = NULL;
  304.                 search_web_retrieve_ico(true);
  305.                 break;
  306.  
  307.         case CONTENT_MSG_STATUS:
  308.                 break;
  309.  
  310.         default:
  311.                 assert(0);
  312.         }
  313.  
  314.         return NSERROR_OK;
  315. }
  316. #endif /* WITH_BMP */
  317.