Clean code. Updated google custom search to handle quota limit and no query submit. Updated encoding issues for input searches: like "void safe" and "void + safe".
237 lines
7.5 KiB
Plaintext
237 lines
7.5 KiB
Plaintext
note
|
|
description: "[
|
|
Simple API to call Google Custome Search Engine
|
|
Example call:
|
|
GET https://www.googleapis.com/customsearch/v1?key=INSERT_YOUR_API_KEY&cx=017576662512468239146:omuauf_lfve&q=lectures
|
|
]"
|
|
date: "$Date: 2015-10-09 08:11:07 -0300 (vi., 09 oct. 2015) $"
|
|
revision: "$Revision: 97973 $"
|
|
EIS: "name=Google Custom Search Engine", "src=https://developers.google.com/custom-search/json-api/v1/using_rest", "protocol=uri"
|
|
|
|
class
|
|
GCSE_API
|
|
|
|
create
|
|
make
|
|
|
|
feature {NONE} -- Initialization
|
|
|
|
make (a_query_parameters: GCSE_QUERY_PARAMETERS)
|
|
-- Create an object GCSE with query_parameters `a_query_parameters'
|
|
do
|
|
query_parameter := a_query_parameters
|
|
ensure
|
|
query_parameters_set: query_parameter = a_query_parameters
|
|
end
|
|
|
|
feature -- Access
|
|
|
|
base_uri: STRING_8 = "https://www.googleapis.com/customsearch/v1"
|
|
-- Google custom search base URI.
|
|
|
|
query_parameter: GCSE_QUERY_PARAMETERS
|
|
-- Google custom search parameters.
|
|
|
|
last_result: detachable GCSE_RESPONSE
|
|
-- Search results.
|
|
|
|
feature -- Status Reports
|
|
|
|
errors: detachable LIST [READABLE_STRING_8]
|
|
-- optional list of error messages.
|
|
|
|
feature -- API
|
|
|
|
search
|
|
-- Search
|
|
local
|
|
l_parser: JSON_PARSER
|
|
l_gcse_response: detachable GCSE_RESPONSE
|
|
do
|
|
-- Data format for the response.
|
|
-- At the moment we are using the default value: json
|
|
-- but it's possible to define atom response using the alt parameter.
|
|
last_result := Void
|
|
if attached get as l_response then
|
|
create l_gcse_response
|
|
l_gcse_response.set_status (l_response.status)
|
|
l_gcse_response.set_status_nessage (l_response.status_message)
|
|
|
|
if attached l_response.body as l_body then
|
|
create l_parser.make_with_string (l_body)
|
|
l_parser.parse_content
|
|
if l_response.status = 200 and then l_parser.is_parsed and then attached {JSON_OBJECT} l_parser.parsed_json_object as jv then
|
|
-- Queries
|
|
if attached {JSON_OBJECT} jv.item (queries_key) as jqueries then
|
|
-- Next Page
|
|
if attached {GCSE_PAGE} query_page (next_page_key, jqueries) as l_page then
|
|
l_gcse_response.set_next_page (l_page)
|
|
end
|
|
-- Current Page
|
|
if attached {GCSE_PAGE} query_page (request_key, jqueries) as l_page then
|
|
l_gcse_response.set_current_page (l_page)
|
|
end
|
|
-- Previous Page
|
|
if attached {GCSE_PAGE} query_page (previous_page_key, jqueries) as l_page then
|
|
l_gcse_response.set_previous_page (l_page)
|
|
end
|
|
end
|
|
if attached {JSON_ARRAY} jv.item (items_key) as jitems then
|
|
across jitems as ic loop
|
|
if attached{JSON_OBJECT} ic.item as j_item then
|
|
l_gcse_response.add_item (item (j_item))
|
|
end
|
|
end
|
|
end
|
|
else
|
|
put_error (l_body)
|
|
end
|
|
else
|
|
put_error (l_response.status.out)
|
|
end
|
|
else
|
|
put_error ("unknown")
|
|
end
|
|
last_result := l_gcse_response
|
|
end
|
|
|
|
feature {NONE} -- REST API
|
|
|
|
get: detachable RESPONSE
|
|
-- Reading Data.
|
|
local
|
|
l_request: REQUEST
|
|
do
|
|
create l_request.make ("GET", new_uri)
|
|
Result := l_request.execute
|
|
end
|
|
|
|
feature {NONE} -- Implementation
|
|
|
|
new_uri: STRING_8
|
|
-- new uri (BaseUri?key=secret_value&cx=a_cx_id&q=a_query
|
|
-- ?key=INSERT_YOUR_API_KEY&cx=017576662512468239146:omuauf_lfve&q=lectures
|
|
-- full template BaseUri?q={searchTerms}&num={count?}&start={startIndex?}&lr={language?}&
|
|
-- safe={safe?}&cx={cx?}&cref={cref?}&sort={sort?}&filter={filter?}&gl={gl?}&cr={cr?}&
|
|
-- googlehost={googleHost?}&c2coff={disableCnTwTranslation?}&hq={hq?}&hl={hl?}&siteSearch={siteSearch?}&
|
|
-- siteSearchFilter={siteSearchFilter?}&exactTerms={exactTerms?}&excludeTerms={excludeTerms?}&linkSite={linkSite?}&
|
|
-- orTerms={orTerms?}&relatedSite={relatedSite?}&dateRestrict={dateRestrict?}&lowRange={lowRange?}&highRange={highRange?}&
|
|
-- searchType={searchType}&fileType={fileType?}&rights={rights?}&imgSize={imgSize?}&imgType={imgType?}&
|
|
-- imgColorType={imgColorType?}&imgDominantColor={imgDominantColor?}&alt=json"
|
|
|
|
do
|
|
create Result.make_from_string (base_uri)
|
|
Result.append ("?key=")
|
|
Result.append (query_parameter.secret)
|
|
Result.append ("&cx=")
|
|
Result.append (query_parameter.cx)
|
|
Result.append ("&q=")
|
|
Result.append (query_parameter.query)
|
|
-- num
|
|
if attached query_parameter.num as l_num then
|
|
Result.append ("&num=")
|
|
Result.append (l_num)
|
|
end
|
|
if attached query_parameter.start as l_start then
|
|
Result.append ("&start=")
|
|
Result.append (l_start)
|
|
end
|
|
end
|
|
|
|
put_error (a_message: READABLE_STRING_GENERAL)
|
|
-- put error message `a_message'.
|
|
local
|
|
l_errors: like errors
|
|
utf: UTF_CONVERTER
|
|
do
|
|
l_errors := errors
|
|
if l_errors = Void then
|
|
create {ARRAYED_LIST [STRING]} l_errors.make (1)
|
|
errors := l_errors
|
|
end
|
|
l_errors.force (utf.utf_32_string_to_utf_8_string_8 (a_message))
|
|
end
|
|
|
|
item (a_item: JSON_OBJECT): GCSE_PAGE_ITEM
|
|
-- Google Result Metadata Item.
|
|
do
|
|
create Result
|
|
if attached {JSON_STRING} a_item.item ("kind") as l_kind then
|
|
Result.set_kind (l_kind.item)
|
|
end
|
|
if attached {JSON_STRING} a_item.item ("title") as l_title then
|
|
Result.set_title (l_title.item)
|
|
end
|
|
if attached {JSON_STRING} a_item.item ("htmlTitle") as l_htmltitle then
|
|
Result.set_html_title (l_htmltitle.unescaped_string_32)
|
|
end
|
|
if attached {JSON_STRING} a_item.item ("link") as l_link then
|
|
Result.set_link (l_link.item)
|
|
end
|
|
if attached {JSON_STRING} a_item.item ("displayLink") as l_display_link then
|
|
Result.set_display_link (l_display_link.item)
|
|
end
|
|
if attached {JSON_STRING} a_item.item ("snippet") as l_snippet then
|
|
Result.set_snippet (l_snippet.unescaped_string_8)
|
|
end
|
|
if attached {JSON_STRING} a_item.item ("htmlSnippet") as l_html_snippet then
|
|
Result.set_html_snippet (l_html_snippet.unescaped_string_32)
|
|
end
|
|
if attached {JSON_STRING} a_item.item ("formattedUrl") as l_formatted_url then
|
|
Result.set_formatted_url (l_formatted_url.item)
|
|
end
|
|
end
|
|
|
|
query_page (a_page_key: JSON_STRING; a_queries: JSON_OBJECT): detachable GCSE_PAGE
|
|
-- Google result medata query. Return a query page based for a query with page key `a_page_key', if any.
|
|
do
|
|
if
|
|
attached {JSON_ARRAY} a_queries.item (a_page_key) as jquerypage and then
|
|
jquerypage.count > 0 and then
|
|
attached {JSON_OBJECT} jquerypage.i_th (1) as jpage
|
|
then
|
|
create Result
|
|
if attached {JSON_STRING} jpage.item ("title") as l_title then
|
|
Result.set_title (l_title.item)
|
|
end
|
|
if attached {JSON_STRING} jpage.item ("totalResults") as l_results then
|
|
Result.set_total_results (l_results.item.to_integer)
|
|
end
|
|
if attached {JSON_STRING} jpage.item ("searchTerms") as l_search_terms then
|
|
Result.set_search_terms (l_search_terms.item)
|
|
end
|
|
-- TODO check if we should use INTEGER_64
|
|
if attached {JSON_NUMBER} jpage.item ("count") as l_count then
|
|
Result.set_count (l_count.integer_64_item.as_integer_32)
|
|
end
|
|
if attached {JSON_NUMBER} jpage.item ("startIndex") as l_index then
|
|
Result.set_start_index (l_index.integer_64_item.as_integer_32)
|
|
end
|
|
end
|
|
end
|
|
|
|
feature {NONE} -- JSON Keys
|
|
|
|
queries_key: STRING = "queries"
|
|
|
|
next_page_key: STRING = "nextPage"
|
|
|
|
request_key: STRING = "request"
|
|
|
|
previous_page_key: STRING = "previousPage"
|
|
|
|
items_key: STRING = "items"
|
|
|
|
note
|
|
copyright: "2011-2015 Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
|
source: "[
|
|
Eiffel Software
|
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
|
Telephone 805-685-1006, Fax 805-685-6869
|
|
Website http://www.eiffel.com
|
|
Customer support http://support.eiffel.com
|
|
]"
|
|
|
|
end
|