diff --git a/CHANGELOG.md b/CHANGELOG.md index 49f0d49..95ee000 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,5 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * subscriptions * episode changes * devices + * device sync API * Flexible configuration via a TOML config file, environment variables or CLI arguments +* CLI tooling for interacting with the database diff --git a/README.md b/README.md index 50497b6..5ef8cea 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Gpodder, suitable for low-power devices. * Devices API * Subscriptions API * Episode actions API + * Device synchronisation API ## Configuration diff --git a/src/cli/gpo.rs b/src/cli/gpo.rs new file mode 100644 index 0000000..cbf5dbd --- /dev/null +++ b/src/cli/gpo.rs @@ -0,0 +1,45 @@ +use clap::Subcommand; + +use crate::db; + +#[derive(Subcommand)] +pub enum Command { + /// Add devices of a specific user to the same sync group + Sync { + username: String, + devices: Vec, + }, + /// List the devices for the given user + Devices { username: String }, +} + +impl Command { + pub fn run(&self, config: &crate::config::Config) -> u8 { + let pool = db::initialize_db(config.data_dir.join(crate::DB_FILENAME), true).unwrap(); + let repo = db::SqliteRepository::from(pool); + let store = crate::gpodder::GpodderRepository::new(repo); + + match self { + Self::Sync { username, devices } => { + let user = store.get_user(&username).unwrap(); + store + .update_device_sync_status( + &user, + vec![devices.iter().map(|s| s.as_ref()).collect()], + Vec::new(), + ) + .unwrap(); + } + Self::Devices { username } => { + let user = store.get_user(&username).unwrap(); + let devices = store.devices_for_user(&user).unwrap(); + + for device in devices { + println!("{} ({} subscriptions)", device.id, device.subscriptions); + } + } + } + + 0 + } +} diff --git a/src/cli/mod.rs b/src/cli/mod.rs index ee50121..dc0a8ba 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,4 +1,5 @@ mod db; +mod gpo; mod serve; use std::path::PathBuf; @@ -49,6 +50,11 @@ pub enum Command { Serve, #[command(subcommand)] Db(db::DbCommand), + + /// Perform operations on the database through the Gpodder abstraction, allowing operations + /// identical to the ones performed by the API. + #[command(subcommand)] + Gpo(gpo::Command), } impl Cli { @@ -75,6 +81,7 @@ impl Cli { match &self.cmd { Command::Serve => serve::serve(&config), Command::Db(cmd) => cmd.run(&config), + Command::Gpo(cmd) => cmd.run(&config), } } } diff --git a/src/gpodder/repository.rs b/src/gpodder/repository.rs index d197cd5..942ef26 100644 --- a/src/gpodder/repository.rs +++ b/src/gpodder/repository.rs @@ -34,6 +34,10 @@ impl GpodderRepository { } } + pub fn get_user(&self, username: &str) -> Result { + self.store.get_user(username)?.ok_or(AuthErr::UnknownUser) + } + pub fn validate_credentials( &self, username: &str,