Init repo
This commit is contained in:
commit
15e70c94a5
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target
|
1737
Cargo.lock
generated
Normal file
1737
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
9
Cargo.toml
Normal file
9
Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "etecal"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1.0.95"
|
||||||
|
clap = { version = "4.5.23", features = ["derive"] }
|
||||||
|
etebase = "0.6.0"
|
145
src/main.rs
Normal file
145
src/main.rs
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
use anyhow::{
|
||||||
|
bail,
|
||||||
|
Context,
|
||||||
|
Result,
|
||||||
|
};
|
||||||
|
use clap::{
|
||||||
|
Parser,
|
||||||
|
Subcommand,
|
||||||
|
};
|
||||||
|
use etebase::{
|
||||||
|
Account,
|
||||||
|
Client,
|
||||||
|
};
|
||||||
|
use std::fs::{
|
||||||
|
File,
|
||||||
|
};
|
||||||
|
use std::io::{
|
||||||
|
Write,
|
||||||
|
};
|
||||||
|
use std::path::{
|
||||||
|
PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Subcommand, Clone)]
|
||||||
|
#[command(arg_required_else_help = true)]
|
||||||
|
enum Commands {
|
||||||
|
/// Login with user account
|
||||||
|
Login {
|
||||||
|
#[arg(long)]
|
||||||
|
url: String,
|
||||||
|
user: String,
|
||||||
|
pass: String,
|
||||||
|
},
|
||||||
|
/// Display available calendars
|
||||||
|
Calendars,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(version, about, long_about = None, arg_required_else_help = true)]
|
||||||
|
struct Cli {
|
||||||
|
#[command(subcommand)]
|
||||||
|
command: Option<Commands>,
|
||||||
|
/// Path to config directory
|
||||||
|
#[arg(long)]
|
||||||
|
config: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_data_dir() -> Result<PathBuf> {
|
||||||
|
if let Ok(xdg_data_home) = std::env::var("XDG_DATA_HOME") {
|
||||||
|
let mut p = PathBuf::from(xdg_data_home);
|
||||||
|
p.push("etecal");
|
||||||
|
return Ok(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(home) = std::env::var("HOME") {
|
||||||
|
let mut p = PathBuf::from(home);
|
||||||
|
p.push(".local/share/etecal");
|
||||||
|
return Ok(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
bail!("Failed to determine data directory");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_url_file_path() -> Result<PathBuf> {
|
||||||
|
let data_dir = get_data_dir()
|
||||||
|
.context("Failed to find data dir")?;
|
||||||
|
|
||||||
|
let mut url_file_path = PathBuf::from(data_dir.clone());
|
||||||
|
url_file_path.push("url");
|
||||||
|
|
||||||
|
return Ok(url_file_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_url() -> Result<String> {
|
||||||
|
let url = std::fs::read_to_string(get_url_file_path()?)
|
||||||
|
.context("Failed to restore API url")?;
|
||||||
|
|
||||||
|
return Ok(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_stored_session_file_path() -> Result<PathBuf> {
|
||||||
|
let data_dir = get_data_dir()
|
||||||
|
.context("Failed to find data dir")?;
|
||||||
|
|
||||||
|
let mut stored_session_file_path = PathBuf::from(data_dir.clone());
|
||||||
|
stored_session_file_path.push("session");
|
||||||
|
|
||||||
|
return Ok(stored_session_file_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_stored_session() -> Result<String> {
|
||||||
|
let stored_session = std::fs::read_to_string(get_stored_session_file_path()?)
|
||||||
|
.context("Failed to read restored session")?;
|
||||||
|
|
||||||
|
return Ok(stored_session);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn restore_etebase_session() -> Result<Account> {
|
||||||
|
let client = Client::new("etecal", &get_url()?)
|
||||||
|
.context("Failed to init API client")?;
|
||||||
|
|
||||||
|
let etebase = Account::restore(client, &get_stored_session()?, None)?;
|
||||||
|
|
||||||
|
return Ok(etebase);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn store_etebase_session(url: &str, user: &str, pass: &str) -> Result<Account> {
|
||||||
|
let client = Client::new("etecal", url)
|
||||||
|
.context("Failed to init API client")?;
|
||||||
|
|
||||||
|
let etebase = Account::login(client, user, pass)?;
|
||||||
|
|
||||||
|
std::fs::create_dir_all(get_data_dir()?)?;
|
||||||
|
|
||||||
|
File::create(get_url_file_path()?)?.write_all(url.as_bytes())?;
|
||||||
|
|
||||||
|
let stored_session = etebase.save(None)?;
|
||||||
|
|
||||||
|
File::create(get_stored_session_file_path()?)?.write_all(stored_session.as_bytes())?;
|
||||||
|
|
||||||
|
return Ok(etebase);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
let cli = Cli::parse();
|
||||||
|
|
||||||
|
let command = &cli.command.context("No command provided")?.clone();
|
||||||
|
|
||||||
|
match &command {
|
||||||
|
Commands::Login{url, user, pass} => {
|
||||||
|
store_etebase_session(url, user, pass)?;
|
||||||
|
},
|
||||||
|
Commands::Calendars => {
|
||||||
|
let etebase = restore_etebase_session()?;
|
||||||
|
|
||||||
|
let collection_manager = etebase.collection_manager()?;
|
||||||
|
for collection in collection_manager.list("etebase.vevent", None)?.data() {
|
||||||
|
println!("{} [{}]", collection.meta()?.name().unwrap(), collection.uid());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user