refactor(scanner): merge add/update into ingest, use shared utilities
- add/update consolidated into ingest(isNew) — persist branch differs, error handling and cover path fully shared (Task 24) - zipIndex/cover use bookfile.OpenReaderAt instead of hand-rolled open+stat pairs - root containment check uses bookfile.Contains (local inside removed) - cover write goes through media.WriteAtomic (now exported, log-free — callers own context); media no longer logs inside the atomic helper
This commit is contained in:
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -54,7 +53,7 @@ func (m *M) EnsureCover(ctx context.Context, bookID int64, format string, size,
|
||||
return err
|
||||
}
|
||||
dir := bookfile.CoverDir(m.cfg.CacheDir, bookfile.DirKey(bookID, bookfile.Hash(size, modTS)))
|
||||
return writeAtomic(dir, "cover"+ext, img)
|
||||
return WriteAtomic(dir, "cover"+ext, img)
|
||||
}
|
||||
|
||||
// PageIndex returns the page list for a CBZ, using redis cache when available.
|
||||
@@ -141,26 +140,26 @@ func (m *M) EnsurePage(bookID int64, size, modTS int64, root, rel string, n int,
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := writeAtomic(dir, strconv.Itoa(n)+ext, data); err != nil {
|
||||
if err := WriteAtomic(dir, strconv.Itoa(n)+ext, data); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
// writeAtomic writes data to dir/name via tmp+rename. B11: cleans tmp only on failure.
|
||||
func writeAtomic(dir, name string, data []byte) error {
|
||||
// WriteAtomic writes data to dir/name via tmp+rename. B11: cleans tmp only on
|
||||
// failure, so a crash mid-write never leaves a readable half-written file.
|
||||
// It does not log — callers own the context (which book, which page).
|
||||
func WriteAtomic(dir, name string, data []byte) error {
|
||||
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
tmp := filepath.Join(dir, fmt.Sprintf("%s.tmp-%d", name, time.Now().UnixNano()))
|
||||
if err := os.WriteFile(tmp, data, 0o644); err != nil {
|
||||
log.Printf("media: write %s: %v", name, err)
|
||||
os.Remove(tmp)
|
||||
return err
|
||||
}
|
||||
dst := filepath.Join(dir, name)
|
||||
if err := os.Rename(tmp, dst); err != nil {
|
||||
log.Printf("media: rename %s: %v", name, err)
|
||||
os.Remove(tmp)
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user