Skip to content

Commit

Permalink
READY : Test task Google Sheets CLI (#1495)
Browse files Browse the repository at this point in the history
* Test task Google Sheets CLI

* format_tools, mod_interface and usage information added

* formating fixed

* formating fixed

* formating fixed

* tests added, debug dir removed, output fixed

* info fixed

* cells command were added

* format fixed

* some code was commented

---------

Co-authored-by: vsevolod <[email protected]>
Co-authored-by: Vsevolod <[email protected]>
  • Loading branch information
3 people authored Dec 3, 2024
1 parent 4330d03 commit 2e7e3de
Show file tree
Hide file tree
Showing 33 changed files with 1,839 additions and 18 deletions.
34 changes: 17 additions & 17 deletions module/core/process_tools/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ mod private
// let ( program, args ) =
// if cfg!( target_os = "windows" )
// {
// ( "cmd", [ "/C", exec_path ] )
// ( "gspread", [ "/C", exec_path ] )
// }
// else
// {
Expand Down Expand Up @@ -234,22 +234,22 @@ mod private
/// # Returns:
/// A `Result` containing a `Report` on success, which includes the command's output,
/// or an error if the command fails to execute or complete.
pub fn run_with_shell( self, exec_path : &str, ) -> Result< Report, Report >
{
let ( program, args ) =
if cfg!( target_os = "windows" )
{
( "cmd", [ "/C", exec_path ] )
}
else
{
( "sh", [ "-c", exec_path ] )
};
self
.args( args.into_iter().map( OsString::from ).collect::< Vec< _ > >() )
.bin_path( program )
.run()
}
// pub fn run_with_shell( self, exec_path : &str, ) -> Result< Report, Report >
// {
// let ( program, args ) =
// if cfg!( target_os = "windows" )
// {
// ( "gspread", [ "/C", exec_path ] )
// }
// else
// {
// ( "sh", [ "-c", exec_path ] )
// };
// self
// .args( args.into_iter().map( OsString::from ).collect::< Vec< _ > >() )
// .bin_path( program )
// .run()
// }
}

/// Process command output.
Expand Down
44 changes: 44 additions & 0 deletions module/move/gspread/.key/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Getting API Keys for OAuth Authentication

Follow these steps to create and configure your OAuth credentials for using Google APIs.

## 1. Create API Credentials

1. Go to the [Google API Console](https://console.developers.google.com/).
2. From the projects list, select an existing project or create a new one.
3. In the left side menu, select **APIs & Services**.
4. On the left menu, click **Credentials**.
5. Click **Create Credentials** and select **OAuth client ID**.
6. In the **Application type** section, select **Desktop app**.
7. Provide an appropriate name for your client ID (e.g., "MyApp OAuth Client").
8. Click **Create**.

Once the credential is created, you will receive a **Client ID** and **Client Secret**. These are required for accessing the API.

## 2. Store Your Credentials

Save the **Client ID** and **Client Secret** in a `.sh` file (e.g., `-env.sh`) within a `key` directory. The file should look like this:

```bash
CLIENT_ID=YOUR_CLIENT_ID
CLIENT_SECRET=YOUR_SECRET_KEY
```

Set also these keys with following values:
```bash
AUTH_URI=https://accounts.google.com/o/oauth2/auth
TOKEN_URI=https://oauth2.googleapis.com/token
```
If you get problems, most likely you will need to change **AUTH_URI** or **TOKEN_URI** to the appropriate one. Try to download your API KEY that you created in JSON format. Then open it and you will see right links. Just copy them and past to file.
Otherwise, follow [Google OAuth Documentation](https://developers.google.com/identity/protocols/oauth2/) to solve them.
Most likely you will need to change **AUTH_URI** or **TOKEN_URI** to the appropriate one.

## How to Use in Shell

To apply these variables to your current shell session, use:

```bash
. ./key/-env.sh
```

This command sources the script, making the variables available in your current session. Ensure `-env.sh` is in the `key` directory relative to your current location.
47 changes: 47 additions & 0 deletions module/move/gspread/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[package]
name = "gspread"
version = "0.1.0"
edition = "2021"
authors = [
"Vsevolod Bakutov <[email protected]>"
]
license = "MIT"
description = """
Google Sheets Cli API
"""
categories = [ "algorithms", "development-tools" ]
keywords = [ "fundamental", "general-purpose" ]
default-run = "main"

[[bin]]
name = "main"
path = "src/bin/main.rs"

[features]
default = [ "enabled" ]
full = [ "enabled" ]
enabled = [
"former/enabled",
"format_tools/enabled",
"reflect_tools/enabled",
]

[dependencies]
mod_interface = { workspace = true, features = ["full"] }
former = { workspace = true, features = ["full"] }
format_tools = { workspace = true, features = ["full"] }
reflect_tools = { workspace = true, features = [ "full" ] }
clap = { version = "4.5.20", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
google-sheets4 = "*"
pth = "0.21.0"
dotenv = "0.15"
serde = { version = "1.0.213", features = ["derive"] }
serde_with = "3.11.0"
error_tools = "0.19.0"
derive_tools = { version = "0.32.0", features = ["full"] }
serde_json = "1.0.132"
regex = "1.11.1"

[dev-dependencies]
test_tools = { workspace = true }
1 change: 1 addition & 0 deletions module/move/gspread/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## Google Sheets CLI
16 changes: 16 additions & 0 deletions module/move/gspread/src/actions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//!
//! CLI actions of the tool.
//!
mod private {}

crate::mod_interface!
{
layer gspread;
layer gspread_get_header;
layer gspread_get_rows;
layer gspread_cell_get;
layer gspread_cell_set;
layer gspread_cells_set;
}

57 changes: 57 additions & 0 deletions module/move/gspread/src/actions/gspread.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//!
//! Google Sheets API actions.
//!
//! This module also contains the definition of Google Sheets Error.
//!
mod private
{
use regex::Regex;
use error_tools::typed::Error;
use derive_tools::AsRefStr;
use crate::*;
use ser::DisplayFromStr;

#[ ser::serde_as ]
#[ derive( Debug, Error, AsRefStr, ser::Serialize ) ]
#[ serde( tag = "type", content = "data" ) ]
pub enum Error
{
#[ error( "Google Sheets returned error:\n{0}" ) ]
ApiError
(
#[ from ]
#[ serde_as( as = "DisplayFromStr" ) ]
google_sheets4::Error
)
}

pub fn get_spreadsheet_id_from_url
(
url : &str
) -> Option< &str >
{

let re = Regex::new( r"d/([^/]+)/edit" ).unwrap();
if let Some( captures ) = re.captures( url )
{
if let Some( id ) = captures.get( 1 )
{
return Some( id.as_str() );
}
}

None
}

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

crate::mod_interface!
{
own use
{
Result,
get_spreadsheet_id_from_url,
};
}
42 changes: 42 additions & 0 deletions module/move/gspread/src/actions/gspread_cell_get.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//!
//! Action for command "cell get"
//!
//! It returns a selected cell
//!
mod private
{
use crate::*;
use actions::gspread::Result;
use client::SheetsType;
use ser::JsonValue;

pub async fn action
(
hub : &SheetsType,
spreadsheet_id : &str,
table_name : &str,
cell_id : &str,
) -> Result< JsonValue >
{
let result = hub
.spreadsheets()
.values_get( spreadsheet_id, format!( "{}!{}", table_name, cell_id ).as_str() )
.doit()
.await?
.1
.values;

match result
{
Some( values ) => Ok( values.get( 0 ).unwrap().get( 0 ).unwrap().clone() ),
None => Ok( JsonValue::Null.clone() )
}

}
}

crate::mod_interface!
{
own use action;
}
50 changes: 50 additions & 0 deletions module/move/gspread/src/actions/gspread_cell_set.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//!
//! Action for command "cell set"
//!
//! It updates a selected cell
//!

mod private
{
use google_sheets4::api::ValueRange;
use crate::*;
use actions::gspread::Result;
use client::SheetsType;
use ser::JsonValue;

pub async fn action
(
hub : &SheetsType,
spreadsheet_id : &str,
table_name : &str,
cell_id : &str,
value : &str
) -> Result< i32 >
{

let value = JsonValue::String( value.to_string() );
let value_range = ValueRange
{
values : Some( vec![ vec![ value ] ] ),
..ValueRange::default()
};

let result = 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();

Ok( result )
}
}

crate::mod_interface!
{
own use action;
}
Loading

0 comments on commit 2e7e3de

Please sign in to comment.