Compare commits

...

12 Commits

Author SHA1 Message Date
2a4ebfa12e Updated google search libary ecf files to have better void-safe .ecf file. 2015-11-02 14:22:41 +01:00
955852747a Include google_search engine in example/demo installation script. 2015-11-02 11:18:45 +01:00
23fe22cad1 Google search module:
- cleanup unwanted file
- fixed bad indentation in html template.
2015-11-02 11:16:54 +01:00
da4b36869a Include the launcher during installation (install.bat). 2015-11-02 10:50:27 +01:00
5624892ebc Updated code related to cache management in CMS core and modules. 2015-11-02 10:50:05 +01:00
jvelilla
e40a7969fa Merge branch 'jvelilla-roc_gcse' 2015-10-26 10:51:51 -03:00
jvelilla
67fdd357df Merge branch 'master' of https://github.com/EiffelWebFramework/ROC into roc_gcse
Conflicts:
	examples/demo/demo-safe.ecf
2015-10-23 16:48:25 -03:00
5b0ab76434 Fixed more unicode issues, or being more flexible when loading from database. 2015-10-20 19:02:04 +02:00
jvelilla
193760b34f Remove unneeded file. 2015-10-14 11:57:06 -03:00
jvelilla
9263f31521 Renamed module name to google_search (custom_search)
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".
2015-10-14 11:51:59 -03:00
jvelilla
454d92f85b Merge https://github.com/EiffelWebFramework/ROC into roc_gcse 2015-10-14 11:45:33 -03:00
jvelilla
0e63c14613 Added Module Custom Search
Added Google custom search library
Added HTTP client extension libaray
Updated demo example to use the Module Custom Search
2015-10-13 10:23:30 -03:00
41 changed files with 2015 additions and 46 deletions

View File

@@ -26,11 +26,13 @@
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/> <library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
<library name="cms_email_service" location="..\..\library\email\email-safe.ecf" readonly="false"/> <library name="cms_email_service" location="..\..\library\email\email-safe.ecf" readonly="false"/>
<library name="cms_feed_aggregator_module" location="..\..\modules\feed_aggregator\feed_aggregator-safe.ecf" readonly="false"/> <library name="cms_feed_aggregator_module" location="..\..\modules\feed_aggregator\feed_aggregator-safe.ecf" readonly="false"/>
<library name="cms_google_search_module" location="..\..\modules\google_search\google_search-safe.ecf" readonly="false" use_application_options="true"/>
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/> <library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="cms_node_module" location="..\..\modules\node\node-safe.ecf" readonly="false"/> <library name="cms_node_module" location="..\..\modules\node\node-safe.ecf" readonly="false"/>
<library name="cms_oauth_20_module" location="..\..\modules\oauth20\oauth20-safe.ecf" readonly="false"/> <library name="cms_oauth_20_module" location="..\..\modules\oauth20\oauth20-safe.ecf" readonly="false"/>
<library name="cms_openid_module" location="..\..\modules\openid\openid-safe.ecf" readonly="false"/> <library name="cms_openid_module" location="..\..\modules\openid\openid-safe.ecf" readonly="false"/>
<library name="cms_recent_changes_module" location="..\..\modules\recent_changes\recent_changes-safe.ecf" readonly="false"/> <library name="cms_recent_changes_module" location="..\..\modules\recent_changes\recent_changes-safe.ecf" readonly="false"/>
<library name="persistence_sqlite3" location="..\..\library\persistence\sqlite3\sqlite3-safe.ecf" readonly="false"> <library name="persistence_sqlite3" location="..\..\library\persistence\sqlite3\sqlite3-safe.ecf" readonly="false">
<option> <option>
<assertions/> <assertions/>

View File

@@ -11,3 +11,4 @@ set ROC_CMS_DIR=%~dp0
%ROC_CMD% install --module ..\..\modules\openid --dir %ROC_CMS_DIR% %ROC_CMD% install --module ..\..\modules\openid --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\recent_changes --dir %ROC_CMS_DIR% %ROC_CMD% install --module ..\..\modules\recent_changes --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\feed_aggregator --dir %ROC_CMS_DIR% %ROC_CMD% install --module ..\..\modules\feed_aggregator --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\google_search --dir %ROC_CMS_DIR%

View File

@@ -0,0 +1,6 @@
{
"gcse": {
"cx":"",
"secret_key":""
}
}

View File

@@ -0,0 +1,40 @@
<section>
<header>
<h2>Results for <kbd>{$result.current_page.search_terms/}</kbd></h2>
</header>
<!-- list of results -->
<ol start="{$result.current_page.start_index/}">
<!-- Item result -->
{foreach from="$result.items" item="item"}
<li>
<article>
<header>
<h3>
<cite>
<a href="{$item.link/}">{$item.title/}</a>
</cite>
</h3>
</header>
<blockquote cite="{$item.link/}">
<p>{$item.html_snippet/}</p>
<footer>
<p><abbr title="Uniform Resource Locator">Source</abbr> <a href="{$item.link/}">{$item.display_link/}</a></p>
</footer>
</blockquote>
</article>
</li>
{/foreach}
</ol>
<ul class="cms-page-links">
{if isset="$result.previous_page"}
<li><a href="{$site_url/}gcse/?q={$result.previous_page.search_terms/}&amp;start={$result.previous_page.start_index/}&amp;num={$result.previous_page.count/}">Previous</a></li>
{/if}
{if isset="$result.next_page"}
<li><a href="{$site_url/}gcse/?q={$result.next_page.search_terms/}&amp;start={$result.next_page.start_index/}&amp;num={$result.next_page.count/}">Next</a></li>
{/if}
</ul>
</section>

View File

@@ -0,0 +1,8 @@
$(document).ready(function() {
$('#gcse_search_form').submit(function() {
window.open('', 'formpopup', 'width=600,height=600,resizeable,scrollbars');
this.target = 'formpopup';
});
});

View File

@@ -5,9 +5,10 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- EWF CMS --> <!-- EWF CMS -->
<link rel="stylesheet" href="{$site_url/}theme/css/style.css"> <link rel="stylesheet" href="{$site_url/}theme/css/style.css">
<!-- jQuery dep --> <!-- jQuery dep -->
<script src="{$site_url/}theme/js/jquery-1.10.2.min.js"></script> <script src="{$site_url/}theme/js/jquery-1.10.2.min.js"></script>
<script src="{$site_url/}theme/js/popup_search.js"></script>
{if isset="$head"}{$head/}{/if} {if isset="$head"}{$head/}{/if}
{if isset="$styles"}{$styles/}{/if} {if isset="$styles"}{$styles/}{/if}
@@ -36,7 +37,17 @@
{$page.primary_nav/} {$page.primary_nav/}
{/if} {/if}
</div> </div>
<!-- Page search -->
<div class="row">
<div class="col-md-2 col-md-offset-9">
<form action="{$site_url/}gcse" class="search-form" id="gcse_search_form">
<div class="form-group has-feedback">
<input type="search" class="form-control" name="q" id="gcse_search" placeholder="search">
<span class="glyphicon glyphicon-search form-control-feedback"></span>
</div>
</form>
</div>
</div>
<!-- General Page Content --> <!-- General Page Content -->
<div id='content' class='row-fluid'> <div id='content' class='row-fluid'>
<!-- Left Sidebar sidebar_first --> <!-- Left Sidebar sidebar_first -->

View File

@@ -82,6 +82,9 @@ feature -- CMS modules
create {CMS_DEMO_MODULE} m.make create {CMS_DEMO_MODULE} m.make
a_setup.register_module (m) a_setup.register_module (m)
create {GOOGLE_CUSTOM_SEARCH_MODULE} m.make
a_setup.register_module (m)
end end
end end

4
library/gcse/Readme.md Normal file
View File

@@ -0,0 +1,4 @@
Google Custom Search Engine Eiffel Lbrary
Based on https://developers.google.com/custom-search/json-api/v1/using_rest

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-14-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-14-0 http://www.eiffel.com/developers/xml/configuration-1-14-0.xsd" name="gcse" uuid="30466429-C24A-40E8-957F-F245992A7A9F" library_target="gcse">
<target name="gcse">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" void_safety="all">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="http_client_extension" location="..\http_client_extension\http_client_extension-safe.ecf" readonly="false"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="wsf_encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
<cluster name="gcse" location=".\src\" recursive="true"/>
</target>
</system>

21
library/gcse/gcse.ecf Normal file
View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-14-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-14-0 http://www.eiffel.com/developers/xml/configuration-1-14-0.xsd" name="gcse" uuid="0B73AB16-3D8A-45EA-84B7-B11BBE4BA80A" library_target="gcse">
<target name="gcse">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" void_safety="none">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="http_client_extension" location="..\http_client_extension\http_client_extension.ecf" readonly="false"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
<library name="wsf_encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/>
<cluster name="gcse" location=".\src\" recursive="true"/>
</target>
</system>

10
library/gcse/license.lic Normal file
View File

@@ -0,0 +1,10 @@
${NOTE_KEYWORD}
copyright: "2011-${YEAR} 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
]"

236
library/gcse/src/gcse_api.e Normal file
View File

@@ -0,0 +1,236 @@
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

View File

@@ -0,0 +1,118 @@
note
description: "Represent metadata describing the query for the current set of results."
date: "$Date: 2015-10-09 08:11:07 -0300 (vi., 09 oct. 2015) $"
revision: "$Revision: 97973 $"
class
GCSE_PAGE
inherit
DEBUG_OUTPUT
feature -- Access
search_terms: detachable STRING_8
-- search term
title: detachable STRING_8
-- Search title.
total_results: INTEGER
-- Search total results.
count: INTEGER
-- Rows per page.
start_index: INTEGER
-- Page index.
feature -- Element change
set_search_terms (a_search_terms: like search_terms)
-- Assign `search_terms' with `a_search_terms'.
do
search_terms := a_search_terms
ensure
search_terms_assigned: search_terms = a_search_terms
end
feature -- Change element
set_title (a_title: like title)
-- Set title with `a_title'
do
title := a_title
ensure
title_set: title = a_title
end
set_total_results (a_total_results: like total_results)
-- Set total_results with `a_total_results'.
do
total_results := a_total_results
ensure
total_results_set: total_results = a_total_results
end
set_count (a_count: like count)
-- Set count with `a_count'.
do
count := a_count
ensure
count_set: count = a_count
end
set_start_index (a_start_index: like start_index)
-- Set start_index with `a_start_index'.
do
start_index := a_start_index
ensure
start_index_set: start_index = a_start_index
end
feature -- Status report
debug_output: STRING_8
-- <Precursor>
do
create Result.make_from_string ("%NPage details%N")
if attached title as l_title then
Result.append ("Title:")
Result.append (l_title)
Result.append_character ('%N')
end
if attached search_terms as l_search_tearm then
Result.append ("Search Tearm:")
Result.append (l_search_tearm)
Result.append_character ('%N')
end
Result.append ("Count:")
Result.append (count.out)
Result.append_character ('%N')
Result.append ("Total Result:")
Result.append (count.out)
Result.append_character ('%N')
Result.append ("Count:")
Result.append (total_results.out)
Result.append_character ('%N')
Result.append ("Start index:")
Result.append (start_index.out)
Result.append_character ('%N')
end
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

View File

@@ -0,0 +1,209 @@
note
description: "Represent a search result, include the URL, title and text snippets that describe the result"
date: "$Date: 2015-10-09 08:11:07 -0300 (vi., 09 oct. 2015) $"
revision: "$Revision: 97973 $"
class
GCSE_PAGE_ITEM
inherit
DEBUG_OUTPUT
feature -- Access
html_formatted_url: detachable STRING_8
-- Html formatted url of this result
formatted_url: detachable STRING_8
-- Formatted url of this result
cache_id: detachable STRING_8
-- Cache id of this result
html_snippet: detachable STRING_8
-- Html snippet of this request
snippet: detachable STRING_8
-- Snippet of this result
display_link: detachable STRING_8
-- Display link of this result
link: detachable STRING_8
-- link of this result
html_title: detachable STRING_8
-- html title of result
title: detachable STRING_8
-- title of result.
kind: detachable STRING_8
-- Kind of actual search result.
page_map: detachable GCSE_PAGE_MAP
-- Page map
--! Not supported for now.
feature -- Element change
set_html_formatted_url (a_html_formatted_url: like html_formatted_url)
-- Assign `html_formatted_url' with `a_html_formatted_url'.
do
html_formatted_url := a_html_formatted_url
ensure
html_formatted_url_assigned: html_formatted_url = a_html_formatted_url
end
set_formatted_url (a_formatted_url: like formatted_url)
-- Assign `formatted_url' with `a_formatted_url'.
do
formatted_url := a_formatted_url
ensure
formatted_url_assigned: formatted_url = a_formatted_url
end
set_cache_id (a_cache_id: like cache_id)
-- Assign `cache_id' with `a_cache_id'.
do
cache_id := a_cache_id
ensure
cache_id_assigned: cache_id = a_cache_id
end
set_html_snippet (a_html_snippet: like html_snippet)
-- Assign `html_snippet' with `a_html_snippet'.
do
html_snippet := a_html_snippet
ensure
html_snippet_assigned: html_snippet = a_html_snippet
end
set_snippet (a_snippet: like snippet)
-- Assign `snippet' with `a_snippet'.
do
snippet := a_snippet
ensure
snippet_assigned: snippet = a_snippet
end
set_display_link (a_display_link: like display_link)
-- Assign `display_link' with `a_display_link'.
do
display_link := a_display_link
ensure
display_link_assigned: display_link = a_display_link
end
set_link (a_link: like link)
-- Assign `link' with `a_link'.
do
link := a_link
ensure
link_assigned: link = a_link
end
set_html_title (a_html_title: like html_title)
-- Assign `html_title' with `a_html_title'.
do
html_title := a_html_title
ensure
html_title_assigned: html_title = a_html_title
end
set_title (a_title: like title)
-- Assign `title' with `a_title'.
do
title := a_title
ensure
title_assigned: title = a_title
end
set_kind (a_kind: like kind)
-- Assign `kind' with `a_kind'.
do
kind := a_kind
ensure
kind_assigned: kind = a_kind
end
set_page_map (a_map: like page_map)
-- Assign `kind' with `a_kind'.
do
page_map := a_map
ensure
page_map_assigned: page_map = a_map
end
feature -- Output
debug_output: STRING_8
-- <Precursor>
do
create Result.make_from_string ("%NPage Item details%N")
if attached title as l_title then
Result.append ("Title:")
Result.append (l_title)
Result.append_character ('%N')
end
if attached kind as l_kind then
Result.append ("Kind:")
Result.append (l_kind)
Result.append_character ('%N')
end
if attached html_title as l_html_title then
Result.append ("Html title:")
Result.append (l_html_title)
Result.append_character ('%N')
end
if attached link as l_link then
Result.append ("Link:")
Result.append (l_link)
Result.append_character ('%N')
end
if attached display_link as l_display_link then
Result.append ("Display link:")
Result.append (l_display_link)
Result.append_character ('%N')
end
if attached snippet as l_snippet then
Result.append ("Snippet:")
Result.append (l_snippet)
Result.append_character ('%N')
end
if attached html_snippet as l_html_snippet then
Result.append ("Html snippet:")
Result.append (l_html_snippet)
Result.append_character ('%N')
end
if attached cache_id as l_cache_id then
Result.append ("Cache_id:")
Result.append (l_cache_id)
Result.append_character ('%N')
end
if attached formatted_url as l_formatted_url then
Result.append ("Formatted url:")
Result.append (l_formatted_url)
Result.append_character ('%N')
end
if attached html_formatted_url as l_html_formatted_url then
Result.append ("Html formatted url:")
Result.append (l_html_formatted_url)
Result.append_character ('%N')
end
end
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

View File

@@ -0,0 +1,41 @@
note
description: "[
Represent a google page map
"pagemap": {
"cse_image": [
{
"src": "https://www.eiffel.org/portal/files/userpictures/picture-40.jpg"
}
],
"cse_thumbnail": [
{
"width": "81",
"height": "61",
"src": "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRnC-RKzps6BFItx_MLYBVskFI7U6u0y3VJBInomPYEF5sO6gkip94mLw"
}
]
}
]"
date: "$Date: 2015-10-09 08:11:07 -0300 (vi., 09 oct. 2015) $"
revision: "$Revision: 97973 $"
EIS: "name=PageMaps", "src=https://developers.google.com/custom-search/docs/structured_data#pagemaps", "protocol=url"
class
GCSE_PAGE_MAP
feature -- Access
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

View File

@@ -0,0 +1,238 @@
note
description: "[
Represent google custom search parameters
Example url template
"template": "https://www.googleapis.com/customsearch/v1?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"
]"
optional_parameters: "[
Optional parameters
c2coff string Enables or disables Simplified and Traditional Chinese Search.
The default value for this parameter is 0 (zero), meaning that the feature is enabled. Supported values are:
1: Disabled
0: Enabled (default)
cr string Restricts search results to documents originating in a particular country.
You may use Boolean operators in the cr parameter's value.
Google Search determines the country of a document by analyzing:
the top-level domain (TLD) of the document's URL
the geographic location of the Web server's IP address
See the Country Parameter Values page for a list of valid values for this parameter.
cref string The URL of a linked custom search engine specification to use for this request.
Does not apply for Google Site Search
If both cx and cref are specified, the cx value is used
cx string The custom search engine ID to use for this request.
If both cx and cref are specified, the cx value is used.
dateRestrict string Restricts results to URLs based on date. Supported values include:
d[number]: requests results from the specified number of past days.
w[number]: requests results from the specified number of past weeks.
m[number]: requests results from the specified number of past months.
y[number]: requests results from the specified number of past years.
exactTerms string Identifies a phrase that all documents in the search results must contain.
excludeTerms string Identifies a word or phrase that should not appear in any documents in the search results.
fileType string Restricts results to files of a specified extension. A list of file types indexable by Google can be found in Webmaster Tools Help Center.
filter string Controls turning on or off the duplicate content filter.
See Automatic Filtering for more information about Google's search results filters. Note that host crowding filtering applies only to multi-site searches.
By default, Google applies filtering to all search results to improve the quality of those results.
Acceptable values are:
"0": Turns off duplicate content filter.
"1": Turns on duplicate content filter.
gl string Geolocation of end user.
The gl parameter value is a two-letter country code. The gl parameter boosts search results whose country of origin matches the parameter value. See the Country Codes page for a list of valid values.
Specifying a gl parameter value should lead to more relevant results. This is particularly true for international customers and, even more specifically, for customers in English- speaking countries other than the United States.
googlehost string The local Google domain (for example, google.com, google.de, or google.fr) to use to perform the search.
highRange string
Specifies the ending value for a search range.
Use lowRange and highRange to append an inclusive search range of lowRange...highRange to the query.
hl string Sets the user interface language.
Explicitly setting this parameter improves the performance and the quality of your search results.
See the Interface Languages section of Internationalizing Queries and Results Presentation for more information, and Supported Interface Languages for a list of supported languages.
hq string Appends the specified query terms to the query, as if they were combined with a logical AND operator.
imgColorType string Returns black and white, grayscale, or color images: mono, gray, and color.
Acceptable values are:
"color": color
"gray": gray
"mono": mono
imgDominantColor string Returns images of a specific dominant color.
Acceptable values are:
"black": black
"blue": blue
"brown": brown
"gray": gray
"green": green
"pink": pink
"purple": purple
"teal": teal
"white": white
"yellow": yellow
imgSize string Returns images of a specified size.
Acceptable values are:
"huge": huge
"icon": icon
"large": large
"medium": medium
"small": small
"xlarge": xlarge
"xxlarge": xxlarge
imgType string Returns images of a type.
Acceptable values are:
"clipart": clipart
"face": face
"lineart": lineart
"news": news
"photo": photo
linkSite string Specifies that all search results should contain a link to a particular URL
lowRange string Specifies the starting value for a search range.
Use lowRange and highRange to append an inclusive search range of lowRange...highRange to the query.
lr string Restricts the search to documents written in a particular language (e.g., lr=lang_ja).
Acceptable values are:
"lang_ar": Arabic
"lang_bg": Bulgarian
"lang_ca": Catalan
"lang_cs": Czech
"lang_da": Danish
"lang_de": German
"lang_el": Greek
"lang_en": English
"lang_es": Spanish
"lang_et": Estonian
"lang_fi": Finnish
"lang_fr": French
"lang_hr": Croatian
"lang_hu": Hungarian
"lang_id": Indonesian
"lang_is": Icelandic
"lang_it": Italian
"lang_iw": Hebrew
"lang_ja": Japanese
"lang_ko": Korean
"lang_lt": Lithuanian
"lang_lv": Latvian
"lang_nl": Dutch
"lang_no": Norwegian
"lang_pl": Polish
"lang_pt": Portuguese
"lang_ro": Romanian
"lang_ru": Russian
"lang_sk": Slovak
"lang_sl": Slovenian
"lang_sr": Serbian
"lang_sv": Swedish
"lang_tr": Turkish
"lang_zh-CN": Chinese (Simplified)
"lang_zh-TW": Chinese (Traditional)
orTerms string Provides additional search terms to check for in a document, where each document in the search results must contain at least one of the additional search terms.
relatedSite string Specifies that all search results should be pages that are related to the specified URL.
rights string Filters based on licensing. Supported values include: cc_publicdomain, cc_attribute, cc_sharealike, cc_noncommercial, cc_nonderived, and combinations of these.
safe string Search safety level.
Acceptable values are:
"high": Enables highest level of SafeSearch filtering.
"medium": Enables moderate SafeSearch filtering.
"off": Disables SafeSearch filtering. (default)
searchType string Specifies the search type: image. If unspecified, results are limited to webpages.
Acceptable values are:
"image": custom image search.
siteSearch string Specifies all search results should be pages from a given site.
siteSearchFilter string Controls whether to include or exclude results from the site named in the siteSearch parameter.
Acceptable values are:
"e": exclude
"i": include
sort string The sort expression to apply to the results.
]"
date: "$Date: 2015-10-08 07:51:29 -0300 (ju., 08 oct. 2015) $"
revision: "$Revision: 97966 $"
EIS: "GCSE parameters", "src=https://developers.google.com/custom-search/json-api/v1/reference/cse/list", "protocol=URI"
class
GCSE_QUERY_PARAMETERS
create
make
feature {NONE} -- Initialization
make (a_secret_key, a_cx, a_query: READABLE_STRING_8)
-- Create an object GCSE_QUERY_PARAMETERS with secret key `a_secret_key' and a custom search engine id `a_cx'.
-- and query `a_query'.
do
-- TODO
-- At the moment the API only use cx as Google Custom Search id.
-- Custom search engine ID - Use either cx or cref to specify the custom search engine you want to use to perform this search
secret := a_secret_key
cx := a_cx
query := a_query
ensure
secret_set: secret.same_string (a_secret_key)
cx_set: cx.same_string (a_cx)
query_set: query.same_string (a_query)
end
feature -- Access : Required Parameters
secret: READABLE_STRING_8
-- Required. The shared key between your site and Google Custom Search Engine.
cx: READABLE_STRING_8
-- Custom search engine id to perform this search.
query: READABLE_STRING_8
-- Search query, query parameter to specify your search expression.
feature -- Optional Parameters
num : detachable STRING_8
-- Number of search results to return.
-- Valid values are integers between 1 and 10, inclusive.
start: detachable STRING_8
-- The index of the first result to return.
feature -- Change Elements
set_num (a_num: READABLE_STRING_8)
require
is_number: a_num.is_integer
valid_range: a_num.to_integer >= 1 and then a_num.to_integer <= 10
do
num := a_num
ensure
num_set: num = a_num
valid_rage_set: attached num as l_num and then l_num.to_integer >= 1 and then l_num.to_integer <= 10
end
set_start (a_start: READABLE_STRING_8)
require
is_number: a_start.is_integer
valid_start: a_start.to_integer >= 1
do
start := a_start
ensure
start_set: start = a_start
valid_start_set: attached start as l_start and then l_start.to_integer >= 1
end
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

View File

@@ -0,0 +1,115 @@
note
description: "[
Represent search request metadata
URL: search template used for the current results.
Queries: current, next and previous page.
Context
Search infromation
Items: array of actual search results.
]"
date: "$Date: 2015-10-08 07:51:29 -0300 (ju., 08 oct. 2015) $"
revision: "$Revision: 97966 $"
class
GCSE_RESPONSE
--! TODO
--! All suppport for for url, context and search information.
feature -- Access
current_page: detachable GCSE_PAGE
-- Metadata describing the query for the current set of results.
-- This role is always present in the response.
-- It is always an array with just one element.
next_page: detachable GCSE_PAGE
-- Metadata describing the query to use for the next page of results.
-- This role is not present if the current results are the last page. Note: This API returns up to the first 100 results only.
-- When present, it is always a array with just one element.
previous_page: detachable GCSE_PAGE
-- Metadata describing the query to use for the previous page of results.
-- Not present if the current results are the first page.
-- When present, it is always a array with just one element.
items: detachable LIST [GCSE_PAGE_ITEM]
-- Contains the actual search results. The search results include the URL, title and text snippets that describe the result.
feature -- Change Element
set_current_page (a_page: GCSE_PAGE)
-- Set `current_page' with `a_page'.
do
current_page := a_page
ensure
current_page_set: current_page = a_page
end
set_next_page (a_page: GCSE_PAGE)
-- Set `next_page' with `a_page'.
do
next_page := a_page
ensure
next_page_set: next_page = a_page
end
set_previous_page (a_page: GCSE_PAGE)
-- Set `previous_page' with `a_page'.
do
previous_page := a_page
ensure
previous_page_set: previous_page = a_page
end
add_item (a_item: GCSE_PAGE_ITEM)
-- Add item `a_item' to the list of items.
local
l_items: like items
do
l_items := items
if l_items = Void then
create {ARRAYED_LIST[GCSE_PAGE_ITEM]}l_items.make (10)
items := l_items
end
l_items.force (a_item)
end
feature -- Acess: HTTP Response
status: INTEGER
-- HTTP status code.
status_message: detachable READABLE_STRING_8
-- associated textual phrase for the response status.
feature -- Change Element: HTTP Response
set_status (a_status: like status)
-- Set `status' with `a_status'.
do
status := a_status
ensure
status_set: status = a_status
end
set_status_nessage (a_message: like status_message)
-- Set `status_message' with `a_message'.
do
status_message := a_message
ensure
status_message_set: status_message = a_message
end
;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

View File

@@ -0,0 +1,80 @@
note
description : "test application root class"
date : "$Date: 2015-10-08 07:51:29 -0300 (ju., 08 oct. 2015) $"
revision : "$Revision: 97966 $"
class
APPLICATION
inherit
ARGUMENTS
create
make
feature {NONE} -- Initialization
make
-- Run application.
local
gcse: GCSE_API
l_parameters: GCSE_QUERY_PARAMETERS
do
create l_parameters.make (key, cx, "scoop")
create gcse.make (l_parameters)
gcse.search
if attached {GCSE_RESPONSE} gcse.last_result as l_result then
if attached l_result.current_page as l_page then
print ("Current Page%N")
print (l_page.to_string)
end
if attached l_result.next_page as l_page then
print ("Next Page%N")
print (l_page.to_string)
end
if attached l_result.previous_page as l_page then
print ("Previous Page%N")
print (l_page.to_string)
end
if attached l_result.items as l_items then
print ("Number of items:" + l_items.count.out)
across l_items as ic loop print (ic.item.to_string) end
end
if attached l_result.next_page as l_page then
l_parameters.set_start (l_page.start_index.out)
gcse.search
end
end
if attached {GCSE_RESPONSE} gcse.last_result as l_result then
if attached l_result.current_page as l_page then
print ("Current Page%N")
print (l_page.to_string)
end
if attached l_result.next_page as l_page then
print ("Next Page%N")
print (l_page.to_string)
end
if attached l_result.previous_page as l_page then
print ("Previous Page%N")
print (l_page.to_string)
end
if attached l_result.items as l_items then
print ("Number of items:" + l_items.count.out)
across l_items as ic loop print (ic.item.to_string) end
end
end
end
feature {NONE} -- Implementation
Key: STRING = "AIzaSyBKAXNofo-RqZb6kUmpbiCwPEy7n7-E51k"
cx : STRING = "015017565055626880074:9gdgp1fvt-g"
end

View File

@@ -0,0 +1,31 @@
note
description: "[
Eiffel tests that can be executed by testing tool.
]"
author: "EiffelStudio test wizard"
date: "$Date: 2015-10-08 07:51:29 -0300 (ju., 08 oct. 2015) $"
revision: "$Revision: 97966 $"
testing: "type/manual"
class
GCSE_API_TEST_SET
inherit
EQA_TEST_SET
feature -- Test routines
feature {NONE} -- Implementation
has_error (l_captcha: GCSE_API; a_error: READABLE_STRING_32): BOOLEAN
do
if attached l_captcha.errors as l_errors then
l_errors.compare_objects
Result := l_errors.has (a_error)
end
end
end

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="test">
<target name="test">
<root class="APPLICATION" feature="make"/>
<option warning="true" void_safety="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<precompile name="base_pre" location="$ISE_PRECOMP\base-safe.ecf"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="gcse" location="..\gcse-safe.ecf" readonly="false"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
<cluster name="test" location=".\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-14-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-14-0 http://www.eiffel.com/developers/xml/configuration-1-14-0.xsd" name="http_client_extension" uuid="EA6A381D-2E78-448C-8A6D-B71759F1082E" library_target="http_client_extension">
<target name="http_client_extension">
<root all_classes="true"/>
<option warning="true" void_safety="all">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
<library name="curl" location="$ISE_LIBRARY\library\cURL\cURL-safe.ecf"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="http_client" location="$ISE_LIBRARY\contrib\library\network\http_client\http_client-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri-safe.ecf"/>
<cluster name="http_client_extension" location=".\src\" recursive="true">
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-14-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-14-0 http://www.eiffel.com/developers/xml/configuration-1-14-0.xsd" name="http_client_extension" uuid="DD90A4FA-1B7F-4C8C-A739-AE67D6F40384" library_target="http_client_extension">
<target name="http_client_extension">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" void_safety="none">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension.ecf"/>
<library name="curl" location="$ISE_LIBRARY\library\cURL\cURL.ecf"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
<library name="http_client" location="$ISE_LIBRARY\contrib\library\network\http_client\http_client.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/>
<cluster name="http_client_extension" location=".\src\" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,199 @@
note
description: "Represent an HTTP request."
date: "$Date: 2015-10-08 07:51:29 -0300 (ju., 08 oct. 2015) $"
revision: "$Revision: 97966 $"
class
REQUEST
inherit
HTTP_CONSTANTS
create
make
feature {NONE} -- Initialization
make (a_method: READABLE_STRING_8; a_uri: READABLE_STRING_8)
require
valid_http_method: is_http_method (a_method)
valid_uri: is_valid_uri (a_uri)
do
verb := a_method
uri := a_uri
create headers.make (5)
ensure
ver_set: verb = a_method
uri_set: uri = a_uri
end
feature -- Status Report
is_valid_uri (a_uri: READABLE_STRING_8): BOOLEAN
local
l_uri: URI
do
create l_uri.make_from_string (a_uri)
Result := l_uri.is_valid
end
query_string: detachable READABLE_STRING_8
local
l_uri: URI
do
create l_uri.make_from_string (uri)
Result := l_uri.query
end
sanitized_url: READABLE_STRING_8
-- Returns the URL without the query string part
local
l_uri: URI
do
create l_uri.make_from_string (uri)
l_uri.remove_query
Result := l_uri.string
ensure
sanitized: not as_uri (Result).has_query
end
is_http_method (a_method: READABLE_STRING_GENERAL): BOOLEAN
do
if a_method.same_string (method_connect) then
Result := True
elseif a_method.same_string (method_delete) then
Result := True
elseif a_method.same_string (method_get) then
Result := True
elseif a_method.same_string (method_head) then
Result := True
elseif a_method.same_string (method_options) then
Result := True
elseif a_method.same_string (method_patch) then
Result := True
elseif a_method.same_string (method_post) then
Result := True
elseif a_method.same_string (method_put) then
Result := True
elseif a_method.same_string (method_trace) then
Result := True
end
end
feature -- Constants
content_type_header_name: STRING_8 = "Content-Type";
default_content_type: STRING
once
Result := application_json
end
feature -- Access
uri: READABLE_STRING_8
verb: READABLE_STRING_8
headers: STRING_TABLE [READABLE_STRING_8]
payload: detachable READABLE_STRING_8
executor: detachable REQUEST_EXECUTOR
feature -- Change Element
add_payload (a_payload: like payload)
do
payload := a_payload
ensure
payload_set: attached payload as l_payload implies l_payload = a_payload
end
add_header (key: READABLE_STRING_8; value: READABLE_STRING_8)
do
headers.force (value, key)
end
feature -- Execute
execute: detachable RESPONSE
do
initialize_executor
Result := execute_request
end
initialize_executor
do
create executor.make (uri, verb)
end
feature {NONE} -- Implementation
execute_request: detachable RESPONSE
do
if attached executor as l_executor then
-- add headers
add_headers (l_executor)
if verb.same_string (method_put) or else verb.same_string (method_post) or else verb.same_string (method_patch) then
l_executor.set_body (body_contents)
end
if not l_executor.context_executor.headers.has (content_type_header_name) then
l_executor.context_executor.add_header (content_type_header_name, default_content_type)
end
if attached l_executor.execute as l_response then
create Result.make (l_response)
end
end
end
feature {NONE} -- Implementation
add_headers (a_executor: REQUEST_EXECUTOR)
local
l_context_executor: HTTP_CLIENT_REQUEST_CONTEXT
s: READABLE_STRING_GENERAL
utf: UTF_CONVERTER
do
l_context_executor := a_executor.context_executor
across
headers as ic
loop
s := ic.key
if s.is_valid_as_string_8 then
l_context_executor.add_header (s.as_string_8, ic.item)
else
l_context_executor.add_header (utf.utf_32_string_to_utf_8_string_8 (s), ic.item)
end
end
end
body_contents: READABLE_STRING_8
do
if attached payload as l_payload then
Result := l_payload
else
Result := ""
end
end
as_uri (a_string: READABLE_STRING_8): URI
require
is_valid_uri: is_valid_uri (a_string)
do
create Result.make_from_string (a_string)
end
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

View File

@@ -0,0 +1,97 @@
note
description: "Executes an HTTP request"
date: "$Date: 2015-10-08 07:51:29 -0300 (ju., 08 oct. 2015) $"
revision: "$Revision: 97966 $"
class
REQUEST_EXECUTOR
inherit
HTTP_CLIENT_HELPER
HTTP_CONSTANTS
create
make
feature {NONE} -- Initialization
make (a_url: READABLE_STRING_8; a_method: READABLE_STRING_8)
do
set_base_url (a_url)
verb := a_method
ensure
base_url_set: base_url.same_string (a_url)
method_set: verb.same_string (a_method)
end
set_base_url (a_url: READABLE_STRING_8)
-- Set base_url with `a_url'
local
s: STRING
do
create s.make_from_string (a_url)
s.left_adjust
s.right_adjust
base_url := s
ensure
base_url_set: a_url.has_substring (base_url)
end
feature -- Access
verb: READABLE_STRING_8
-- HTTP METHOD (Get, Post, ...)
body: detachable READABLE_STRING_8
-- body content
feature -- Element Change
set_body (a_body: like body)
-- Set body with `a_body'.
do
body := a_body
ensure
body_set: body = a_body
end
feature -- Execute
execute: detachable HTTP_CLIENT_RESPONSE
-- Http executor
do
if verb.same_string (method_connect) then
Result := Void -- not supported for now
elseif verb.same_string (method_delete) then
Result := execute_delete ("")
elseif verb.same_string (method_get) then
Result := execute_get ("")
elseif verb.same_string (method_head) then
Result := Void
elseif verb.same_string (method_options) then
Result := Void
elseif verb.same_string (method_patch) then
Result := execute_patch ("", body)
elseif verb.same_string (method_post) then
Result := execute_post ("", body)
elseif verb.same_string (method_put) then
Result := execute_put ("", body)
elseif verb.same_string (method_trace) then
Result := Void
end
end
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

View File

@@ -0,0 +1,57 @@
note
description: "Represent and HTTP Response"
date: "$Date: 2015-10-08 07:51:29 -0300 (ju., 08 oct. 2015) $"
revision: "$Revision: 97966 $"
class
RESPONSE
create
make
feature {NONE} --Initialization
make (a_response: HTTP_CLIENT_RESPONSE)
do
http_response := a_response
body := a_response.body
status := a_response.status
headers := a_response.headers
status_message := a_response.status_line
error_message := a_response.error_message
ensure
http_reponse_set: http_response = a_response
headers_set: headers = a_response.headers
status_set: status = a_response.status
status_message_set: status_message = a_response.status_line
error_message_set: error_message = a_response.error_message
end
feature -- Access
status: INTEGER
status_message: detachable READABLE_STRING_8
error_message: detachable READABLE_STRING_8
body: detachable READABLE_STRING_8
headers: LIST [TUPLE [name: READABLE_STRING_8; value: READABLE_STRING_8]]
feature {NONE} -- Implementation
http_response: HTTP_CLIENT_RESPONSE;
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

View File

@@ -0,0 +1,99 @@
note
description: "Wrapper class for HTTP_CLIENT_SESSION"
date: "$Date: 2015-10-08 07:51:29 -0300 (ju., 08 oct. 2015) $"
revision: "$Revision: 97966 $"
deferred class
HTTP_CLIENT_HELPER
feature -- Access
http_session: detachable HTTP_CLIENT_SESSION
get_http_session
local
h: LIBCURL_HTTP_CLIENT
b: like base_url
do
create h.make
b := base_url
if b = Void then
b := ""
end
if attached {HTTP_CLIENT_SESSION} h.new_session (base_url) as sess then
http_session := sess
sess.set_timeout (-1)
sess.set_connect_timeout (-1)
sess.set_is_insecure (True)
sess.set_any_auth_type
debug ("curl")
sess.set_is_debug (True)
end
debug ("proxy8888")
sess.set_proxy ("127.0.0.1", 8888) --| inspect traffic with http://www.fiddler2.com/
end
end
end
feature -- HTTP client helpers
execute_get (command_name: READABLE_STRING_8): detachable HTTP_CLIENT_RESPONSE
do
get_http_session
if attached http_session as sess then
Result := sess.get (command_name, context_executor)
end
end
execute_post (command_name: READABLE_STRING_8; data: detachable READABLE_STRING_8): detachable HTTP_CLIENT_RESPONSE
do
get_http_session
if attached http_session as sess then
Result := sess.post (command_name, context_executor, data)
end
end
execute_delete (command_name: READABLE_STRING_8): detachable HTTP_CLIENT_RESPONSE
do
get_http_session
if attached http_session as sess then
Result := sess.delete (command_name, context_executor)
end
end
execute_put (command_name: READABLE_STRING_8; data: detachable READABLE_STRING_8): detachable HTTP_CLIENT_RESPONSE
do
get_http_session
if attached http_session as sess then
Result := sess.put (command_name, context_executor, data)
end
end
execute_patch (command_name: READABLE_STRING_8; data: detachable READABLE_STRING_8): detachable HTTP_CLIENT_RESPONSE
do
get_http_session
if attached http_session as sess then
Result := sess.patch (command_name, context_executor, data)
end
end
context_executor: HTTP_CLIENT_REQUEST_CONTEXT
-- request context for each request
once
create Result.make
end
base_url: STRING;
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

View File

@@ -99,6 +99,8 @@ feature -- Security
Result.force ("admin roles") Result.force ("admin roles")
Result.force ("admin modules") Result.force ("admin modules")
Result.force ("install modules") Result.force ("install modules")
Result.force ("admin core caches")
Result.force ("clear blocks cache")
end end
feature -- Hooks feature -- Hooks
@@ -128,13 +130,9 @@ feature -- Hooks
lnk.set_permission_arguments (<<"manage " + {CMS_ADMIN_MODULE}.name>>) lnk.set_permission_arguments (<<"manage " + {CMS_ADMIN_MODULE}.name>>)
a_menu_system.management_menu.extend (lnk) a_menu_system.management_menu.extend (lnk)
end end
if -- Per module cache permission!
a_response.has_permission ("admin cache") -- Note: admin user has all permissions enabled by default. create lnk.make ("Cache", "admin/cache")
then a_menu_system.management_menu.extend (lnk)
create lnk.make ("Cache", "admin/cache")
lnk.set_permission_arguments (<<"admin cache">>)
a_menu_system.management_menu.extend (lnk)
end
end end
note note

View File

@@ -42,14 +42,10 @@ feature -- Execution
f: CMS_FORM f: CMS_FORM
do do
create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api) create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api)
if l_response.has_permission ("admin cache") then f := clear_cache_web_form (l_response)
f := clear_cache_web_form (l_response) create s.make_empty
create s.make_empty f.append_to_html (create {CMS_TO_WSF_THEME}.make (l_response, l_response.theme), s)
f.append_to_html (create {CMS_TO_WSF_THEME}.make (l_response, l_response.theme), s) l_response.set_main_content (s)
l_response.set_main_content (s)
else
create {FORBIDDEN_ERROR_CMS_RESPONSE} l_response.make (req, res, api)
end
l_response.execute l_response.execute
end end
@@ -60,26 +56,22 @@ feature -- Execution
f: CMS_FORM f: CMS_FORM
do do
create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api) create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api)
if l_response.has_permission ("admin cache") then f := clear_cache_web_form (l_response)
f := clear_cache_web_form (l_response) f.process (l_response)
f.process (l_response) if
if attached f.last_data as fd and then
attached f.last_data as fd and then fd.is_valid
fd.is_valid then
then if attached fd.string_item ("op") as l_op and then l_op.same_string (text_clear_all_caches) then
if attached fd.string_item ("op") as l_op and then l_op.same_string (text_clear_all_caches) then l_response.hooks.invoke_clear_cache (Void, l_response)
l_response.hooks.invoke_clear_cache (Void, l_response) l_response.add_notice_message ("Caches cleared (if allowed)!")
l_response.add_notice_message ("Cache cleared!") else
else fd.report_error ("Invalid form data!")
fd.report_error ("Invalid form data!")
end
end end
create s.make_empty
f.append_to_html (create {CMS_TO_WSF_THEME}.make (l_response, l_response.theme), s)
l_response.set_main_content (s)
else
create {FORBIDDEN_ERROR_CMS_RESPONSE} l_response.make (req, res, api)
end end
create s.make_empty
f.append_to_html (create {CMS_TO_WSF_THEME}.make (l_response, l_response.theme), s)
l_response.set_main_content (s)
l_response.execute l_response.execute
end end

View File

@@ -123,6 +123,7 @@ feature -- Hooks configuration
lnk.set_weight (98) lnk.set_weight (98)
a_menu_system.primary_menu.extend (lnk) a_menu_system.primary_menu.extend (lnk)
end end
end end
feature -- Handler feature -- Handler

View File

@@ -230,9 +230,9 @@ feature -- HTML Output
lnk := blog_api.node_api.node_link (n) lnk := blog_api.node_api.node_link (n)
a_output.append ("<p class=%"blog_list_summary%">") a_output.append ("<p class=%"blog_list_summary%">")
if attached api.format (n.format) as f then if attached api.format (n.format) as f then
a_output.append (f.formatted_output (l_summary)) f.append_formatted_to (l_summary, a_output)
else else
a_output.append (page.formats.default_format.formatted_output (l_summary)) page.formats.default_format.append_formatted_to (l_summary, a_output)
end end
a_output.append ("<br />") a_output.append ("<br />")
a_output.append (page.link ("See more...", lnk.location, Void)) a_output.append (page.link ("See more...", lnk.location, Void))

View File

@@ -46,9 +46,13 @@ feature -- Access
-- List of permission ids, used by this module, and declared. -- List of permission ids, used by this module, and declared.
do do
Result := Precursor Result := Precursor
Result.force ("manage feed aggregator") Result.force (permission__manage_feed_aggregator)
Result.force (permission__clear_feed_cache)
end end
permission__manage_feed_aggregator: STRING = "manage feed aggregator"
permission__clear_feed_cache: STRING = "clear feed cache"
feature {CMS_API} -- Module Initialization feature {CMS_API} -- Module Initialization
initialize (api: CMS_API) initialize (api: CMS_API)
@@ -194,12 +198,14 @@ feature -- Hook
p: PATH p: PATH
dir: DIRECTORY dir: DIRECTORY
do do
if a_cache_id_list = Void then if a_response.has_permissions (<<permission__clear_feed_cache, permission__manage_feed_aggregator>>) then
-- Clear all cache. if a_cache_id_list = Void then
p := a_response.api.files_location.extended (".cache").extended (name) -- Clear all cache.
create dir.make_with_path (p) p := a_response.api.files_location.extended (".cache").extended (name)
if dir.exists then create dir.make_with_path (p)
dir.recursive_delete if dir.exists then
dir.recursive_delete
end
end end
end end
end end
@@ -341,7 +347,7 @@ feature -- Hook
-- for related response `a_response'. -- for related response `a_response'.
do do
a_menu_system.navigation_menu.extend (create {CMS_LOCAL_LINK}.make ("Feeds", "feed_aggregation/")) a_menu_system.navigation_menu.extend (create {CMS_LOCAL_LINK}.make ("Feeds", "feed_aggregation/"))
if a_response.has_permission ("manage feed aggregator") then if a_response.has_permission (permission__manage_feed_aggregator) then
a_menu_system.management_menu.extend (create {CMS_LOCAL_LINK}.make ("Feeds (admin)", "admin/feed_aggregator/")) a_menu_system.management_menu.extend (create {CMS_LOCAL_LINK}.make ("Feeds (admin)", "admin/feed_aggregator/"))
end end
end end

View File

@@ -0,0 +1 @@
Google Custom Search Module.

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-14-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-14-0 http://www.eiffel.com/developers/xml/configuration-1-14-0.xsd" name="google_search" uuid="054E9C5C-ACCB-4A4D-B825-6C574AEC30A9" library_target="google_search">
<target name="google_search">
<root all_classes="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="cms" location="$ISE_LIBRARY\unstable\library\web\cms\cms-safe.ecf" readonly="false"/>
<library name="cms_app_env" location="$ISE_LIBRARY\unstable\library\web\cms\library\app_env\app_env-safe.ecf" readonly="false"/>
<library name="cms_config" location="$ISE_LIBRARY\unstable\library\web\cms\library\configuration\config-safe.ecf"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
<library name="google_cse" location="..\..\library\gcse\gcse-safe.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
<cluster name="src" location="src\" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="google_search" uuid="054E9C5C-ACCB-4A4D-B825-6C574AEC30A9" library_target="google_search">
<target name="google_search">
<root all_classes="true"/>
<option is_attached_by_default="false" void_safety="none">
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="cms" location="$ISE_LIBRARY\unstable\library\web\cms\cms.ecf" readonly="false"/>
<library name="cms_app_env" location="$ISE_LIBRARY\unstable\library\web\cms\library\app_env\app_env.ecf" readonly="false"/>
<library name="cms_config" location="$ISE_LIBRARY\unstable\library\web\cms\library\configuration\config.ecf"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
<library name="google_cse" location="..\..\library\gcse\gcse.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
<library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf.ecf"/>
<library name="wsf_encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/>
<cluster name="src" location="src\" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,6 @@
{
"gcse": {
"cx":"",
"secret_key":""
}
}

View File

@@ -0,0 +1,40 @@
<section>
<header>
<h2>Results for <kbd>{$result.current_page.search_terms/}</kbd></h2>
</header>
<!-- list of results -->
<ol start="{$result.current_page.start_index/}">
<!-- Item result -->
{foreach from="$result.items" item="item"}
<li>
<article>
<header>
<h3>
<cite>
<a href="{$item.link/}">{$item.title/}</a>
</cite>
</h3>
</header>
<blockquote cite="{$item.link/}">
<p>{$item.html_snippet/}</p>
<footer>
<p><abbr title="Uniform Resource Locator">Source</abbr> <a href="{$item.link/}">{$item.display_link/}</a></p>
</footer>
</blockquote>
</article>
</li>
{/foreach}
</ol>
<ul class="cms-page-links">
{if isset="$result.previous_page"}
<li><a href="{$site_url/}gcse/?q={$result.previous_page.search_terms/}&amp;start={$result.previous_page.start_index/}&amp;num={$result.previous_page.count/}">Previous</a></li>
{/if}
{if isset="$result.next_page"}
<li><a href="{$site_url/}gcse/?q={$result.next_page.search_terms/}&amp;start={$result.next_page.start_index/}&amp;num={$result.next_page.count/}">Next</a></li>
{/if}
</ul>
</section>

View File

@@ -0,0 +1,150 @@
note
description: "[
Module providing Google Custom Search functionality.
]"
date: "$Date: 2015-10-09 20:50:01 -0300 (vi. 09 de oct. de 2015) $"
revision: "$Revision: 97982 $"
class
GOOGLE_CUSTOM_SEARCH_MODULE
inherit
CMS_MODULE
CMS_HOOK_BLOCK_HELPER
SHARED_EXECUTION_ENVIRONMENT
export
{NONE} all
end
REFACTORING_HELPER
SHARED_LOGGER
create
make
feature {NONE} -- Initialization
make
-- Create current module
do
version := "1.0"
description := "Google custome search module"
package := "search"
end
feature -- Access
name: STRING = "google_search"
-- <Precursor>
feature -- Router
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
-- Router configuration.
do
a_router.handle ("/gcse", create {WSF_URI_AGENT_HANDLER}.make (agent handle_search (a_api, ?, ?)), a_router.methods_head_get)
end
feature -- Recaptcha
gcse_secret_key (api: CMS_API): detachable READABLE_STRING_8
-- Get recaptcha security key.
local
utf: UTF_CONVERTER
do
if attached api.module_configuration (Current, Void) as cfg then
if
attached cfg.text_item ("gcse.secret_key") as l_recaptcha_key and then
not l_recaptcha_key.is_empty
then
Result := utf.utf_32_string_to_utf_8_string_8 (l_recaptcha_key)
end
end
end
gcse_cx_key (api: CMS_API): detachable READABLE_STRING_8
-- Get recaptcha security key.
local
utf: UTF_CONVERTER
do
if attached api.module_configuration (Current, Void) as cfg then
if
attached cfg.text_item ("gcse.cx") as l_recaptcha_key and then
not l_recaptcha_key.is_empty
then
Result := utf.utf_32_string_to_utf_8_string_8 (l_recaptcha_key)
end
end
end
feature -- Handler
handle_search (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
local
r: CMS_RESPONSE
l_parameters:GCSE_QUERY_PARAMETERS
l_search: GCSE_API
do
-- TODO handle errors!!!
write_debug_log (generator + ".handle_search")
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
if
attached {WSF_STRING} req.query_parameter ("q") as l_query and then
not l_query.value.is_empty
then
if
attached gcse_cx_key (api) as l_cx and then
attached gcse_secret_key (api) as l_key
then
create l_parameters.make (l_key, l_cx, l_query.url_encoded_value )
if
attached {WSF_STRING} req.query_parameter ("start") as l_index and then
attached {WSF_STRING} req.query_parameter ("num") as l_num
then
l_parameters.set_start (l_index.value)
l_parameters.set_num (l_num.value)
end
create l_search.make (l_parameters)
l_search.search
if
attached l_search.last_result as l_result and then
l_result.status = 200
then
if attached template_block (Current, "search", r) as l_tpl_block then
l_tpl_block.set_value (l_result, "result")
r.add_block (l_tpl_block, "content")
end
else
-- Quota limit (403 status code) or not results.
google_search_site (req, r, l_query)
end
else
-- If no key are provided, at least output google search result page.
google_search_site (req, r, l_query)
end
else
r.add_message ("No query submitted", Void)
end
r.execute
end
feature {NONE} -- Helper
google_search_site (req: WSF_REQUEST; res: CMS_RESPONSE; query: WSF_STRING)
-- Workaround to output google search result page
-- If no key are provided or if GCSE reached the quota limit.
local
l_url_encoder: URL_ENCODER
do
create l_url_encoder
if req.is_https then
res.set_redirection ("https://www.google.com/search?sitesearch=" + l_url_encoder.general_encoded_string (res.absolute_url ("", Void)) + "&q=" + query.url_encoded_value)
else
res.set_redirection ("http://www.google.com/search?sitesearch=" + l_url_encoder.general_encoded_string (res.absolute_url ("", Void)) + "&q=" + query.url_encoded_value)
end
end
end

View File

@@ -219,7 +219,7 @@ feature -- Hook: cache
end end
end end
a_response.clear_block_caches (a_cache_id_list) a_response.clear_cache (a_cache_id_list)
end end
end end

View File

@@ -302,6 +302,11 @@ feature -- Access
l_item := sql_item (a_index) l_item := sql_item (a_index)
if attached {READABLE_STRING_8} l_item as l_string then if attached {READABLE_STRING_8} l_item as l_string then
Result := l_string Result := l_string
elseif
attached {READABLE_STRING_32} l_item as l_string_32 and then
l_string_32.is_valid_as_string_8
then
Result := l_string_32.to_string_8
elseif attached {BOOLEAN} l_item as l_boolean then elseif attached {BOOLEAN} l_item as l_boolean then
Result := l_boolean.out Result := l_boolean.out
elseif attached {BOOLEAN_REF} l_item as l_boolean_ref then elseif attached {BOOLEAN_REF} l_item as l_boolean_ref then

View File

@@ -997,6 +997,17 @@ feature -- Element Change
status_code_set: status_code = a_status status_code_set: status_code = a_status
end end
feature -- Cache managment
clear_cache (a_cache_id_list: detachable ITERABLE [READABLE_STRING_GENERAL])
-- Clear caches identified by `a_cache_id_list',
-- or clear all caches if `a_cache_id_list' is Void.
do
if has_permissions (<<"clear blocks cache", "admin core caches">>) then
clear_block_caches (a_cache_id_list)
end
end
feature -- Generation feature -- Generation
prepare (page: CMS_HTML_PAGE) prepare (page: CMS_HTML_PAGE)

View File

@@ -50,12 +50,14 @@ set TMP_CONTRIB_DIR=%TMP_TARGET_DIR%\contrib
set TMP_UNSTABLE_DIR=%TMP_TARGET_DIR%\unstable set TMP_UNSTABLE_DIR=%TMP_TARGET_DIR%\unstable
echo Install ROC as CMS ewf echo Install ROC as CMS ewf
%SAFE_RMDIR% %TMP_UNSTABLE_DIR%\library\cms\launcher
%SAFE_RMDIR% %TMP_UNSTABLE_DIR%\library\cms\library %SAFE_RMDIR% %TMP_UNSTABLE_DIR%\library\cms\library
%SAFE_RMDIR% %TMP_UNSTABLE_DIR%\library\cms\src %SAFE_RMDIR% %TMP_UNSTABLE_DIR%\library\cms\src
%SAFE_RMDIR% %TMP_UNSTABLE_DIR%\library\cms\doc %SAFE_RMDIR% %TMP_UNSTABLE_DIR%\library\cms\doc
%SAFE_RMDIR% %TMP_UNSTABLE_DIR%\library\cms\modules %SAFE_RMDIR% %TMP_UNSTABLE_DIR%\library\cms\modules
%SAFE_RMDIR% %TMP_UNSTABLE_DIR%\library\cms\examples %SAFE_RMDIR% %TMP_UNSTABLE_DIR%\library\cms\examples
%COPYCMD% %TMP_DIR%\launcher %TMP_UNSTABLE_DIR%\library\web\cms\launcher
%COPYCMD% %TMP_DIR%\library %TMP_UNSTABLE_DIR%\library\web\cms\library %COPYCMD% %TMP_DIR%\library %TMP_UNSTABLE_DIR%\library\web\cms\library
%COPYCMD% %TMP_DIR%\src %TMP_UNSTABLE_DIR%\library\web\cms\src %COPYCMD% %TMP_DIR%\src %TMP_UNSTABLE_DIR%\library\web\cms\src
%COPYCMD% %TMP_DIR%\doc %TMP_UNSTABLE_DIR%\library\web\cms\doc %COPYCMD% %TMP_DIR%\doc %TMP_UNSTABLE_DIR%\library\web\cms\doc