;;; skk-search-web.el --- Google サジェストなどを利用したかな漢字変換 -*- coding: iso-2022-jp -*-

;; Copyright (C) 2010, 2011 HAMANO Kiyoto <khiker.mail@gmail.com>
;; Copyright (C) 2011 Tsuyoshi Kitamoto <tsuyoshi.kitamoto@gmail.com>

;; Author: HAMANO Kiyoto <khiker.mail@gmail.com>
;; Maintainer: Tsuyoshi Kitamoto <tsuyoshi.kitamoto@gmail.com>
;; Version: $Id: skk-search-web.el,v 1.1 2011/11/21 12:56:26 skk-cvs Exp $
;; Keywords: japanese, mule, input method
;; Last Modified: $Date: 2011/11/21 12:56:26 $

;; This file is part of Daredevil SKK.

;; Daredevil SKK 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.

;; Daredevil SKK 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 Daredevil SKK, see the file COPYING.  If not, write to
;; the Free Software Foundation Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.

;;; Commentary:

;; 使用方法を２つ説明します。好みの方を使用してください。

;; (1) かな漢字変換の候補に Google サジェストを利用する
;;     skk-search-prog-list の最後方に skk-search-web() を置くことにより、
;;     個人辞書や共有辞書に登録されていない見出し語を Google サジェスト
;;     します。
;;     (add-to-list 'skk-search-prog-list
;;                  '(skk-search-web 'skk-google-suggest)
;;                  t)

;; (2) 辞書登録モードへの突入時の初期値に Google サジェストを利用する
;;     (setq skk-read-from-minibuffer-function
;;           (lambda ()
;;             (car (skk-google-suggest skk-henkan-key))))

;;     ※関数 skk-google-suggest は skk-google-cgi-api-for-japanese-input や
;;                                  skk-wikipedia-suggest へ
;;       置き換え可能です。

;;; 謝辞
;;    もともとのオリジナルは HAMANO Kiyoto <khiker.mail@gmail.com> さんが
;;    書いた記事 http://d.hatena.ne.jp/khiker/20100128/google_suggest です。
;;    改変、公開を快く承諾していただいた HAMANO Kiyoto さんに感謝します。

;;; Code:

(require 'url-http)
(require 'json)

(defun skk-url-retrieve (url coding-system)
  "URL を取得する。戻り値は decode-coding-string である."
  (let (buf p)
    (unwind-protect
	(progn
	  (setq buf (let (
			  ;;(url-request-extra-headers
			  ;;	 '(("" . "")
			  ;;	   ("" . "")))
			  (url-request-method "GET")
			  (url-max-redirextions 0))
		      (url-retrieve-synchronously url)))
	  (when (setq p (url-http-symbol-value-in-buffer
			 'url-http-end-of-headers buf))
	    (with-current-buffer buf
	      (decode-coding-string (buffer-substring (1+ p)
						      (point-max))
				    coding-system))))
      (when buf
	(kill-buffer buf)))))


(defun skk-google-cgi-api-for-japanese-input (word)
  "Google CGI API for Japanese Input を利用したかな漢字変換.
http://www.google.com/intl/ja/ime/cgiapi.html"
  (let* ((jsonp (skk-url-retrieve
		 (concat "http://www.google.com/transliterate"
			 "?langpair=ja-Hira|ja"
			 "&text=" (url-hexify-string
				   (encode-coding-string (concat word ",")
							 'utf-8)))
		 'utf-8))
	 (json (json-read-from-string jsonp))
	 ;; [["みだしご" ["候補a" "候補b" "候補c"]]]
	 (ary (aref (aref json 0) 1))
	 list)
    (dotimes (i (length ary))
      (setq list (cons (aref ary i)
		       list)))
    (nreverse list)))


(defun skk-google-suggest (word)
  "Google サジェストを利用したかな漢字変換.
http://labs.google.com/intl/ja/suggestfaq.html"
  (let* ((jsonp (skk-url-retrieve
		 (concat "http://clients1.google.co.jp/complete/search"
			 "?hl=ja"
			 "&cp=2"
			 "&q=" (url-hexify-string
				(encode-coding-string word 'utf-8)))
		 'sjis))
	 (json (json-read-from-string (substring jsonp
						 19
						 (1- (length jsonp)))))
	 ;; ["みだしご" [["候補a" "" "0r"]
	 ;;              ["候補b" "" "1r"]
	 ;;              ["候補c" "" "2r"]] ((k . 1))]
	 (ary (aref json 1))
	 list)
    (dotimes (i (length ary))
      (setq list (cons (aref (aref ary i) 0)
		       list)))
    (nreverse list)))


(defun skk-wikipedia-suggest (word)
  (let* ((jsonp (skk-url-retrieve
		 (concat "http://ja.wikipedia.org/w/api.php"
			 "?action=opensearch"
			 "&format=json"
			 "&search=" (url-hexify-string
				     (encode-coding-string word 'utf-8)))
		 'utf-8))
	 (json (json-read-from-string jsonp))
	 ;; ["みだしご" ["候補a" "候補b" "候補c"]]
	 ;; ※「みだしご」が漢字であれば様々な候補が得られるが、
	 ;;   平仮名だとあまりヒットしない。そのため、かな漢字
	 ;;   変換の用途には不向きかも。
	 (ary (aref json 1))
	 list)
    (dotimes (i (length ary))
      (setq list (cons (aref ary i)
		       list)))
    (nreverse list)))


;; (defun skk-search-amazon-suggest (word)
;;   ""
;;   (let* ((jsonp (skk-url-retrieve
;; 		 (concat "http://completion.amazon.co.jp/search/complete"
;; 			 "?method=completion"
;; 			 "&search-alias=aps"
;; 			 "&mkt=6"
;; 			 "&q=" (url-hexify-string
;; 				     (encode-coding-string word 'utf-8)))
;; 		 'utf-8))
;; 	 (json  (json-read-from-string jsonp)))
;;     json))


;;;; for skk-search-prog-list

;; (add-to-list 'skk-search-prog-list
;; 	     '(skk-search-web 'skk-google-cgi-api-for-japanese-input)
;; 	     t)

;; (add-to-list 'skk-search-prog-list
;; 	     '(skk-search-web 'skk-google-suggest
;; 	     t)

(defun skk-search-web (function)
  (funcall function skk-henkan-key))


;;;; for 辞書登録モード
(setq skk-read-from-minibuffer-function
      (lambda ()
	(car
	 (skk-google-cgi-api-for-japanese-input skk-henkan-key)
;; 	 (skk-google-suggest skk-henkan-key)
	)))

(provide 'skk-search-web)

;;; skk-search-web.el ends here
