diff --git a/Cargo.lock b/Cargo.lock index af5fb88..83edbc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3520,7 +3520,7 @@ checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" [[package]] name = "pdfs-cli" -version = "3.6.0" +version = "3.7.0" dependencies = [ "anyhow", "clap", @@ -3536,7 +3536,7 @@ dependencies = [ [[package]] name = "pdfs-core" -version = "3.6.0" +version = "3.7.0" dependencies = [ "async-trait", "base64 0.23.1", @@ -3563,7 +3563,7 @@ dependencies = [ [[package]] name = "pdfs-fuse" -version = "3.6.0" +version = "3.7.0" dependencies = [ "async-trait", "base64 0.23.1", @@ -3585,7 +3585,7 @@ dependencies = [ [[package]] name = "pdfs-gui" -version = "3.6.0" +version = "3.7.0" dependencies = [ "anyhow", "async-channel", diff --git a/Cargo.toml b/Cargo.toml index fc1f035..0bd0dbd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "2" members = ["crates/pdfs-core", "crates/pdfs-fuse", "crates/pdfs-cli", "crates/pdfs-gui"] [workspace.package] -version = "3.6.0" +version = "3.7.0" edition = "2024" license = "MIT" authors = ["Nils Pukropp "] diff --git a/crates/pdfs-cli/src/main.rs b/crates/pdfs-cli/src/main.rs index 8109bf2..90cd4ce 100644 --- a/crates/pdfs-cli/src/main.rs +++ b/crates/pdfs-cli/src/main.rs @@ -1036,10 +1036,7 @@ fn cmd_devices(action: DeviceCmd) -> Result<()> { CtlResponse::Devices { items } if items.is_empty() => println!("No devices."), CtlResponse::Devices { items } => { for d in items { - let sync = d - .last_sync - .map(|t| t.to_string()) - .unwrap_or_else(|| "never".to_string()); + let sync = last_synced(d.last_sync); let tag = match (d.adopted, d.this_device) { (true, _) => " *adopted*", (false, true) => " *this machine*", @@ -1130,11 +1127,7 @@ fn cmd_sync(action: SyncCmd) -> Result<()> { } CtlResponse::SyncFolders { items } => { for f in items { - let sync = if f.last_sync == 0 { - "never".to_string() - } else { - f.last_sync.to_string() - }; + let sync = last_synced(Some(f.last_sync)); // 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 { @@ -1915,6 +1908,15 @@ fn format_epoch(secs: i64) -> String { format!("{m:02}-{d:02} {h:02}:{mi:02}") } +/// The `synced:` column of `sync list` and `devices list`: when the last pass +/// finished, or `never`. The daemon reports 0 for a folder that never synced. +fn last_synced(secs: Option) -> String { + match secs { + Some(secs) if secs > 0 => format_epoch(secs), + _ => "never".to_string(), + } +} + fn cmd_leave(uid: String) -> Result<()> { ok_or_bail(control_request(CtlRequest::LeaveShared { uid })?) } @@ -4452,6 +4454,14 @@ mod login_wait_tests { assert_eq!(format_epoch_utc(-86_400), "1969-12-31"); } + #[test] + fn last_synced_shows_a_time_not_epoch_seconds() { + // B278: issue #46 showed `synced: 1793570850`. + assert_eq!(last_synced(Some(1_793_570_850)), "11-01 22:07"); + assert_eq!(last_synced(Some(0)), "never"); + assert_eq!(last_synced(None), "never"); + } + #[test] fn a_forged_looking_invitation_is_flagged_not_stated() { let mut entry = pdfs_core::control::DirEntry { diff --git a/docs/BUGS.md b/docs/BUGS.md index fac94e1..4356d24 100644 --- a/docs/BUGS.md +++ b/docs/BUGS.md @@ -109,6 +109,7 @@ a live account since. | Entry | Title | |---|---| +| [B278](#b278--sync-list-and-devices-list-show-the-last-sync-as-epoch-seconds) | `sync list` and `devices list` show the last sync as epoch seconds | | [B277](#b277--my-files-mounted-over-a-folder-with-files-in-it-and-hid-them) | My files mounted over a folder with files in it, and hid them | | [B274](#b274--opening-a-file-for-writing-fails-with-eio-while-its-queued-revision-lands) | Opening a file for writing fails with EIO while its queued revision lands | | [B272](#b272--after-a-folder-is-removed-and-added-again-its-file-events-go-to-the-old-id) | After a folder is removed and added again, its file events go to the old id | @@ -380,6 +381,26 @@ a live account since. Newest first. +### B278 — `sync list` and `devices list` show the last sync as epoch seconds + +**Status:** Fixed, not verified live +**Found:** 2026-11-02, issue #46. The reporter's `pdfs sync list` on 3.6.0 read +`synced: 1793570850`, a pass that finished at 2026-11-01 22:07 UTC. +**Where:** `cmd_sync` and `cmd_devices` in `crates/pdfs-cli/src/main.rs` + +**Repro:** Let a synced folder finish one pass and run `pdfs sync list`, or `pdfs devices list` +on an account with a device that synced. + +**Cause.** Both commands printed `last_sync` with `to_string()`. The activity feed already +formats the same epoch seconds with `format_epoch`. + +**Fix.** Both columns go through `last_synced`, which prints `MM-DD HH:MM` in UTC like +`pdfs activity`, and `never` for 0 or no value. `--json` output is unchanged. + +**Test:** `last_synced_shows_a_time_not_epoch_seconds` in `crates/pdfs-cli/src/main.rs`. + +--- + ### B277 — My files mounted over a folder with files in it, and hid them **Status:** Fixed, not verified live @@ -575,7 +596,9 @@ folder list has now. **Status:** Fixed, not verified live **Found:** 2026-10-31, code audit after issue #46: a folder of about 19,900 items restored on a second computer sat at `scanning…` with nothing downloaded, and the journal showed -`RequestTimeout (http 408)`. +`RequestTimeout (http 408)`. On 2026-11-01 the reporter's 3.6.0 journal showed the same pass +failing four times in four minutes with `reconcile failed id=1 error=enumerate …: HTTP transport +error`, after the laptop woke from sleep; a later pass finished. **Where:** `walk_remote` in `crates/pdfs-fuse/src/sync.rs` **Repro:** Restore or add a mirror folder with tens of thousands of items on Drive, on a link diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index da3abf4..968efc8 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -11,6 +11,10 @@ scratch (user data in `staging/` and `recovery/` is never touched by this). ## [Unreleased] +## [3.7.0] — 2026-11-02 + +Schema: **44**, unchanged. + ### Added - **The app and the tray say why your Drive does not open** (B263, #40). When the service runs @@ -78,6 +82,9 @@ scratch (user data in `staging/` and `recovery/` is never touched by this). - **A restore that skipped folders is reported as failed**, with the reason for each, instead of "restored 0 folder(s)" as a success (B269). +- **`pdfs sync list` and `pdfs devices list` show when a folder last synced as a time**, such as + `synced: 11-01 22:07` in UTC like `pdfs activity`, instead of seconds since 1970 (B278, #46). + - **"You're offline" no longer appears for a cache or database error** when pinning, unpinning, searching or loading a folder (B266, #38). The app shows the actual error. diff --git a/docs/INSTALL.md b/docs/INSTALL.md index a4ec509..3731583 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -102,7 +102,7 @@ That URL follows `main`. To stay on releases, pin the input to a release tag ins the tag to update: ```nix -inputs.proton-drive-linux.url = "github:narrrl/proton-drive-linux/v3.6.0"; +inputs.proton-drive-linux.url = "github:narrrl/proton-drive-linux/v3.7.0"; ``` Each release tag is built with Nix before the release is published. diff --git a/packaging/PKGBUILD b/packaging/PKGBUILD index 7079b8d..fe35901 100644 --- a/packaging/PKGBUILD +++ b/packaging/PKGBUILD @@ -9,7 +9,7 @@ # Build + install: cd packaging && makepkg -fi pkgname=proton-drive-linux -pkgver=3.6.0 +pkgver=3.7.0 pkgrel=1 pkgdesc="Unofficial Proton Drive client for Linux: files-on-demand FUSE mount, CLI, GTK4 app + tray" arch=('x86_64') diff --git a/packaging/proton-drive-linux.spec b/packaging/proton-drive-linux.spec index 8d8ed57..a4c1005 100644 --- a/packaging/proton-drive-linux.spec +++ b/packaging/proton-drive-linux.spec @@ -10,7 +10,7 @@ # Match Arch PKGBUILD `!lto` — LTO has broken some GTK/Rust links in practice. %global _lto_cflags %{nil} -%{!?version: %global version 3.6.0} +%{!?version: %global version 3.7.0} %global forge https://github.com/narrrl/proton-drive-linux # Files come from the checkout, or from the unpacked tag archive. %global src %{?git_dir}%{!?git_dir:.} diff --git a/po/pdfs.pot b/po/pdfs.pot index 0a6f3f2..ebeac28 100644 --- a/po/pdfs.pot +++ b/po/pdfs.pot @@ -6,7 +6,7 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: proton-drive-linux 3.6.0\n" +"Project-Id-Version: proton-drive-linux 3.7.0\n" "Report-Msgid-Bugs-To: https://github.com/narrrl/proton-drive-linux/issues\n" "POT-Creation-Date: 2026-11-01 17:51+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"