Skip to content

Commit

Permalink
FIX GSPREAD: fix gspread structure (#1516)
Browse files Browse the repository at this point in the history
* added: error handling and nice output for cell set

* fixed: cell get

* fixed: error handling for all actions

* added: help description

* fixed gspread_cell_set action returning value

* fixed: sheet name in description

* fixed: commands examples

* added mock for oauth2

* with_online added to tests

* added third oauth2 endpoint

* feature with_online

* added mock tests

* with_online fixed

* fixed gspread_cells_set return type

* fixed display

* draft wrap_function

* something bad

* update_row function and documentation for some functions and structures were added

---------

Co-authored-by: Vsevolod <[email protected]>
  • Loading branch information
sevabakutov and Vsevolod authored Dec 30, 2024
1 parent 33f1d1a commit b0a22e6
Show file tree
Hide file tree
Showing 24 changed files with 984 additions and 237 deletions.
2 changes: 2 additions & 0 deletions module/core/format_tools/src/format/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ mod private
#[ derive( Debug, Default ) ]
pub struct RowDescriptor
{


/// Index of the row.
pub irow : usize,
/// Height of the row.
Expand Down
4 changes: 4 additions & 0 deletions module/move/gspread/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ name = "main"
path = "src/bin/main.rs"

[features]
with_online = []
default = [ "enabled" ]
full = [ "enabled" ]
enabled = [
Expand All @@ -44,6 +45,9 @@ error_tools = "0.19.0"
derive_tools = { version = "0.32.0", features = ["full"] }
serde_json = "1.0.132"
regex = "1.11.1"
unicode-width = "0.2.0"

[dev-dependencies]
test_tools = { workspace = true }
httpmock = "0.7.0-rc.1"
reqwest = "0.12.9"
150 changes: 148 additions & 2 deletions module/move/gspread/src/actions/gspread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,35 @@ mod private
use error_tools::typed::Error;
use derive_tools::AsRefStr;
use crate::*;
use ser::DisplayFromStr;
use ser::
{
DisplayFromStr,
JsonValue
};
use std::collections::HashMap;
use google_sheets4::api::
{
BatchUpdateValuesResponse,
BatchUpdateValuesRequest,
ValueRange
};

#[ ser::serde_as ]
#[ derive( Debug, Error, AsRefStr, ser::Serialize ) ]
#[ serde( tag = "type", content = "data" ) ]

/// Represents errors that can occur while interacting with the Google Sheets API
/// or during related operations in the application.
pub enum Error
{
/// Represents an error returned by the Google Sheets API.
///
/// # Details
/// This error occurs when the API returns a specific error message.
/// The error message from the Google Sheets API is stored and displayed.
///
/// # Fields
/// - `google_sheets4::Error`: The raw error returned by the API.
#[ error( "Google Sheets returned error:\n{0}" ) ]
ApiError
(
Expand All @@ -25,13 +47,75 @@ mod private
google_sheets4::Error
),

#[ error( "Invalid URL format: {0}" ) ]
/// Represents an error that occurs while initializing Google Sheets Hub.
///
/// # Details
/// This error indicates that the application failed to properly configure with the Google Sheets Hub.
///
/// # Fields
/// - `String`: A detailed error message describing the issue.
#[ error( "Hub Error:\n{0}" ) ]
HubError
(
String
),

/// Represents an error caused by an invalid URL format.
///
/// # Details
/// This error occurs when the provided URL does not match the expected format
///
/// # Fields
/// - `String`: The invalid URL or a message describing the issue.
#[ error( "Invalid URL format:\n{0}" ) ]
InvalidUrl
(
String
),

/// Represents an error related to a cell in the spreadsheet.
///
/// # Details
/// This error indicates that a cell was not got or updated
///
/// # Fields
/// - `String`: A message describing the issue with the cell.
#[ error( "Cell error:\n{0}" ) ]
CellError
(
String
),

/// Represents an error caused by invalid JSON input or parsing issues.
///
/// # Details
/// This error occurs when the provided JSON data does not conform to the expected
/// structure or format.
///
/// # Fields
/// - `String`: A detailed error message describing the JSON issue.
#[ error( "Invalid JSON format:\n{0}" ) ]
InvalidJSON
(
String
),

/// Represents a generic parsing error.
///
/// # Details
/// This error is raised when a string or other input cannot be parsed
/// into the expected format or structure.
///
/// # Fields
/// - `String`: A message describing the parse error.
#[ error( "Parse error:\n{0}" ) ]
ParseError
(
String
)
}

/// Retrive spreadsheet id from url
pub fn get_spreadsheet_id_from_url
(
url : &str
Expand All @@ -53,14 +137,76 @@ mod private
)
}

/// Function to update a row on a Google Sheet.
///
/// It sends HTTP request to Google Sheets API and change row wich provided values.
///
/// **Params**
/// - `spreadsheet_id` : Spreadsheet identifire.
/// - `sheet_name` : Sheet name.
/// - `row_key` : row's key.
/// - `row_key_val` : pairs of key value, where key is a column name and value is a new value.
///
/// **Returns**
/// - `Result`
pub async fn update_row
(
spreadsheet_id : &str,
sheet_name : &str,
row_key : &str,
row_key_val : HashMap< String, String >
) -> Result< BatchUpdateValuesResponse >
{
let secret = Secret::read();
let hub = hub(&secret)
.await
.map_err( | _ | {
Error::HubError( format!( "Failed to create a hub. Ensure that you have a .env file with Secrets" ) )
})?;

let mut value_ranges = Vec::with_capacity( row_key_val.len() );

for ( col_name, value ) in row_key_val {
value_ranges.push
(
ValueRange
{
major_dimension: Some( String::from( "ROWS" ) ),
values: Some( vec![ vec![ JsonValue::String( value ) ] ] ),
range: Some( format!( "{}!{}{}", sheet_name, col_name, row_key ) ),
}
)
}

let req = BatchUpdateValuesRequest
{
value_input_option: Some( "USER_ENTERED".to_string() ),
data: Some( value_ranges ),
include_values_in_response: Some( true ),
..Default::default()
};

match hub
.spreadsheets()
.values_batch_update( req, spreadsheet_id )
.doit()
.await
{
Ok( ( _, response ) ) => Ok( response ),
Err( error ) => Err( Error::ApiError( error ) ),
}
}

pub type Result< T > = core::result::Result< T, Error >;
}

crate::mod_interface!
{
own use
{
Error,
Result,
update_row,
get_spreadsheet_id_from_url,
};
}
25 changes: 16 additions & 9 deletions module/move/gspread/src/actions/gspread_cell_get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@
mod private
{


use crate::*;
use actions::gspread::Result;
use actions::gspread::
{
Error,
Result
};
use client::SheetsType;
use ser::JsonValue;

Expand All @@ -19,18 +25,19 @@ mod private
cell_id : &str,
) -> Result< JsonValue >
{
let result = hub
match hub
.spreadsheets()
.values_get( spreadsheet_id, format!( "{}!{}", table_name, cell_id ).as_str() )
.doit()
.await?
.1
.values;

match result
.await
{
Some( values ) => Ok( values.get( 0 ).unwrap().get( 0 ).unwrap().clone() ),
None => Ok( JsonValue::Null.clone() )
Ok( (_, response ) ) =>
match response.values
{
Some( values ) => Ok( values.get( 0 ).unwrap().get( 0 ).unwrap().clone() ),
None => Ok( JsonValue::Null.clone() )
}
Err( error ) => Err( Error::ApiError( error ) )
}

}
Expand Down
25 changes: 18 additions & 7 deletions module/move/gspread/src/actions/gspread_cell_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ mod private
{
use google_sheets4::api::ValueRange;
use crate::*;
use actions::gspread::Result;
use actions::gspread::
{
Result,
Error
};
use client::SheetsType;
use ser::JsonValue;

Expand All @@ -30,17 +34,24 @@ mod private
..ValueRange::default()
};

let result = hub
match hub
.spreadsheets()
.values_update( value_range, spreadsheet_id, format!( "{}!{}", table_name, cell_id ).as_str() )
.value_input_option( "USER_ENTERED" )
.doit()
.await?
.1
.updated_cells
.unwrap();
.await
{
Ok( ( _, response) ) =>
{
match response.updated_cells
{
Some( number ) => Ok( number ),
None => Err( Error::CellError( "Some problem with cell updating".to_string() ) )
}
}
Err( error) => Err( Error::ApiError( error ) )
}

Ok( result )
}
}

Expand Down
Loading

0 comments on commit b0a22e6

Please sign in to comment.