Init repo

This commit is contained in:
clerie 2025-01-04 16:54:51 +01:00
commit 15e70c94a5
4 changed files with 1892 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

1737
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

9
Cargo.toml Normal file
View 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
View 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(())
}