mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-10-15 21:48:43 -04:00
feat: Add job commands and list locations
Co-authored-by: ijamespine <ijamespine@me.com>
This commit is contained in:
1 parent
470ff03bd6
commit
e26ead654b
5 files changed
+97
-2
No files matched your search
+40
-1
@@ -47,6 +47,9 @@ enum Commands {
|
||||
/// Networking and pairing
|
||||
#[command(subcommand)]
|
||||
Network(NetworkCommands),
|
||||
/// Job commands
|
||||
#[command(subcommand)]
|
||||
Job(JobCommands),
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
@@ -116,6 +119,14 @@ enum PairCommands {
|
||||
Cancel { session_id: Uuid },
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum JobCommands {
|
||||
/// List jobs
|
||||
List { #[arg(long)] status: Option<String> },
|
||||
/// Job info
|
||||
Info { job_id: Uuid },
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct SpacedropArgs {
|
||||
/// Target device ID
|
||||
@@ -554,7 +565,13 @@ async fn main() -> Result<()> {
|
||||
println!("Added location {} -> {}", out.id, out.path.display());
|
||||
}
|
||||
Commands::Location(LocationCommands::List) => {
|
||||
println!("Listing locations is not available yet in this build");
|
||||
// If only one library exists, use it; else require --library later (omitted for brevity)
|
||||
let libs: Vec<sd_core::ops::libraries::list::output::LibraryInfo> = core
|
||||
.query(&sd_core::ops::libraries::list::query::ListLibrariesQuery::basic())
|
||||
.await?;
|
||||
let library_id = if libs.len() == 1 { libs[0].id } else { anyhow::bail!("Specify --library to list locations when multiple libraries exist") };
|
||||
let out: sd_core::ops::locations::list::output::LocationsListOutput = core.query(&sd_core::ops::locations::list::query::LocationsListQuery { library_id }).await?;
|
||||
for loc in out.locations { println!("- {} {}", loc.id, loc.path.display()); }
|
||||
}
|
||||
Commands::Location(LocationCommands::Remove { location_id }) => {
|
||||
let _out: sd_core::ops::locations::remove::output::LocationRemoveOutput = core.action(&sd_core::ops::locations::remove::action::LocationRemoveInput { location_id }).await?;
|
||||
@@ -655,6 +672,28 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
}
|
||||
}
|
||||
Commands::Job(cmd) => {
|
||||
match cmd {
|
||||
JobCommands::List { status } => {
|
||||
// There isn't a direct op; use library job manager via a helper query when available. For now, use running jobs
|
||||
let libs: Vec<sd_core::ops::libraries::list::output::LibraryInfo> = core
|
||||
.query(&sd_core::ops::libraries::list::query::ListLibrariesQuery::basic())
|
||||
.await?;
|
||||
if libs.is_empty() { println!("No libraries found"); }
|
||||
for lib in libs {
|
||||
let running = core.query(&sd_core::ops::indexing::state::RunningJobsQuery { library_id: lib.id }).await;
|
||||
if let Ok(running_jobs) = running {
|
||||
for j in running_jobs.jobs { println!("- {} {} {}%", j.id, j.name, (j.progress * 100.0) as u32); }
|
||||
} else {
|
||||
println!("Library {}: jobs listing not available", lib.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
JobCommands::Info { job_id } => {
|
||||
println!("Job {} info not available yet", job_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
pub mod query;
|
||||
pub mod output;
|
||||
|
||||
pub use query::*;
|
||||
pub use output::*;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LocationInfo {
|
||||
pub id: Uuid,
|
||||
pub path: PathBuf,
|
||||
pub name: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct LocationsListOutput {
|
||||
pub locations: Vec<LocationInfo>,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
use super::output::{LocationInfo, LocationsListOutput};
|
||||
use crate::{context::CoreContext, cqrs::Query};
|
||||
use anyhow::Result;
|
||||
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct LocationsListQuery {
|
||||
pub library_id: uuid::Uuid,
|
||||
}
|
||||
|
||||
impl Query for LocationsListQuery {
|
||||
type Output = LocationsListOutput;
|
||||
|
||||
async fn execute(self, context: Arc<CoreContext>) -> Result<Self::Output> {
|
||||
// Fetch library and query locations table
|
||||
let library = context.library_manager.get_library(self.library_id).await.ok_or_else(|| anyhow::anyhow!("Library not found"))?;
|
||||
let db = library.db().conn();
|
||||
let rows = crate::infra::db::entities::location::Entity::find()
|
||||
.filter(crate::infra::db::entities::location::Column::LibraryId.eq(self.library_id))
|
||||
.all(db)
|
||||
.await?;
|
||||
let mut out = Vec::new();
|
||||
for r in rows {
|
||||
out.push(LocationInfo { id: r.uuid, path: std::path::PathBuf::from(r.path), name: r.name });
|
||||
}
|
||||
Ok(LocationsListOutput { locations: out })
|
||||
}
|
||||
}
|
||||
|
||||
crate::register_query!(LocationsListQuery, "locations.list");
|
||||
|
||||
@@ -4,8 +4,10 @@ pub mod add;
|
||||
// pub mod index; // Module removed during migration
|
||||
pub mod remove;
|
||||
pub mod rescan;
|
||||
pub mod list;
|
||||
|
||||
pub use add::*;
|
||||
// pub use index::*; // Module removed during migration
|
||||
pub use remove::*;
|
||||
pub use rescan::*;
|
||||
pub use rescan::*;
|
||||
pub use list::*;
|
||||
Reference in new issue
Block a user