get cards with GetStores and GetStore, read them through fs.FS (closes #4)
GetStores replaces GetDCFStores: it takes a context, has no count argument and returns a plain slice. GetStore returns the one mounted card, or ErrNoStore or ErrMultipleStores. Each Object keeps the fs.FS its card was read through, and Hash reads through it, so tests can use fstest.MapFS. A cancelled context stops the read before the next directory. Library errors wrap with %w. Model: opus-5-5 Co-authored-by: clawbot <sneak+clawbot@sneak.cloud>
This commit was merged in pull request #13.
This commit is contained in:
1 parent
cf7611ea1b
commit
acb108a82e
8 files changed
+352
-115
No files matched your search
@@ -29,6 +29,7 @@ Then list the DCF stores on the mounted filesystems:
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
@@ -36,17 +37,21 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
stores, err := dcf.GetDCFStores(0)
|
||||
stores, err := dcf.GetStores(context.Background())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, store := range *stores {
|
||||
for _, store := range stores {
|
||||
fmt.Println(store.String())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Call `dcf.GetStore` instead when you expect exactly one DCF store. It returns
|
||||
`dcf.ErrNoStore` when none is mounted, and `dcf.ErrMultipleStores` when more
|
||||
than one is.
|
||||
|
||||
To work on the library itself, you need docker and git:
|
||||
|
||||
```sh
|
||||
@@ -105,8 +110,8 @@ 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 reads
|
||||
each one.
|
||||
- `dcf.go` holds the public API. `GetStores` finds the DCF stores and reads each
|
||||
one. `GetStore` returns the one DCF store when exactly one is mounted.
|
||||
- `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.
|
||||
- `filegroup.go` sorts the files of one DCF directory into file groups.
|
||||
@@ -117,7 +122,9 @@ The main types are:
|
||||
- `Directory` is one DCF directory. It has a directory number, a name, the
|
||||
objects inside it and their file groups.
|
||||
- `Object` is one file in a store. A file in a DCF directory also has a
|
||||
directory number and a file number.
|
||||
directory number and a file number. `Object.Hash` reads the file through the
|
||||
`fs.FS` of its store. An `Object` you build yourself has none, so its `Hash`
|
||||
returns an error.
|
||||
- `FileGroup` is one file group in a DCF directory.
|
||||
- `Image` and `Video` embed `Object`. The file extension decides which one a
|
||||
file becomes. A file with any other extension, such as a `THM` thumbnail, is
|
||||
@@ -129,6 +136,10 @@ filesystem. Media anywhere else on the filesystem is not part of the store.
|
||||
|
||||
`dcf` never follows a symlink.
|
||||
|
||||
`GetStores` and `GetStore` take a `context.Context`. When it is cancelled, the
|
||||
read stops before the next directory. The returned error matches
|
||||
`context.Canceled`.
|
||||
|
||||
`dcf` applies the naming rules of the DCF specification, CIPA DC-009-2010, under
|
||||
`DCIM`:
|
||||
|
||||
@@ -182,8 +193,6 @@ The primary member is the first of these that the group holds:
|
||||
|
||||
## TODO
|
||||
|
||||
- Take a `context.Context` to cancel the walk of a store.
|
||||
- Return a plain slice from `GetDCFStores`, not a pointer to one.
|
||||
- Copy files off a card, and verify each copy against its SHA256 hash.
|
||||
|
||||
## License
|
||||
|
||||
Reference in new issue
Block a user