diff options
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 89 |
1 files changed, 50 insertions, 39 deletions
@@ -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) + } } |