Skip to content

Commit 0e95177

Browse files
authored
Merge pull request #5 from EiffelWebFramework/pg_dev
Pg dev
2 parents 230fcc9 + af0fd52 commit 0e95177

File tree

4 files changed

+236
-31
lines changed

4 files changed

+236
-31
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,7 @@ EIFGENs
44

55
system.log
66
token.access
7-
credentials.json
7+
8+
sheets/test/eiftmp*
9+
credentials.json
10+

sheets/src/eg_sheets_api.e

Lines changed: 175 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ feature -- Spreedsheets Operations
5555
note
5656
EIS:"name=create.spreedsheets", "src=https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/create", "protocol=uri"
5757
do
58-
api_post_call (sheets_url ("spreadsheets", Void ), Void, Void)
58+
api_post_call (sheets_url ("spreadsheets", Void ), Void, Void, Void)
5959
if
6060
attached last_response as l_response and then
6161
attached l_response.body as l_body
@@ -105,7 +105,7 @@ feature -- Spreedsheets Operations
105105
end
106106
end
107107

108-
append (a_spreadsheet_id: attached like spreadsheet_id; a_data_line: ARRAY[STRING]): detachable like last_response.body
108+
append_with_id (a_spreadsheet_id: attached like spreadsheet_id; a_data: detachable ARRAY[ARRAY[STRING]]): detachable like last_response.body
109109
note
110110
EIS:"name=append.spreedsheets", "src=https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append", "protocol=uri"
111111
require
@@ -115,38 +115,52 @@ feature -- Spreedsheets Operations
115115
l_range,
116116
l_path_params_s: STRING
117117
l_qry_params: STRING_TABLE [STRING]
118+
l_post_data: STRING -- TUPLE[data:PATH; content_type: STRING]
119+
url_encoder: URL_ENCODER
118120
do
119121
l_range := ""
120122
logger.write_information ("append-> spreadsheed_id:" + a_spreadsheet_id)
121123
-- path params
122124
l_path_params_s := a_spreadsheet_id
123-
l_path_params_s.append ("/values/{") -- spreadsheets/{spreadsheetId}/values/{range}:append
124-
l_path_params_s.append ("") -- range ex. A1:B2 or namedRanges TRY: last not null index could be: =index(J:J,max(row(J:J)*(J:J<>"")))
125-
l_path_params_s.append ("}:append")
125+
l_path_params_s.append ("/values/") -- spreadsheets/{spreadsheetId}/values/{range}:append
126+
127+
-- TODO add url encode to the query parameters.
128+
create url_encoder
129+
l_path_params_s.append (url_encoder.encoded_string ("Sheet1!A1:B5")) -- range ex. A1:B2 or namedRanges TRY: Sheet1!A:A | last not null index could be: =index(J:J,max(row(J:J)*(J:J<>"")))
130+
131+
l_path_params_s.append (":append")
126132
-- qry params
127133
create l_qry_params.make (2)
128134
l_qry_params.extend ("RAW", "valueInputOption") -- INPUT_VALUE_OPTION_UNSPECIFIED|RAW|USER_ENTERED https://developers.google.com/sheets/api/reference/rest/v4/ValueInputOption
129-
l_qry_params.extend ("INSERT_ROWS", "insertDataOption") -- OVERWRITE|INSERT_ROWS https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append#InsertDataOption
130-
l_qry_params.extend ("true", "includeValuesInResponse") -- BOOLEAN
131-
l_qry_params.extend ("true", "responseValueRenderOption") -- FORMATTED_VALUE| https://developers.google.com/sheets/api/reference/rest/v4/ValueRenderOption
135+
-- l_qry_params.extend ("INSERT_ROWS", "insertDataOption") -- OVERWRITE|INSERT_ROWS https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append#InsertDataOption
136+
-- l_qry_params.extend ("true", "includeValuesInResponse") -- BOOLEAN
137+
-- l_qry_params.extend ("json", "alt") -- BOOLEAN
138+
-- alt=json
139+
-- l_qry_params.extend ("UNFORMATTED_VALUE", "responseValueRenderOption") -- UNFORMATTED_VALUE|FORMULA|FORMATTED_VALUE https://developers.google.com/sheets/api/reference/rest/v4/ValueRenderOption
140+
-- l_qry_params.extend ("SERIAL_NUMBER", "responseDateTimeRenderOption") -- SERIAL_NUMBER|FORMATTED_STRING https://developers.google.com/sheets/api/reference/rest/v4/DateTimeRenderOption
141+
142+
143+
l_post_data := impl_append_post_data2
144+
145+
-- Google API append require body parameter instead of upload data.
146+
api_post_call (sheets_url ("spreadsheets/" + l_path_params_s, Void), l_qry_params, l_post_data, Void)
132147

133-
api_get_call (sheets_url ("spreadsheets/" + l_path_params_s, Void), l_qry_params)
134148
check
135-
attached last_response as l_response and then
149+
attached last_response as l_response
136150
attached l_response.body as l_body
137151
then
138152
parse_last_response
139153
if l_response.status = {HTTP_STATUS_CODE}.ok then
140154
Result := l_body
141155

142-
create l_file.make_create_read_write ("/tmp/hitme_sheet_json-append.json")
143-
logger.write_information ("get_from_id->Writing body into " + l_file.path.utf_8_name)
144-
l_file.close
145-
l_file.wipe_out
146-
l_file.open_append
156+
-- create l_file.make_create_read_write ("/tmp/hitme_sheet_json-append.json")
157+
-- logger.write_information ("get_from_id->Writing body into " + l_file.path.utf_8_name)
158+
-- l_file.close
159+
-- l_file.wipe_out
160+
-- l_file.open_append
147161

148-
l_file.put_string (l_body)
149-
l_file.close
162+
-- l_file.put_string (l_body)
163+
-- l_file.close
150164
elseif l_response.status = {HTTP_STATUS_CODE}.not_found then
151165
logger.write_error ("get_from_id-> Not found:" + l_response.status.out + " %NBody: " + l_body)
152166
else
@@ -260,25 +274,25 @@ feature -- Versions
260274

261275
feature {NONE} -- Implementation
262276

263-
api_post_call (a_api_url: STRING; a_params: detachable STRING_TABLE [STRING]; a_upload_data: detachable TUPLE[data:PATH; content_type: STRING])
277+
api_post_call (a_api_url: STRING; a_params: detachable STRING_TABLE [STRING]; a_payload: detachable STRING; a_upload_data: detachable TUPLE[data:PATH; content_type: STRING])
264278
-- POST REST API call for `a_api_url'
265279
do
266-
internal_api_call (a_api_url, "POST", a_params, a_upload_data)
280+
internal_api_call (a_api_url, "POST", a_params, a_payload, a_upload_data)
267281
end
268282

269283
api_delete_call (a_api_url: STRING; a_params: detachable STRING_TABLE [STRING])
270284
-- DELETE REST API call for `a_api_url'
271285
do
272-
internal_api_call (a_api_url, "DELETE", a_params, Void)
286+
internal_api_call (a_api_url, "DELETE", a_params, Void, Void)
273287
end
274288

275289
api_get_call (a_api_url: STRING; a_params: detachable STRING_TABLE [STRING])
276290
-- GET REST API call for `a_api_url'
277291
do
278-
internal_api_call (a_api_url, "GET", a_params, Void)
292+
internal_api_call (a_api_url, "GET", a_params, Void, Void)
279293
end
280294

281-
internal_api_call (a_api_url: STRING; a_method: STRING; a_params: detachable STRING_TABLE [STRING]; a_upload_data: detachable TUPLE[filename:PATH; content_type: STRING])
295+
internal_api_call (a_api_url: STRING; a_method: STRING; a_params: detachable STRING_TABLE [STRING]; a_payload: detachable STRING; a_upload_data: detachable TUPLE[filename:PATH; content_type: STRING])
282296
note
283297
EIS:"name=access token", "src=https://developers.google.com/identity/protocols/oauth2", "protocol=uri"
284298
local
@@ -304,7 +318,7 @@ feature {NONE} -- Implementation
304318
-- Create the access token that will identifies the user making the request.
305319
create l_access_token.make_token_secret (access_token, "NOT_NEEDED")
306320
--| Todo improve access_token to create a token without a secret.
307-
if attached l_access_token as ll_access_token then
321+
check attached l_access_token as ll_access_token then
308322
logger.write_information ("internal_api_call->Got the Access Token:" + ll_access_token.token);
309323

310324
--Now let's go and check if the request is signed correcty
@@ -314,10 +328,23 @@ feature {NONE} -- Implementation
314328
-- Workaorund to make it work with Google API
315329
-- in other case it return HTTP 411 Length Required.
316330
-- Todo check.
317-
request.add_header ("Content-length", "0")
318331
upload_data (a_method, request, a_upload_data)
319332
add_parameters (a_method, request, a_params)
333+
-- adding payload
334+
if attached a_payload then
335+
request.add_header ("Content-length", a_payload.count.out)
336+
request.add_header ("Content-Type", "application/json; charset=UTF-8")
337+
request.add_payload (a_payload)
338+
else
339+
request.add_header ("Content-length", "")
340+
end
341+
320342
api_service.sign_request (ll_access_token, request)
343+
344+
logger.write_debug ("internal_api_call->uri:'" + request.uri + "'")
345+
if attached request.upload_file as l_s then
346+
logger.write_debug ("internal_api_call->upload file:'" + l_s + "'")
347+
end
321348
if attached {OAUTH_RESPONSE} request.execute as l_response then
322349
last_response := l_response
323350
end
@@ -423,9 +450,10 @@ feature {NONE} -- Implementation
423450
l_raw_file: RAW_FILE
424451
do
425452
if a_method.is_case_insensitive_equal_general ("POST") and then attached a_upload_data as l_upload_data then
426-
427453
create l_raw_file.make_open_read (l_upload_data.file_name.absolute_path.name)
428454
if l_raw_file.exists then
455+
logger.write_debug ("upload_data-> Content-type: '" + l_upload_data.content_type + "'")
456+
logger.write_debug ("upload_data-> upload file name: '" + l_upload_data.file_name.absolute_path.name + "'")
429457
request.add_header ("Content-Type", l_upload_data.content_type)
430458
request.set_upload_filename (l_upload_data.file_name.absolute_path.name)
431459
request.add_form_parameter("source", l_upload_data.file_name.name.as_string_32)
@@ -437,5 +465,127 @@ feature -- Service Endpoint
437465

438466
endpooint_sheets_url: STRING = "https://sheets.googleapis.com"
439467
-- base URL that specifies the network address of an API service.
468+
469+
feature {NONE} -- Implementation
470+
471+
data_file: detachable PLAIN_TEXT_FILE
472+
473+
474+
impl_append_post_data: TUPLE[data:PATH; content_type: STRING]
475+
require
476+
not attached data_file
477+
local
478+
l_res: JSON_OBJECT
479+
l_jsa_main,
480+
l_jsa_line: JSON_ARRAY
481+
482+
do
483+
create l_res.make_with_capacity (5)
484+
l_res.put_string ("ROWS", "majorDimension") -- "DIMENSION_UNSPECIFIED", "ROWS", "COLUMNS"
485+
486+
create l_jsa_main.make (10)
487+
488+
create l_jsa_line.make (2)
489+
l_jsa_line.extend (create {JSON_STRING}.make_from_string ("first_cell line 1"))
490+
l_jsa_line.extend (create {JSON_STRING}.make_from_string ("second_cell line 1"))
491+
l_jsa_main.extend (l_jsa_line)
492+
493+
l_res.put (l_jsa_main, "values")
494+
495+
496+
create data_file.make_open_temporary
497+
check
498+
attached data_file as l_df
499+
then
500+
l_df.put_string (l_res.representation)
501+
Result := [l_df.path, "application/json"]
502+
end
503+
504+
505+
-- Result.content_type :=
506+
507+
508+
logger.write_debug ("impl_append_body-> Result: '" + Result.out + "'")
509+
ensure
510+
attached data_file
511+
end
512+
513+
impl_append_post_data2: STRING
514+
local
515+
l_res: JSON_OBJECT
516+
l_jsa_main,
517+
l_jsa_line: JSON_ARRAY
518+
j_array: JSON_ARRAY
519+
520+
--{
521+
-- "range": string,
522+
-- "majorDimension": enum (Dimension),
523+
-- "values": [
524+
-- array
525+
-- ]
526+
--}
527+
--// "values": [
528+
-- // [
529+
-- // "Item",
530+
-- // "Cost"
531+
-- // ],
532+
-- // [
533+
-- // "Wheel",
534+
-- // "$20.50"
535+
-- // ],
536+
-- // [
537+
-- // "Door",
538+
-- // "$15"
539+
-- // ],
540+
-- // [
541+
-- // "Engine",
542+
-- // "$100"
543+
-- // ],
544+
-- // [
545+
-- // "Totals",
546+
-- // "$135.50"
547+
-- // ]
548+
-- // ]
549+
550+
do
551+
create l_res.make_with_capacity (5)
552+
l_res.put_string ("Sheet1!A1:B5", "range")
553+
l_res.put_string ("ROWS", "majorDimension") -- "DIMENSION_UNSPECIFIED", "ROWS", "COLUMNS"
554+
555+
create l_jsa_main.make (10)
556+
557+
create j_array.make (1)
558+
create l_jsa_line.make (2)
559+
l_jsa_line.extend (create {JSON_STRING}.make_from_string ("Item"))
560+
l_jsa_line.extend (create {JSON_STRING}.make_from_string ("Cost"))
561+
j_array.add (l_jsa_line)
562+
563+
create l_jsa_line.make (2)
564+
l_jsa_line.extend (create {JSON_STRING}.make_from_string ("Wheel"))
565+
l_jsa_line.extend (create {JSON_STRING}.make_from_string ("$20.50"))
566+
j_array.add (l_jsa_line)
567+
568+
create l_jsa_line.make (2)
569+
l_jsa_line.extend (create {JSON_STRING}.make_from_string ("Door"))
570+
l_jsa_line.extend (create {JSON_STRING}.make_from_string ("$15"))
571+
j_array.add (l_jsa_line)
572+
573+
create l_jsa_line.make (2)
574+
l_jsa_line.extend (create {JSON_STRING}.make_from_string ("Engine"))
575+
l_jsa_line.extend (create {JSON_STRING}.make_from_string ("$100"))
576+
j_array.add (l_jsa_line)
577+
578+
create l_jsa_line.make (2)
579+
l_jsa_line.extend (create {JSON_STRING}.make_from_string ("Totals"))
580+
l_jsa_line.extend (create {JSON_STRING}.make_from_string ("$135.50"))
581+
j_array.add (l_jsa_line)
582+
583+
584+
l_res.put (j_array, "values")
585+
586+
Result := l_res.representation
587+
logger.write_debug ("impl_append_body-> Result: '" + Result.out + "'")
588+
end
589+
440590
end
441591

sheets/test/application_flow.e

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ feature {NONE} -- Initialization
2222
create last_token.make_empty
2323
get_token
2424
if last_token.token.is_empty then
25-
logger.write_warning ("retrieve_access_token-> There is something wrong token is empty")
25+
logger.write_warning ("retrieve_access_token-> There is something wrong token is empty from file_path: " + Token_file_path_s)
2626
check
2727
not_happening: False
2828
end
@@ -39,7 +39,7 @@ feature {NONE} -- Initialization
3939
l_date_now: DATE_TIME
4040
l_diff: INTEGER_64
4141
do
42-
create {PLAIN_TEXT_FILE} file.make_with_name ("token.access")
42+
create {PLAIN_TEXT_FILE} file.make_with_name (Token_file_path_s)
4343
if file.exists then
4444
file.open_read
4545
file.read_stream (file.count)
@@ -97,7 +97,7 @@ feature {NONE} -- Initialization
9797
end
9898

9999
if attached api_service.access_token_post (empty_token, create {OAUTH_VERIFIER}.make (io.last_string)) as access_token then
100-
create {PLAIN_TEXT_FILE} file.make_create_read_write ("token.access")
100+
create {PLAIN_TEXT_FILE} file.make_create_read_write (Token_file_path_s)
101101
file.put_string (serialize (access_token))
102102
Result := access_token
103103
file.flush
@@ -137,7 +137,7 @@ feature {NONE} -- Initialization
137137
if attached request.execute as l_response then
138138
if attached l_response.body as l_body then
139139
if attached {OAUTH_TOKEN} google.access_token_extractor.extract (l_body) as l_access_token then
140-
create {PLAIN_TEXT_FILE} file.make_create_read_write ("token.access")
140+
create {PLAIN_TEXT_FILE} file.make_create_read_write (Token_file_path_s)
141141
file.put_string (serialize (l_access_token))
142142
Result := l_access_token
143143
file.flush
@@ -148,6 +148,10 @@ feature {NONE} -- Initialization
148148
end
149149
end
150150

151+
feature -- Access
152+
153+
Token_file_path_s: STRING = "token.access"
154+
151155
feature -- Status Setting
152156

153157
set_from_json_credentials_file_path (an_fp: PATH)

0 commit comments

Comments
 (0)