parse the DCF structure under DCIM (closes #2)
A card is now read by the naming rules in CIPA DC-009-2010, not by looking for media extensions anywhere on the volume. Store.Directories holds the DCF directories and their objects, with directory and file numbers. Store.NonConforming lists everything else under DCIM, including symlinks and names fs.FS refuses. Media under PRIVATE/M4ROOT stays, with no DCF numbers. Media anywhere else is no longer part of the store. A symlink is never followed, and a read error names the card's mount point. Model: opus-5-5
This commit is contained in:
1 parent
445424ba3e
commit
25c6aca864
7 files changed
+1243
-57
No files matched your search
@@ -105,30 +105,57 @@ overengineering and reusable code.
|
||||
|
||||
All the code is in the `pkg/dcf` package. The repo has no commands.
|
||||
|
||||
- `dcf.go` holds the public API. `GetDCFStores` finds the DCF stores and lists
|
||||
the files on them.
|
||||
- `dcf.go` holds the public API. `GetDCFStores` finds the DCF stores and reads
|
||||
each one.
|
||||
- `helpers.go` finds the mount points that hold a DCF store.
|
||||
- `parse.go` reads one DCF store through an `fs.FS` rooted at its mount point.
|
||||
|
||||
The main types are:
|
||||
|
||||
- `Store` is one DCF store on one mounted filesystem.
|
||||
- `Object` is one file in a store.
|
||||
- `Directory` is one DCF directory. It has a directory number, a name and the
|
||||
objects inside it.
|
||||
- `Object` is one file in a store. A file in a DCF directory also has a
|
||||
directory number and a file number.
|
||||
- `Image` and `Video` embed `Object`. The file extension decides which one a
|
||||
file becomes.
|
||||
file becomes. A file with any other extension, such as a `THM` thumbnail, is
|
||||
neither.
|
||||
|
||||
A mounted filesystem is a DCF store when its root holds a `DCIM` or
|
||||
`PRIVATE/M4ROOT` directory. `dcf` never mounts a filesystem.
|
||||
`PRIVATE/M4ROOT` directory. It needs only one of them. `dcf` never mounts a
|
||||
filesystem. Media anywhere else on the filesystem is not part of the store.
|
||||
|
||||
`dcf` never follows a symlink.
|
||||
|
||||
`dcf` applies the naming rules of the DCF specification, CIPA DC-009-2010, under
|
||||
`DCIM`:
|
||||
|
||||
- A DCF directory sits directly under `DCIM`. Its name is a directory number
|
||||
from 100 to 999, then five characters, such as `100MSDCF`.
|
||||
- A DCF file sits directly in a DCF directory. Its name is four characters, then
|
||||
a file number from 0001 to 9999, then a dot and a three-character extension,
|
||||
such as `DSC00001.ARW`.
|
||||
- The characters allowed are `A` to `Z`, `0` to `9` and `_`. Lower-case letters
|
||||
count as upper-case.
|
||||
- Directories that share a directory number are not DCF directories.
|
||||
- `JPG` files that share a file number in one directory are not DCF files.
|
||||
|
||||
`Store.NonConforming` lists the path of everything else under `DCIM`. It
|
||||
includes everything inside a directory that breaks the rules. It also includes
|
||||
every symlink, whatever its name. These entries have no DCF numbers, and they
|
||||
are not counted as images or videos.
|
||||
|
||||
The naming rules do not apply under `PRIVATE/M4ROOT`. The images and videos
|
||||
there are in `Store.Images` and `Store.Videos`, and their DCF numbers are 0.
|
||||
`dcf` skips any symlink there.
|
||||
|
||||
## TODO
|
||||
|
||||
- Handle DCF file groups, where multiple objects share the same index number.
|
||||
`dcf` does not handle these yet. If you need this, send me a link to a zip or
|
||||
tar of a memory card that uses them, and I'll see what I can do.
|
||||
- Parse the DCF directory and file names, rather than listing every media file
|
||||
on the filesystem.
|
||||
- Read stores through `fs.FS`, with a `context.Context` to cancel a walk.
|
||||
- Take a `context.Context` to cancel the walk of a store.
|
||||
- Return a plain slice from `GetDCFStores`, not a pointer to one.
|
||||
- Test the walk of a store. It only runs against real mounted media today.
|
||||
- Copy files off a card, and verify each copy against its SHA256 hash.
|
||||
|
||||
## License
|
||||
|
||||
Reference in new issue
Block a user