Minor changes
- using http_client library instead of libcurl directly - using implicit conversion to JSON_STRING to improve code readability - use ARRAYED_LIST instead of LINKED_LIST .. for performance. - cosmetic .. but still a lot of feature clauses are missing, comments, assertions ...
This commit is contained in:
@@ -9,12 +9,22 @@ class
|
||||
inherit
|
||||
|
||||
WSF_ROUTED_SERVICE
|
||||
rename
|
||||
execute as execute_router
|
||||
end
|
||||
|
||||
WSF_FILTERED_SERVICE
|
||||
|
||||
WSF_DEFAULT_SERVICE
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
WSF_FILTER
|
||||
rename
|
||||
execute as execute_router
|
||||
end
|
||||
|
||||
create
|
||||
make_and_launch
|
||||
|
||||
@@ -24,10 +34,47 @@ feature {NONE} -- Initialization
|
||||
-- Initialize current service.
|
||||
do
|
||||
initialize_router
|
||||
initialize_filter
|
||||
Precursor
|
||||
set_service_option ("port", 9090)
|
||||
end
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
feature -- Router and Filter
|
||||
|
||||
create_filter
|
||||
-- Create `filter'
|
||||
local
|
||||
f, l_filter: detachable WSF_FILTER
|
||||
do
|
||||
l_filter := Void
|
||||
|
||||
-- Maintenance
|
||||
create {WSF_MAINTENANCE_FILTER} f
|
||||
f.set_next (l_filter)
|
||||
l_filter := f
|
||||
|
||||
-- Logging
|
||||
create {WSF_LOGGING_FILTER} f
|
||||
f.set_next (l_filter)
|
||||
l_filter := f
|
||||
|
||||
filter := l_filter
|
||||
end
|
||||
|
||||
setup_filter
|
||||
-- Setup `filter'
|
||||
local
|
||||
f: WSF_FILTER
|
||||
do
|
||||
from
|
||||
f := filter
|
||||
until
|
||||
not attached f.next as l_next
|
||||
loop
|
||||
f := l_next
|
||||
end
|
||||
f.set_next (Current)
|
||||
end
|
||||
|
||||
setup_router
|
||||
do
|
||||
@@ -35,6 +82,9 @@ feature {NONE} -- Initialization
|
||||
map_agent_uri ("/", agent execute_hello, Void)
|
||||
map_agent_uri ("/grid", agent grid_demo, Void)
|
||||
map_agent_uri ("/repeater", agent repeater_demo, Void)
|
||||
|
||||
-- NOTE: you could put all those files in a specific folder, and use WSF_FILE_SYSTEM_HANDLER with "/"
|
||||
-- this way, it handles the caching and so on
|
||||
map_agent_uri ("/widget.js", agent load_file("widget.js", ?, ?), Void)
|
||||
map_agent_uri ("/jquery.min.js", agent load_file("jquery.min.js", ?, ?), Void)
|
||||
map_agent_uri ("/typeahead.min.js", agent load_file("typeahead.min.js", ?, ?), Void)
|
||||
|
||||
@@ -16,7 +16,7 @@ create
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make ()
|
||||
make
|
||||
do
|
||||
template := "{{=value}}";
|
||||
end
|
||||
@@ -25,26 +25,24 @@ feature -- Implementation
|
||||
|
||||
autocompletion (input: STRING): JSON_ARRAY
|
||||
local
|
||||
cl: LIBCURL_HTTP_CLIENT
|
||||
sess: HTTP_CLIENT_SESSION
|
||||
l_json: detachable READABLE_STRING_8
|
||||
|
||||
o: JSON_OBJECT
|
||||
l_result: INTEGER
|
||||
l_curl_string: CURL_STRING
|
||||
json_parser: JSON_PARSER
|
||||
query_str: STRING
|
||||
do
|
||||
query_str := input
|
||||
query_str.replace_substring_all (" ", "+")
|
||||
curl_handle := curl_easy.init
|
||||
create cl.make
|
||||
sess := cl.new_session ("http://google.com")
|
||||
if attached sess.get ("/complete/search?client=chrome&q=" + query_str, Void) as resp and then not resp.error_occurred then
|
||||
l_json := resp.body
|
||||
end
|
||||
create Result.make_array
|
||||
if curl_handle /= default_pointer then
|
||||
create l_curl_string.make_empty
|
||||
curl_easy.setopt_string (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_url, "http://google.com/complete/search?client=chrome&q=" + query_str)
|
||||
curl_easy.set_write_function (curl_handle)
|
||||
curl_easy.setopt_integer (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_writedata, l_curl_string.object_id)
|
||||
l_result := curl_easy.perform (curl_handle)
|
||||
|
||||
-- Always cleanup
|
||||
curl_easy.cleanup (curl_handle)
|
||||
create json_parser.make_parser (l_curl_string.out)
|
||||
if l_json /= Void and then not l_json.is_empty then
|
||||
create json_parser.make_parser (l_json)
|
||||
if attached {JSON_ARRAY} json_parser.parse_json as data and then attached {JSON_ARRAY} data.i_th (2) as list then
|
||||
across
|
||||
1 |..| list.count as c
|
||||
@@ -59,14 +57,4 @@ feature -- Implementation
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
curl_easy: CURL_EASY_EXTERNALS
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
curl_handle: POINTER;
|
||||
-- cURL handle
|
||||
|
||||
end
|
||||
|
||||
@@ -18,18 +18,21 @@ feature {NONE}
|
||||
|
||||
make_from_json (json: JSON_OBJECT)
|
||||
do
|
||||
if attached {JSON_STRING} json.item (create {JSON_STRING}.make_json ("title")) as a_title then
|
||||
title := a_title.unescaped_string_32
|
||||
if attached {JSON_STRING} json.item ("title") as l_title then
|
||||
title := l_title.unescaped_string_32
|
||||
end
|
||||
if attached {JSON_STRING} json.item (create {JSON_STRING}.make_json ("content")) as a_content then
|
||||
content := a_content.unescaped_string_32
|
||||
if attached {JSON_STRING} json.item ("content") as l_content then
|
||||
content := l_content.unescaped_string_32
|
||||
end
|
||||
if attached {JSON_OBJECT} json.item (create {JSON_STRING}.make_json ("image")) as img and then attached {JSON_STRING} img.item (create {JSON_STRING}.make_json ("url")) as a_image then
|
||||
image := a_image.item
|
||||
if
|
||||
attached {JSON_OBJECT} json.item ("image") as img and then
|
||||
attached {JSON_STRING} img.item ("url") as l_image
|
||||
then
|
||||
image := l_image.item
|
||||
end
|
||||
end
|
||||
|
||||
feature
|
||||
feature -- Access
|
||||
|
||||
title: detachable STRING
|
||||
|
||||
@@ -37,13 +40,14 @@ feature
|
||||
|
||||
image: detachable STRING
|
||||
|
||||
get (field: STRING): detachable ANY
|
||||
item (a_field: READABLE_STRING_GENERAL): detachable ANY
|
||||
-- <Precursor>
|
||||
do
|
||||
if field.is_equal ("title") then
|
||||
if a_field.same_string ("title") then
|
||||
Result := title
|
||||
elseif field.is_equal ("content") then
|
||||
elseif a_field.same_string ("content") then
|
||||
Result := content
|
||||
elseif field.is_equal ("image") then
|
||||
elseif a_field.same_string ("image") then
|
||||
Result := image
|
||||
end
|
||||
end
|
||||
|
||||
@@ -47,26 +47,28 @@ feature
|
||||
data: ITERABLE [GOOGLE_NEWS]
|
||||
local
|
||||
list: LINKED_LIST [GOOGLE_NEWS]
|
||||
l_result: INTEGER
|
||||
l_curl_string: CURL_STRING
|
||||
l_json: detachable READABLE_STRING_8
|
||||
json_parser: JSON_PARSER
|
||||
query_str: STRING
|
||||
cl: LIBCURL_HTTP_CLIENT
|
||||
sess: HTTP_CLIENT_SESSION
|
||||
do
|
||||
curl_handle := curl_easy.init
|
||||
create list.make
|
||||
row_count := 0
|
||||
if curl_handle /= default_pointer then
|
||||
create l_curl_string.make_empty
|
||||
query_str := query.out
|
||||
query_str.replace_substring_all (" ", "+")
|
||||
curl_easy.setopt_string (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_url, "https://ajax.googleapis.com/ajax/services/search/news?v=1.0&q=" + query_str + "&rsz=" + page_size.out + "&start=" + (page_size * (page - 1)).out)
|
||||
curl_easy.set_write_function (curl_handle)
|
||||
curl_easy.setopt_integer (curl_handle, {CURL_OPT_CONSTANTS}.curlopt_writedata, l_curl_string.object_id)
|
||||
l_result := curl_easy.perform (curl_handle)
|
||||
|
||||
-- Always cleanup
|
||||
curl_easy.cleanup (curl_handle)
|
||||
create json_parser.make_parser (l_curl_string.out)
|
||||
query_str := query.out
|
||||
query_str.replace_substring_all (" ", "+")
|
||||
create cl.make
|
||||
sess := cl.new_session ("https://ajax.googleapis.com/ajax/services/search")
|
||||
sess.set_is_insecure (True)
|
||||
if sess.is_available then
|
||||
if attached {HTTP_CLIENT_RESPONSE} sess.get ("/news?v=1.0&q=" + query_str + "&rsz=" + page_size.out + "&start=" + (page_size * (page - 1)).out, Void) as l_response then
|
||||
if not l_response.error_occurred then
|
||||
l_json := l_response.body
|
||||
end
|
||||
end
|
||||
end
|
||||
if l_json /= Void and then not l_json.is_empty then
|
||||
create json_parser.make_parser (l_json)
|
||||
if attached {JSON_OBJECT} json_parser.parse_json as sp then
|
||||
if attached {JSON_OBJECT} sp.item (create {JSON_STRING}.make_json ("responseData")) as responsedata and then attached {JSON_ARRAY} responsedata.item (create {JSON_STRING}.make_json ("results")) as results then
|
||||
if attached {JSON_OBJECT} responsedata.item (create {JSON_STRING}.make_json ("cursor")) as cursor and then attached {JSON_STRING} cursor.item (create {JSON_STRING}.make_json ("estimatedResultCount")) as count then
|
||||
@@ -94,14 +96,4 @@ feature
|
||||
|
||||
query: STRING
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
curl_easy: CURL_EASY_EXTERNALS
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
curl_handle: POINTER;
|
||||
-- cURL handle
|
||||
|
||||
end
|
||||
|
||||
@@ -29,7 +29,8 @@ feature
|
||||
search_query.set_change_event (agent change_query)
|
||||
container.add_control (search_query)
|
||||
container.add_control (create {WSF_BASIC_CONTROL}.make_with_body("h2","","Results"))
|
||||
create grid.make_grid ("mygrid", <<create {WSF_GRID_COLUMN}.make_column ("Title", "title"), create {WSF_GRID_COLUMN}.make_column ("Content", "content")>>, datasource)
|
||||
create grid.make_grid ("mygrid", <<create {WSF_GRID_COLUMN}.make ("Title", "title"),
|
||||
create {WSF_GRID_COLUMN}.make ("Content", "content")>>, datasource)
|
||||
container.add_control (grid)
|
||||
control := container
|
||||
end
|
||||
|
||||
@@ -8,11 +8,10 @@ class
|
||||
REPEATER_PAGE
|
||||
|
||||
inherit
|
||||
|
||||
BASE_PAGE
|
||||
redefine
|
||||
initialize_controls
|
||||
end
|
||||
redefine
|
||||
initialize_controls
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
@@ -22,13 +21,13 @@ feature
|
||||
initialize_controls
|
||||
do
|
||||
Precursor
|
||||
container.add_control (create {WSF_BASIC_CONTROL}.make_with_body("h1","","Repeater Demo"))
|
||||
container.add_control (create {WSF_BASIC_CONTROL}.make_with_body ("h1", ""," Repeater Demo"))
|
||||
create datasource.make_news
|
||||
create search_query.make_autocomplete ("query", create {GOOGLE_AUTOCOMPLETION}.make)
|
||||
search_query.add_class ("form-control")
|
||||
search_query.set_change_event (agent change_query)
|
||||
container.add_control (search_query)
|
||||
container.add_control (create {WSF_BASIC_CONTROL}.make_with_body("h2","","Results"))
|
||||
container.add_control (create {WSF_BASIC_CONTROL}.make_with_body("h2", "", "Results"))
|
||||
create repeater.make_repeater ("myrepeater", datasource)
|
||||
container.add_control (repeater)
|
||||
end
|
||||
|
||||
@@ -1,33 +1,32 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-10-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-10-0 http://www.eiffel.com/developers/xml/configuration-1-10-0.xsd" name="widgetapp" uuid="C28C4F53-9963-46C0-A080-8F13E94E7486" library_target="widgetapp">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-11-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-11-0 http://www.eiffel.com/developers/xml/configuration-1-11-0.xsd" name="widgetapp" uuid="C28C4F53-9963-46C0-A080-8F13E94E7486" library_target="widgetapp">
|
||||
<target name="common" abstract="true">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="curl" location="$ISE_LIBRARY\library\cURL\cURL-safe.ecf"/>
|
||||
<library name="http" location="..\..\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="wsf" location="..\..\library\server\wsf\wsf-safe.ecf"/>
|
||||
<library name="wsf_html" location="..\..\library\server\wsf_html\wsf_html-safe.ecf"/>
|
||||
<library name="wsf_html" location="..\..\library\server\wsf_html\wsf_html-safe.ecf" readonly="false"/>
|
||||
</target>
|
||||
<target name="widgetapp_nino" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<option warning="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_nino" location="..\..\library\server\wsf\default\nino-safe.ecf"/>
|
||||
<library name="json" location="..\..\contrib\library\text\parser\json\library\json-safe.ecf"/>
|
||||
<cluster name="widgetapp" location=".\" recursive="true">
|
||||
</cluster>
|
||||
<cluster name="widgetapp" location=".\" recursive="true"/>
|
||||
</target>
|
||||
<target name="widgetapp_cgi" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<option warning="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_cgi" location="..\..\library\server\wsf\default\cgi-safe.ecf"/>
|
||||
@@ -35,7 +34,7 @@
|
||||
</target>
|
||||
<target name="widgetapp_libfcgi" extends="common">
|
||||
<root class="APPLICATION" feature="make_and_launch"/>
|
||||
<option warning="true" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<option warning="true" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<library name="default_libfcgi" location="..\..\library\server\wsf\default\libfcgi-safe.ecf"/>
|
||||
|
||||
Reference in New Issue
Block a user