summaryrefslogtreecommitdiff
path: root/elisp/erbot/contrib/google.el
diff options
context:
space:
mode:
Diffstat (limited to 'elisp/erbot/contrib/google.el')
-rw-r--r--elisp/erbot/contrib/google.el271
1 files changed, 271 insertions, 0 deletions
diff --git a/elisp/erbot/contrib/google.el b/elisp/erbot/contrib/google.el
new file mode 100644
index 0000000..d940119
--- /dev/null
+++ b/elisp/erbot/contrib/google.el
@@ -0,0 +1,271 @@
+;;; Debugging info for self: Saved through ges-version 1.5dev
+;;; ;;; From: Edward O'Connor <ted@oconnor.cx>
+;;; ;;; Subject: google.el
+;;; ;;; Newsgroups: gnu.emacs.sources
+;;; ;;; Date: Sat, 14 Sep 2002 10:37:56 GMT
+;;; ;;; Organization: RoadRunner - West
+
+;;; > google.el --- Emacs interface to the Google API
+
+;;; Virtually unchanged; just fixed a remarkably embarassing bug.
+
+;;;
+
+;;; google.el --- Emacs interface to the Google API
+
+;; Copyright (C) 2002 Edward O'Connor <ted@oconnor.cx>
+
+;; Author: Edward O'Connor <ted@oconnor.cx>
+;; Keywords: comm, processes, tools
+;; Version: 0.1
+
+;; This file 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 3, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; A really bare-bones first hack at Google API support for Emacs.
+;; Note that you need a Google license key to use this; you can
+;; get one by following the instructions here:
+
+;; <URL:http://www.google.com/apis/>
+
+;; Usage:
+
+;; (require 'google)
+;; (setq google-license-key "my license key")
+;; Then M-x google-search RET
+;; or M-x google-search-region RET
+
+;; To use this in a program, see the functions `google-search' and
+;; `google-display-response' for example usage.
+
+;;; Code:
+
+(require 'soap)
+(require 'xml)
+
+(defgroup google nil
+ ""
+ :group 'tools)
+
+(defcustom google-license-key nil
+ "*Your Google license key."
+ :type '(string)
+ :group 'google)
+
+(defcustom google-search-result-callback nil
+ "*The function to be called with the search result."
+ :type '(function)
+ :group 'google)
+
+(defcustom google-start 0
+ "*Which result to start with."
+ :type 'integer
+ :group 'google)
+
+(defcustom google-max-results 10
+ "*Maximum number of results to return."
+ :type 'integer
+ :group 'google)
+
+(defcustom google-filter-p t
+ "*Whether or not to filter results."
+ :type 'boolean
+ :group 'google)
+
+(defcustom google-safe-p nil
+ "*Safe or not?"
+ :type 'boolean
+ :group 'google)
+
+(defcustom google-linkify-links-p t
+ "*Whether or not we should linkify links in the response buffer."
+ :type 'boolean
+ :group 'google)
+
+(defun google-xml-sexp-attr-to-xml (attr-cons)
+ (let ((attr-name (car attr-cons))
+ (attr-val (cdr attr-cons)))
+ (unless (stringp attr-val)
+ (setq attr-val (format "%s" attr-val)))
+ (concat (format " %s=" attr-name)
+ (if (string-match "[\"]" attr-val)
+ (format "'%s'" attr-val)
+ (format "\"%s\"" attr-val)))))
+
+(defun google-xml-sexp-to-xml (xml-sexp)
+ "Return a string containing an XML representation of XML-SEXP."
+ (cond ((null xml-sexp)
+ "")
+ ((stringp xml-sexp)
+ xml-sexp)
+ ((listp xml-sexp)
+ (let ((tag (xml-node-name xml-sexp))
+ (attrs (xml-node-attributes xml-sexp))
+ (children (xml-node-children xml-sexp)))
+ (concat (format "<%s" tag)
+ (if attrs
+ (mapconcat 'google-xml-sexp-attr-to-xml
+ attrs
+ "")
+ "")
+ (if children
+ (concat ">"
+ (mapconcat 'google-xml-sexp-to-xml
+ children
+ "")
+ (format "</%s>" tag))
+ "/>"))))
+
+ (t (google-xml-sexp-to-xml (format "%s" xml-sexp)))))
+
+(defun google-request (xml-sexp)
+ "Send XML-SEXP to Google as a request."
+ (soap-request "http://api.google.com/search/beta2"
+ (google-xml-sexp-to-xml xml-sexp)))
+
+(defun google-search-internal (terms start max-results filter-p safe-p)
+ "Search for TERMS."
+ (google-request
+ `(SOAP-ENV:Envelope ((xmlns:SOAP-ENV
+ . "http://schemas.xmlsoap.org/soap/envelope/")
+ (xmlns:xsi
+ . "http://www.w3.org/1999/XMLSchema-instance")
+ (xmlns:xsd . "http://www.w3.org/1999/XMLSchema"))
+ (SOAP-ENV:Body ()
+ (ns1:doGoogleSearch ((xmlns:ns1 . "urn:GoogleSearch")
+ (SOAP-ENV:encodingStyle .
+ "http://schemas.xmlsoap.org/soap/encoding/"))
+ (key ((xsi:type . "xsd:string"))
+ ,google-license-key)
+ (q ((xsi:type . "xsd:string"))
+ ,terms)
+ (start ((xsi:type . "xsd:int"))
+ ,(format "%d" start))
+ (maxResults ((xsi:type . "xsd:int"))
+ ,(format "%d" max-results))
+ (filter ((xsi:type . "xsd:boolean"))
+ ,(if filter-p "true" "false"))
+ (restrict ((xsi:type . "xsd:string")))
+ (safeSearch ((xsi:type . "xsd:boolean"))
+ ,(if safe-p "true" "false"))
+ (lr ((xsi:type . "xsd:string")))
+ (ie ((xsi:type . "xsd:string"))
+ "latin1")
+ (oe ((xsi:type . "xsd:string"))
+ "latin1"))))))
+
+(defvar google-result-mode-map (make-sparse-keymap)
+ "Map to be used in `google-result-mode'.")
+
+(define-key google-result-mode-map "q" 'google-result-quit)
+
+(defun google-result-quit ()
+ (interactive)
+ (kill-buffer (get-buffer-create "*google-response*")))
+
+(defun google-result-mode ()
+ (kill-all-local-variables)
+ (setq major-mode 'google-result-mode
+ mode-name "Google Result")
+ (set (make-local-variable 'font-lock-defaults)
+ '(message-font-lock-keywords t))
+ (use-local-map google-result-mode-map))
+
+(defun google-display-response (processed-response)
+ (with-current-buffer (get-buffer-create "*google-response*")
+ (delete-region (point-min)
+ (point-max))
+ (google-result-mode)
+ (insert (format "Google search results for %S\n" (car processed-response))
+ "-------------------------------------------------\n\n")
+ (setq processed-response (cdr processed-response))
+ (while processed-response
+ (let* ((item (car processed-response))
+ (url (nth 0 item))
+ (title (nth 1 item))
+ (hostname (nth 2 item))
+ (cached-size (nth 3 item))
+ (snippet (nth 4 item)))
+
+ (when title
+ (insert (format "Title: %s\n" title)))
+
+ (when url
+ (insert (format "URL: %s\n" url)))
+
+ (when hostname
+ (insert (format "Hostname: %s\n" hostname)))
+
+ (when cached-size
+ (insert (format "Size: %s\n" cached-size)))
+
+ (when snippet
+ (insert (format "Snippet: %s\n" snippet)))
+
+ (insert "\n"))
+
+ (setq processed-response (cdr processed-response)))
+ (when google-linkify-links-p
+ (goto-address))
+ (switch-to-buffer (current-buffer))))
+
+(defun google-process-response (response)
+ (let* ((body (car (xml-get-children (car response) 'SOAP-ENV:Body)))
+ (g-s-r (car (xml-get-children body 'ns1:doGoogleSearchResponse)))
+ (return (car (xml-get-children g-s-r 'return)))
+ (search-query (nth 2 (car (xml-get-children return 'searchQuery))))
+ (r-e (car (xml-get-children return 'resultElements)))
+ (items (xml-get-children r-e 'item))
+ (retval '()))
+
+ (while items
+ (let* ((item (car items))
+ (hostname (nth 2 (car (xml-get-children item 'hostName))))
+ (url (nth 2 (car (xml-get-children item 'URL))))
+ (title (nth 2 (car (xml-get-children item 'title))))
+ (snippet (nth 2 (car (xml-get-children item 'snippet))))
+ (cached-size (nth 2 (car (xml-get-children item 'cachedSize))))
+ (retval-item '()))
+
+ (add-to-list 'retval-item url t)
+ (add-to-list 'retval-item title t)
+ (add-to-list 'retval-item hostname t)
+ (add-to-list 'retval-item cached-size t)
+ (add-to-list 'retval-item snippet t)
+
+ (add-to-list 'retval retval-item)
+
+ (setq items (cdr items))))
+
+ (cons search-query retval)))
+
+(defun google-search (terms)
+ "Search for TERMS."
+ (interactive "sGoogle search: ")
+ (google-display-response
+ (google-process-response
+ (google-search-internal terms google-start google-max-results
+ google-filter-p google-safe-p))))
+
+(defun google-search-region (beg end)
+ "Perform a Google search on the words from BEG to END."
+ (interactive "r")
+ (google-search (buffer-substring-no-properties beg end)))
+
+(provide 'google)
+;;; google.el ends here
+