Download
(require 'json)
(require 'url)
(defgroup DuckDuckGo nil "DuckDuckGo"
:group 'applications
:version "23.0"
:tag "DuckDuckGo"
)
(defcustom ddg-duckduckgo-url "http://api.duckduckgo.com"
"This is the URL where the query will be sended."
:group 'DuckDuckGo
:type 'string)
(defun ddg-search (term)
"Search for a term in the DuckDuckGo search engine.
Returns a list with parsed results."
(condition-case nil
(json-read-from-string (ddg-send-search-query term))
(error nil)
)
)
(defun ddg-search-asyn (term function)
"Same as `ddg-search' but asynchronous.
FUNCTION will be called as soon as the search finishes must recieve one parameter a string containing the results."
(ddg-send-search-query-asyn term function)
)
(defun ddg-send-search-query-asyn (term function)
"Send the search query and return the results.
This functions works *asynchronously*.
FUNCTION will be called with the result as parameter when the search is finished."
(let ((url-request-method "GET")
(url-request-data "")
(url-request-extra-headers
'(("Accept-Language" . "en")
("Accept-Charset" . "utf-8")))
(get-data
(mapconcat (lambda (arg)
(concat (url-hexify-string (car arg)) "=" (url-hexify-string (cdr arg))))
(list (cons "q" term)
(cons "format" "json")
)
"&"))
)
(url-retrieve (concat ddg-duckduckgo-url "/?" get-data) 'ddg-url-handler (list function))
)
)
(defun ddg-url-handler (state function)
"Handler function for `ddg-send-search-query-asyn'.
It deletes the HTTP header and parse the JSON code. The call the function FUNCTION with the result as a parameter."
(let ((results ""))
(ddg-delete-http-header)
(condition-case nil
(setq results (json-read))
(error nil))
(kill-buffer)
(apply function (list results))
)
)
(defun ddg-send-search-query (term)
"Send the search query and return the results.
This functions works *synchronously*."
(let ((url-request-method "GET")
(url-request-data "")
(url-request-extra-headers
'(("Accept-Language" . "en")
("Accept-Charset" . "utf-8")))
(get-data
(mapconcat (lambda (arg)
(concat (url-hexify-string (car arg)) "=" (url-hexify-string (cdr arg))))
(list (cons "q" term)
(cons "format" "json")
)
"&"))
)
(with-current-buffer (url-retrieve-synchronously (concat ddg-duckduckgo-url "/?" get-data))
(let ((results ""))
(ddg-delete-http-header)
(setq results (buffer-string))
(kill-buffer)
results
)
)
)
)
(defun ddg-delete-http-header ()
"Delete the HTTP header in the current buffer."
(goto-char (point-min))
(let ((beg (point-min))
(end (search-forward "\n\n" nil t)))
(when end
(delete-region beg end)
)
)
)
(provide 'ddg)