diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-27 08:49:13 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-27 08:49:13 +0300 |
| commit | dee27d8f2805c9e409853462d35f9103e1a8c53e (patch) | |
| tree | 3b7f7593b7481e012801dbf44961883407833d9e /internal/processor/image.go | |
| parent | ad0cc92e16aa98ee10bead846c0ff4c74c5244d6 (diff) | |
processor: refactor to two-phase commit for inbox processing
Introduce postPlan to capture everything validated in Phase 1 before
any filesystem mutation occurs. Phase 1 scans the inbox, validates all
source files (parses text, markdown, image, audio), checks markdown
image claims for conflicts, and collects a plan per item. Phase 2
commits mutations only after every plan is validated: creates post
directories, writes assets, persists post.json, and removes sources.
If Phase 1 fails (e.g. unsupported file, missing markdown image, claim
conflict), no mutations occur and the inbox is left untouched. Roll
back the partial post directory if a mutation fails during commit.
Also refactor image and audio sub-processors into validation-only and
write-only parts (validateImage/writeImageAsset, validateAudio/copyFile)
so that Phase 1 is strictly read-only.
All existing tests pass.
Diffstat (limited to 'internal/processor/image.go')
| -rw-r--r-- | internal/processor/image.go | 33 |
1 files changed, 12 insertions, 21 deletions
diff --git a/internal/processor/image.go b/internal/processor/image.go index 9a7d769..a981e85 100644 --- a/internal/processor/image.go +++ b/internal/processor/image.go @@ -13,33 +13,24 @@ import ( ) const ( - maxImageWidth = 1024 - jpegQuality = 80 + maxImageWidth = 1024 + jpegQuality = 80 ) -// processImage reads the source image, resizes it if wider than maxImageWidth, -// encodes it as JPEG at jpegQuality, and writes the result to destDir. -// Returns the output filename (always a .jpg) and an HTML <img> snippet. -func processImage(srcPath, destDir, postID string) (filename, htmlContent string, err error) { +// validateImage reads and decodes the source image, resizing if necessary. +// It performs only read validation; the caller is responsible for writing assets. +func validateImage(srcPath string) (image.Image, error) { img, err := decodeImage(srcPath) if err != nil { - return "", "", err + return nil, err } + return resizeIfNeeded(img), nil +} - img = resizeIfNeeded(img) - - outName := "image.jpg" - outPath := filepath.Join(destDir, outName) - - if err := writeJPEG(img, outPath); err != nil { - return "", "", err - } - - // The <img> src is relative to the site root, pointing into the posts dir. - src := fmt.Sprintf("posts/%s/%s", postID, outName) - html := fmt.Sprintf(`<img src="%s" alt="" class="post-image">`, src) - - return outName, html, nil +// writeImageAsset writes the prepared image as JPEG into postDir. +func writeImageAsset(img image.Image, postDir string) error { + outPath := filepath.Join(postDir, "image.jpg") + return writeJPEG(img, outPath) } // decodeImage decodes a JPEG, PNG, or GIF (first frame) from srcPath. |
