summaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go89
1 files changed, 50 insertions, 39 deletions
diff --git a/main.go b/main.go
index 09ff161..b57042e 100644
--- a/main.go
+++ b/main.go
@@ -64,35 +64,36 @@ func dbCollect(query string) ([]string, error) {
// cmdInit initializes a "gallery directory" that contains gallery.sqlite,
// images, thumbs.
-func cmdInit(args []string) {
+func cmdInit(args []string) error {
if len(args) != 1 {
- log.Fatalln("usage: GD")
+ return errors.New("usage: GD")
}
if err := openDB(args[0]); err != nil {
- log.Fatalln(err)
+ return err
}
if _, err := db.Exec(initializeSQL); err != nil {
- log.Fatalln(err)
+ return err
}
// XXX: There's technically no reason to keep images as symlinks,
// we might just keep absolute paths in the database as well.
if err := os.MkdirAll(filepath.Join(gd, "images"), 0755); err != nil {
- log.Fatalln(err)
+ return err
}
if err := os.MkdirAll(filepath.Join(gd, "thumbs"), 0755); err != nil {
- log.Fatalln(err)
+ return err
}
+ return nil
}
// cmdRun runs a web UI against GD on ADDRESS.
-func cmdRun(args []string) {
+func cmdRun(args []string) error {
if len(args) != 2 {
- log.Fatalln("usage: GD ADDRESS")
+ return errors.New("usage: GD ADDRESS")
}
if err := openDB(args[0]); err != nil {
- log.Fatalln(err)
+ return err
}
address := args[1]
@@ -120,7 +121,7 @@ func cmdRun(args []string) {
WriteTimeout: 60 * time.Second,
MaxHeaderBytes: 32 << 10,
}
- log.Fatalln(s.ListenAndServe())
+ return s.ListenAndServe()
}
func isImage(path string) (bool, error) {
@@ -202,46 +203,49 @@ func importFunc(path string, d fs.DirEntry, err error) error {
}
// cmdImport adds files to the "entry" table.
-func cmdImport(args []string) {
+func cmdImport(args []string) error {
if len(args) < 1 {
- log.Fatalln("usage: GD ROOT...")
+ return errors.New("usage: GD ROOT...")
}
if err := openDB(args[0]); err != nil {
- log.Fatalln(err)
+ return err
}
// TODO: This would better be done in parallel (making hashes).
// TODO: Show progress in some manner. Perhaps port my propeller code.
for _, name := range args[1:] {
if err := filepath.WalkDir(name, importFunc); err != nil {
- log.Fatalln(err)
+ return err
}
}
+ return nil
}
// cmdSync is like import, but clears the "entry" table beforehands.
-func cmdSync(args []string) {
+func cmdSync(args []string) error {
if len(args) < 1 {
- log.Fatalln("usage: GD ROOT...")
+ return errors.New("usage: GD ROOT...")
}
if err := openDB(args[0]); err != nil {
- log.Fatalln(err)
+ return err
}
// TODO
+ return nil
}
// cmdCheck checks if all files tracked in the DB are accessible.
-func cmdCheck(args []string) {
+func cmdCheck(args []string) error {
if len(args) != 1 {
- log.Fatalln("usage: GD")
+ return errors.New("usage: GD")
}
if err := openDB(args[0]); err != nil {
- log.Fatalln(err)
+ return err
}
// TODO: Check if all hashes of DB entries have a statable image file,
// and that all images with thumb{w,h} have a thumbnail file. Perhaps.
+ return nil
}
func makeThumbnail(pathImage, pathThumb string) (int, int, error) {
@@ -275,12 +279,12 @@ func makeThumbnail(pathImage, pathThumb string) (int, int, error) {
}
// cmdThumbnail generates missing thumbnails, in parallel.
-func cmdThumbnail(args []string) {
+func cmdThumbnail(args []string) error {
if len(args) < 1 {
- log.Fatalln("usage: GD [SHA1...]")
+ return errors.New("usage: GD [SHA1...]")
}
if err := openDB(args[0]); err != nil {
- log.Fatalln(err)
+ return err
}
hexSHA1 := args[1:]
@@ -291,7 +295,7 @@ func cmdThumbnail(args []string) {
LEFT OUTER JOIN image ON entry.sha1 = image.sha1
WHERE thumbw IS NULL OR thumbh IS NULL`)
if err != nil {
- log.Fatalln(err)
+ return err
}
}
@@ -302,16 +306,17 @@ func cmdThumbnail(args []string) {
pathThumb := thumbPath(sha1)
w, h, err := makeThumbnail(pathImage, pathThumb)
if err != nil {
- log.Fatalln(err)
+ return err
}
_, err = db.Exec(`INSERT INTO image(
sha1, thumbw, thumbh, dhash
) VALUES (?, ?, ?, NULL)`, sha1, w, h)
if err != nil {
- log.Fatalln(err)
+ return err
}
}
+ return nil
}
func makeDhash(hasher, pathThumb string) (uint64, error) {
@@ -337,12 +342,12 @@ func makeDhash(hasher, pathThumb string) (uint64, error) {
}
// cmdDhash generates perceptual hash from thumbnails.
-func cmdDhash(args []string) {
+func cmdDhash(args []string) error {
if len(args) < 1 {
- log.Fatalln("usage: GD HASHER [SHA1...]")
+ return errors.New("usage: GD HASHER [SHA1...]")
}
if err := openDB(args[0]); err != nil {
- log.Fatalln(err)
+ return err
}
hasher, hexSHA1 := args[1], args[2:]
@@ -350,7 +355,7 @@ func cmdDhash(args []string) {
var err error
hexSHA1, err = dbCollect(`SELECT sha1 FROM image WHERE dhash IS NULL`)
if err != nil {
- log.Fatalln(err)
+ return err
}
}
@@ -359,19 +364,20 @@ func cmdDhash(args []string) {
pathThumb := thumbPath(sha1)
hash, err := makeDhash(hasher, pathThumb)
if err != nil {
- log.Fatalln(err)
+ return err
}
_, err = db.Exec(`UPDATE image SET dhash = ? WHERE sha1 = ?`,
int64(hash), sha1)
if err != nil {
- log.Fatalln(err)
+ return err
}
}
+ return nil
}
var commands = map[string]struct {
- handler func(args []string)
+ handler func(args []string) error
}{
"init": {cmdInit},
"run": {cmdRun},
@@ -392,12 +398,17 @@ func main() {
log.Fatalln("Unknown command: " + os.Args[1])
}
- // TODO: Check if this runs on fatal errors.
- defer func() {
- if db != nil {
- db.Close()
+ err := cmd.handler(os.Args[2:])
+
+ // Note that the database object has a closing finalizer,
+ // we just additionally print any errors coming from there.
+ if db != nil {
+ if err := db.Close(); err != nil {
+ log.Println(err)
}
- }()
+ }
- cmd.handler(os.Args[2:])
+ if err != nil {
+ log.Fatalln(err)
+ }
}