Adopt the standard tooling from sneak/prompts: the Makefile and script/ entrypoints, lint and test stages in one Dockerfile, the canonical lint config, the CI workflow and the formatter settings. Change the module path to sneak.berlin/go/dcf. Fix the lint findings in pkg/dcf in place. DCFStore becomes Store and DCFObject becomes Object. One behaviour changes: an error listing mount points is now returned, where a typo used to drop it. Replace the placeholder test with real tests. Move the README into the required sections. make build now compiles the library; it pointed at a command that does not exist. Model: opus-5-5
4.4 KiB
dcf
Description
dcf is a WTFPL-licensed Go library by @sneak that
reads DCF memory cards from digital cameras.
DCF is the "Design rule for Camera File system". It is also JEITA specification number CP-3461. JEITA is the Japan Electronics and Information Technology Industries Association. Wikipedia describes it at Design rule for Camera File system.
The DCF specification is why your digital camera puts images and videos in
DCIM and PRIVATE/M4ROOT directories on the memory card.
dcf is incomplete and under development. It does not work yet.
Getting Started
Add the library to your Go module:
go get sneak.berlin/go/dcf
Then list the DCF stores on the mounted filesystems:
package main
import (
"fmt"
"log"
"sneak.berlin/go/dcf/pkg/dcf"
)
func main() {
stores, err := dcf.GetDCFStores(0)
if err != nil {
log.Fatal(err)
}
for _, store := range *stores {
fmt.Println(store.String())
}
}
To work on the library itself, you need docker and git:
git clone git@git.eeqj.de:sneak/dcf.git
cd dcf
script/setup
make check
Entrypoints
This repo adheres to the
Scripts to Rule Them All
standard. Each entrypoint is a POSIX sh script in script/. Use these instead
of running the underlying tools directly.
script/bootstrap(make bootstrap) installs the tools the host needs. It does not install Go or the linter.script/setup(make setup) runsscript/bootstrapand then installs the git pre-commit hook.script/test(make test) runs the tests by building theteststage of theDockerfile.script/lint(make lint) checks the Go code by building thelintstage of theDockerfile. The stage fails on Go code thatgofmtwould change.script/fmt(make fmt) rewrites the Markdown files withprettier. It does not format Go code.script/fmt-check(make fmt-check) checks the Markdown formatting and changes nothing.script/check(make check) runs the tests, then the linter, then the Markdown check.script/build(make build) compiles every package. It needs Go on the host.script/docker(make docker) builds the development image, taggeddcf.script/cibuildruns the whole CI build. The Gitea workflow runs it on every push.script/precommitis what the git pre-commit hook runs. It runsscript/check.script/install-precommit(make hooks) installs the git pre-commit hook.script/projectnameprints the project name for the other scripts.
The development image cannot be built unless the lint and test stages pass.
Run docker run --rm -it dcf for a shell inside it, with Go and make.
Rationale
I wanted to copy images off my memory cards for processing. I also like overengineering and reusable code.
Design
All the code is in the pkg/dcf package. The repo has no commands.
dcf.goholds the public API.GetDCFStoresfinds the DCF stores and lists the files on them.helpers.gofinds the mount points that hold a DCF store.
The main types are:
Storeis one DCF store on one mounted filesystem.Objectis one file in a store.ImageandVideoembedObject. The file extension decides which one a file becomes.
A mounted filesystem is a DCF store when its root holds a DCIM or M4ROOT
directory. dcf never mounts a filesystem.
TODO
- Handle DCF file groups, where multiple objects share the same index number.
dcfdoes 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.
- Look for
PRIVATE/M4ROOTrather thanM4ROOTwhen detecting a DCF store. - Return exactly the number of stores asked for.
GetDCFStoresreturns one too few when asked for two or more. - Read stores through
fs.FS, with acontext.Contextto cancel a walk. - Return a plain slice from
GetDCFStores, not a pointer to one. - Test the walk of a store and the detection of mount points. They only run against real mounted media today.
- Copy files off a card, and verify each copy against its SHA256 hash.
License
WTFPL. See LICENSE.