mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-03 16:41:26 +01:00
implemented offline scaffold
This commit is contained in:
1 parent
bb9804498c
commit
68e07ed426
9 files changed
+2412
-275
No files matched your search
@@ -11,7 +11,7 @@ use pdfs_core::auth;
|
||||
use pdfs_core::cache::ContentCache;
|
||||
use pdfs_core::config::AppDirs;
|
||||
use pdfs_core::control::{
|
||||
Request as CtlRequest, Response as CtlResponse, ShareEntryKind, SyncPhase,
|
||||
RefreshScope, Request as CtlRequest, Response as CtlResponse, ShareEntryKind, SyncPhase,
|
||||
};
|
||||
use pdfs_core::db::Db;
|
||||
|
||||
@@ -146,6 +146,15 @@ enum Command {
|
||||
/// Permanently delete everything in the trash. This cannot be undone.
|
||||
EmptyTrash,
|
||||
|
||||
/// Drop a cached listing so the next read re-fetches it from the server.
|
||||
/// Use it when another client changed something and the daemon hasn't
|
||||
/// noticed yet.
|
||||
Refresh {
|
||||
/// What to refresh: a folder path (inside the mountpoint or relative to
|
||||
/// it), `trash`, or `photos`. The mount root if omitted.
|
||||
target: Option<String>,
|
||||
},
|
||||
|
||||
/// Manage the account's registered devices.
|
||||
Devices {
|
||||
#[command(subcommand)]
|
||||
@@ -376,6 +385,7 @@ fn main() -> Result<()> {
|
||||
Command::Restore { uids } => cmd_restore(uids),
|
||||
Command::DeleteForever { uids } => cmd_delete_forever(uids),
|
||||
Command::EmptyTrash => cmd_empty_trash(),
|
||||
Command::Refresh { target } => cmd_refresh(target),
|
||||
Command::Devices { action } => cmd_devices(action),
|
||||
Command::Sync { action } => cmd_sync(action),
|
||||
Command::Share {
|
||||
@@ -451,14 +461,23 @@ fn cmd_sync(action: SyncCmd) -> Result<()> {
|
||||
} else {
|
||||
f.last_sync.to_string()
|
||||
};
|
||||
// A queued switch is reported as the mode the folder is moving
|
||||
// to, so `sync list` never reads as if the request was dropped.
|
||||
let mode = match &f.pending_mode {
|
||||
Some(pending) => format!("{} → {pending}", f.mode),
|
||||
None => f.mode.clone(),
|
||||
};
|
||||
println!(
|
||||
"[{}] {} ({}, {}, synced: {sync})",
|
||||
f.id, f.local_path, f.mode, f.state
|
||||
"[{}] {} ({mode}, {}, synced: {sync})",
|
||||
f.id, f.local_path, f.state
|
||||
);
|
||||
// A pass in flight says what it is doing, indented under it.
|
||||
if let Some(p) = &f.progress {
|
||||
match p.phase {
|
||||
SyncPhase::Scanning => println!(" scanning…"),
|
||||
SyncPhase::Scanning if p.total == 0 => println!(" scanning…"),
|
||||
SyncPhase::Scanning => {
|
||||
println!(" scanning: {} of {}", p.done, p.total.max(p.done))
|
||||
}
|
||||
SyncPhase::Applying => println!(
|
||||
" {} of {} {}",
|
||||
p.done + 1,
|
||||
@@ -809,9 +828,19 @@ fn cmd_status() -> Result<()> {
|
||||
// If a mount daemon is running, report live status from its control socket.
|
||||
match control_request(CtlRequest::Status) {
|
||||
Ok(CtlResponse::Status {
|
||||
mountpoint, pinned, ..
|
||||
mountpoint,
|
||||
pinned,
|
||||
online,
|
||||
pending_uploads,
|
||||
..
|
||||
}) => {
|
||||
println!("Mounted at {mountpoint} ({pinned} pinned)");
|
||||
let state = if online { "" } else { ", offline" };
|
||||
let queued = match pending_uploads {
|
||||
0 => String::new(),
|
||||
1 => ", 1 upload queued".to_string(),
|
||||
n => format!(", {n} uploads queued"),
|
||||
};
|
||||
println!("Mounted at {mountpoint} ({pinned} pinned{state}{queued})");
|
||||
}
|
||||
Ok(other) => println!("Mount: unexpected response {other:?}"),
|
||||
Err(_) => println!("Mount: not running."),
|
||||
@@ -1166,6 +1195,25 @@ fn cmd_empty_trash() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Drop a cached listing. `trash` and `photos` name those two listings; anything
|
||||
/// else is read as a folder path, so a folder actually called "trash" is still
|
||||
/// reachable as `./trash`.
|
||||
fn cmd_refresh(target: Option<String>) -> Result<()> {
|
||||
let scope = match target.as_deref() {
|
||||
Some("trash") => RefreshScope::Trash,
|
||||
Some("photos") => RefreshScope::Photos,
|
||||
path => RefreshScope::Dir {
|
||||
path: path.unwrap_or("").to_string(),
|
||||
},
|
||||
};
|
||||
match control_request(CtlRequest::Refresh { scope })? {
|
||||
CtlResponse::Ok { message } => println!("{message}"),
|
||||
CtlResponse::Error { message } => bail!("{message}"),
|
||||
other => bail!("unexpected response: {other:?}"),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Ask for a typed `yes` before an irreversible destroy. Errors (aborting the
|
||||
/// command) on anything else, including a non-interactive stdin: a piped or
|
||||
/// scripted invocation must not silently wipe the trash.
|
||||
|
||||
Reference in new issue
Block a user