show-rss/src/asses/one.go

92 lines
2.0 KiB
Go

package asses
import (
"context"
"crypto/md5"
"encoding/base64"
"fmt"
"io"
"log"
"math/rand"
"os"
"path"
"show-rss/src/slow"
"time"
)
func One(ctx context.Context, p string) error {
shortp := path.Join("...", path.Base(path.Dir(p)), path.Base(p))
last, err := checkLast(ctx, p)
if err != nil {
return err
}
threshold := 20 + rand.Int()%10
if daysSince := int(time.Since(last.T).Hours()/24); daysSince > threshold {
log.Printf("asses.One(%s) // no modified check as %vd since last check", shortp, daysSince)
} else if stat, err := os.Stat(p); err != nil {
return fmt.Errorf("cannot stat %s: %w", p, err)
} else if stat.ModTime() == last.Modified {
log.Printf("asses.One(%s) // unmodified since %v", shortp, last.T)
return nil
} else {
log.Printf("asses.One(%s) // modified (%v) is now %v", shortp, last.Modified, stat.ModTime())
}
if err := func() error {
if len(last.Cksum) > 0 {
if last.Modified.IsZero() {
log.Printf("asses.One(%s) // assume cksum unchanged given null modified ", shortp)
return nil
}
cksum, err := Cksum(ctx, p)
if err != nil {
return err
}
if cksum == last.Cksum {
log.Printf("asses.One(%s) // cksum unchanged since %v", shortp, last.T)
return nil
}
}
log.Printf("asses.deport(%s)...", shortp)
if err := deport(ctx, p); err != nil {
return err
}
return nil
}(); err != nil {
return err
}
cksum, err := Cksum(ctx, p)
if err != nil {
return err
}
stat, err := os.Stat(p)
if err != nil {
return err
}
if err := checked(ctx, p, cksum, stat.ModTime()); err != nil {
log.Printf("failed to mark %s checked: %v", shortp, err)
return err
}
return nil
}
func Cksum(ctx context.Context, p string) (string, error) {
f, err := os.Open(p)
if err != nil {
return "", err
}
defer f.Close()
hasher := md5.New()
_, err = io.Copy(hasher, slow.NewReader(ctx, 10_000_000, f))
return base64.StdEncoding.EncodeToString(hasher.Sum(nil)), err
}