diff options
author | Přemysl Eric Janouch <p@janouch.name> | 2023-12-21 06:19:03 +0100 |
---|---|---|
committer | Přemysl Eric Janouch <p@janouch.name> | 2023-12-21 06:19:03 +0100 |
commit | 068f6f82cfee723e6c6213ea58d05c9e9708e131 (patch) | |
tree | 9c49bde1a866299e6a54e83d28ee65771752e18f /main.go | |
parent | 2011f2b198871b6acb4bbc50012b8bd6801b6a7f (diff) | |
download | gallery-068f6f82cfee723e6c6213ea58d05c9e9708e131.tar.gz gallery-068f6f82cfee723e6c6213ea58d05c9e9708e131.tar.xz gallery-068f6f82cfee723e6c6213ea58d05c9e9708e131.zip |
WIP: FS to DB sync
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 62 |
1 files changed, 47 insertions, 15 deletions
@@ -831,6 +831,11 @@ type syncFile struct { fsIsDir bool } +type syncPair struct { + db *syncNode + fs *syncFile +} + // syncGetNodes returns direct children of a DB node, ordered by name. // SQLite, like Go, compares strings byte-wise by default. func syncGetNodes(tx *sql.Tx, dbParent int64) (nodes []syncNode, err error) { @@ -885,9 +890,38 @@ func syncGetFiles(fsPath string) (files []syncFile, err error) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -type syncPair struct { - db *syncNode - fs *syncFile +func syncProcess(c *syncContext, info *syncFileInfo) error { + // Skip videos, which ImageMagick can process, but we don't want it to, + // so that they're not converted 1:1 to WebP. + pathIsImage, err := isImage(info.fsPath) + if err != nil { + return err + } + if !pathIsImage { + return nil + } + + info.width, info.height, err = pingImage(info.fsPath) + if err != nil { + return err + } + + f, err := os.Open(info.fsPath) + if err != nil { + return err + } + defer f.Close() + + // We could make this at least somewhat interruptible by c.ctx, + // though it would still work poorly. + hash := sha1.New() + _, err = io.CopyBuffer(hash, f, make([]byte, 65536)) + if err != nil { + return err + } + + info.sha1 = hex.EncodeToString(hash.Sum(nil)) + return nil } // syncEnqueue runs file scanning, which can be CPU and I/O expensive, @@ -899,8 +933,8 @@ func syncEnqueue(c *syncContext, info syncFileInfo) error { go func(info syncFileInfo) { defer taskSemaphore.release() - - // TODO: Process the file and enqueue a result. + info.err = syncProcess(c, &info) + c.info <- info }(info) return nil } @@ -921,22 +955,20 @@ func syncDequeue(c *syncContext) error { } } -// TODO: Implement. -// -// - When collecting node subtrees, we need to delete bottom-up -// because of foreign key constraints, -// so maybe in reverse order of recursive CTE results. -// -// - Sadly, this can't be done with a DB trigger. (What and why?) -// -// - One of the inputs needs to be the FS path, for the orphan table. -// // syncDispose creates orphan records for the entire subtree given by nodeID // as appropriate, then deletes all nodes within the subtree. The subtree root // node is not deleted if "keepNode" is true. // // Orphans keep their thumbnail files, as evidence. func syncDispose(c *syncContext, nodeID int64, keepNode bool) error { + // TODO: Implement. + // - When collecting node subtrees, we need to delete bottom-up + // because of foreign key constraints, + // so maybe in reverse order of recursive CTE results. + // - Sadly, this can't be done with a DB trigger. (What and why?) + // - One of the inputs needs to be the FS path, for the orphan table. + // - I may not have the FS path (symlink). + // - I can just recursively select for the path based on nodeID. return nil } |