summaryrefslogtreecommitdiff
path: root/internal/processor/image.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-27 08:49:13 +0300
committerPaul Buetow <paul@buetow.org>2026-04-27 08:49:13 +0300
commitdee27d8f2805c9e409853462d35f9103e1a8c53e (patch)
tree3b7f7593b7481e012801dbf44961883407833d9e /internal/processor/image.go
parentad0cc92e16aa98ee10bead846c0ff4c74c5244d6 (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.go33
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.