da78f7252c3fc064127f57d46af71465ae956687
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ece79515c0 |
fix: cost the device prefix exactly rather than approximately
Build and publish container / build (pull_request) Successful in 3m54s
The budget subtracted the prefix length plus two, on the assumption of a leading and a trailing slash. That is right for /Music and wrong for an empty prefix, where there is only one slash -- losing a character at the card root, which is exactly where the longest paths sit. Computed from the prefix as it will actually appear instead: /Music/ costs seven characters and gives a mirror-relative budget of 253, the root costs one and gives 259. Worth being exact about because the reverse error is worse. A checker comparing mirror-relative paths against the flat 260 passes everything between 253 and 260, and those are precisely the paths closest to the edge. |
||
|
|
d5f67c6de5 |
feat: shorten paths that exceed the device's limit
Build and publish container / build (pull_request) Successful in 2m16s
Rockbox's MAX_PATH is 260, defined in firmware/include/fs_defines.h and used to size the directory entry buffer in dir.h. It bounds the path as the device sees it, so the directory the mirror is copied into spends part of the same budget; --device-prefix accounts for that and defaults to /Music. Over-budget paths are shortened from the deepest component outward. The track name carries the least navigational value and the artist directory the most, so the filename is cut first and the artist only if nothing else will serve. A shortened component keeps its extension and gains four hex digits of the original name: two long titles sharing a prefix cut to the same string otherwise, and a silent collision between two tracks is a worse outcome than an ugly filename. The result is stable. The same source always yields the same shortened name, so one pass does not rename what the last one wrote -- an unstable scheme would churn the whole mirror every six hours. A path too deeply nested to fit without reducing every component to nonsense is left alone and reported rather than mangled. Migration now tries more than one previous naming, because there is more than one. A mirror already running with --fat32-safe holds sanitised but unshortened paths, and matching only the original unsanitised name would have re-encoded every one of them instead of moving it. The checker gains the same two options, since it was measuring the mirror-relative path against a limit that applies to the device-absolute one, and so under-reported by the length of the destination directory. |
||
|
|
802d91490f |
feat: a sync script that submits scrobbles, copies, and unmounts cleanly
Build and publish container / build (pull_request) Canceled after 3m8s
tools/sync-to-ipod.sh does the whole transfer to a Rockbox device, so the only manual part left is the disk-mode button sequence. The guards are the substance rather than decoration. rsync --delete is being aimed at a whole filesystem, so the destination must exist, be its own mount point, and be a FAT filesystem; the mirror must be non-empty and must not be the destination. Emptying the wrong directory is not a mistake that announces itself. It also excludes /.rockbox, the scrobbler logs and the usual filesystem metadata directories. The mirror does not contain them, so a sync to the card root would otherwise have deleted the Rockbox installation -- which the first draft of this script would have done. The unmount is why this is a script at all. FAT32 has no journal, the device is reached through the Apple firmware's disk mode because Rockbox's own mass storage is unreliable on an iFlash, and an interrupted write is corruption that needs fsck.vfat from another machine. tools/submit_scrobbles.py sends the Rockbox scrobbler log to Last.fm and sets it aside. Rockbox writes it in AUDIOSCROBBLER 1.1: tab-separated, one line per track, rated L for listened or S for skipped, and only the listened ones are a play. It runs before the copy, because the plays already happened and a failed transfer is no reason to lose them as well. Two things there differ from every other Last.fm call in these projects. Scrobbling is a write method, so it needs the API secret and a session key obtained once through the browser rather than the read-only key. And a target with no real-time clock gets /.scrobbler-timeless.log with every timestamp set to zero; those are counted and reported but never sent, since submitting them would mean inventing when they happened. Signature generation sorts parameter names by the ASCII table rather than numerically, so artist[10] precedes artist[1]. Sorting them the obvious way produces an invalid signature and no other symptom, so there is a test for it. The log is renamed rather than deleted once accepted, so that if Last.fm quietly dropped something the evidence is still on the device. |
||
|
|
3141f7ca87 |
feat: name the mirror so a FAT32 device will take it, and copy album art
Build and publish container / build (pull_request) Successful in 2m18s
Two changes for playing the mirror on a Rockbox iPod, where the device is FAT32 and Rockbox reads a plain directory tree rather than a database. --fat32-safe names mirror files acceptably: the reserved characters and control characters become underscores, trailing dots and spaces are stripped because FAT eats them silently and the name then round-trips as a different one, and a component left empty becomes an underscore. Names differing only in case are detected as collisions, since two files here are one file there and the second would silently overwrite the first. "Kick Out the Epic Motherf**ker" is a real example from a real library, and without this it simply never arrives. Off by default. It renames files, and that should be a decision rather than a surprise on somebody's next pass. Turning it on does not re-encode anything. Every track whose name held a reserved character changes path, and encoding those again would be hours of work producing files that already exist byte for byte, so the run moves them instead and logs each one. Prune then finds nothing left behind. Album art is now also copied into the mirror as cover.jpg beside the tracks. Rockbox searches the filesystem for art -- cover.jpg, folder.jpg and the rest, in the track's directory or its parent -- and that search never looks at the picture embedded in the tag, so a mirror that only embeds art displays none of it on the device. Embedding continues for the Apple firmware; both are now satisfied. A cover whose tracks have all been pruned is removed too, or its directory would never look empty and never go. Adds tools/check_fat32.py, which reports unacceptable paths before a copy rather than during one: rsync reports them too, but scattered through fifty thousand files where they are easy to lose. It exits non-zero so it can gate a script. The README documents the rsync invocation, including why --modify-window=2 is required against FAT and why Rhythmbox must be kept out of the transfer -- rb_ipod_helpers_is_ipod() reads access-protocols from media-player-info and returns true on the USB id alone, without looking at the filesystem, so removing iPod_Control changes nothing. |