@@ -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_data 2
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
261275feature {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_data 2 : 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+
440590end
441591
0 commit comments