v0.2.2: device-sync guards — quit warning, sleep/shutdown inhibition
Quitting mid-transfer now asks (Keep Syncing / Quit Anyway) from closeEvent, which every quit path hits — including the self-update restart, which previously bypassed closeEvent via a bare quit() and now routes through close(). A running sync holds its own GNOME inhibitor (suspend + logout, "Syncing a playlist to a device") so the machine won't sleep or shutdown/restart under a copy. Along the way: the Inhibit D-Bus call marshaled Python ints as signed against GNOME's (susu) signature, so every call was rejected and the playback sleep inhibitor had silently never worked — _uint fixes both holders (verified live: cookies taken, IsInhibited flips, releases clean). Also investigated trav's mid-copy Syncthing question: the transfer works from a click-time snapshot and never reads live library state, so remote changes can't corrupt it — no state freeze needed. Hardened the one real gap: a source file relocated under the queue (remote metadata edit moving files) is now skipped, dropped from the m3u, and reported, instead of aborting the whole sync. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -177,15 +177,16 @@ class TestWorker:
|
||||
assert seen[-1][0] == seen[-1][1] == 2 * device_sync.CHUNK // 1024
|
||||
assert "1/1" in seen[-1][2]
|
||||
|
||||
def test_source_vanishing_reports_failure(self, qapp, tmp_path):
|
||||
def test_device_side_error_reports_failure(self, qapp, tmp_path):
|
||||
# A file squatting on the dest-dir path stands in for a device-side
|
||||
# write error (unplug mid-sync). Vanished *sources* are tolerated
|
||||
# (round 27); device errors still abort.
|
||||
a = _audio(tmp_path, "a.mp3")
|
||||
plan = plan_sync("Mix", [_track(1, "A", "X", a)], tmp_path / "Music")
|
||||
a.unlink() # unplugged/deleted between plan and run
|
||||
(tmp_path / "Music").mkdir()
|
||||
(tmp_path / "Music" / "Mix").write_bytes(b"not a dir")
|
||||
result = self._synced(qapp, plan)
|
||||
assert "Sync failed" in result["error"]
|
||||
# No half-copied file left behind at full-looking size.
|
||||
leftover = plan.dest_dir / "X - A.mp3"
|
||||
assert not leftover.exists() or leftover.stat().st_size != plan.copies[0].size
|
||||
|
||||
def test_empty_playlist_clears_folder(self, qapp, tmp_path):
|
||||
dest = tmp_path / "Music" / "Mix"
|
||||
|
||||
Reference in New Issue
Block a user