1package scanner
2
3import (
4 "context"
5 "fmt"
6 "math"
7 "os"
8 "path"
9
10 "git.sr.ht/~gabrielgio/img/pkg/database/repository"
11 "git.sr.ht/~gabrielgio/img/pkg/fileop"
12 "git.sr.ht/~gabrielgio/img/pkg/worker"
13)
14
15type (
16 ThumbnailScanner struct {
17 repository repository.MediaRepository
18 cachePath string
19 }
20)
21
22var _ worker.ListProcessor[*repository.Media] = &EXIFScanner{}
23
24func NewThumbnailScanner(cachePath string, repository repository.MediaRepository) *ThumbnailScanner {
25 return &ThumbnailScanner{
26 repository: repository,
27 cachePath: cachePath,
28 }
29}
30
31func (t *ThumbnailScanner) Query(ctx context.Context) ([]*repository.Media, error) {
32 return t.repository.ListEmptyThumbnail(ctx, &repository.Pagination{
33 Page: 0,
34 Size: 100,
35 })
36}
37
38func (t *ThumbnailScanner) OnFail(ctx context.Context, media *repository.Media, _ error) {
39 _ = t.repository.CreateThumbnail(ctx, media.ID, &repository.MediaThumbnail{
40 Path: "",
41 })
42}
43
44func (t *ThumbnailScanner) Process(ctx context.Context, media *repository.Media) error {
45 split := media.PathHash[:2]
46 filename := media.PathHash[2:]
47 folder := path.Join(t.cachePath, split)
48 output := path.Join(folder, filename+".jpeg")
49
50 err := os.MkdirAll(folder, os.ModePerm)
51 if err != nil {
52 return err
53 }
54
55 if media.IsVideo() {
56 err := fileop.EncodeVideoThumbnail(media.Path, output, 1080, 1080)
57 if err != nil {
58 return fmt.Errorf("Error thumbnail video %d; %w", media.ID, err)
59 }
60 } else {
61 err := fileop.EncodeImageThumbnail(media.Path, output, 1080, math.MinInt32)
62 if err != nil {
63 return fmt.Errorf("Error thumbnail image %d; %w", media.ID, err)
64 }
65 }
66
67 return t.repository.CreateThumbnail(ctx, media.ID, &repository.MediaThumbnail{
68 Path: output,
69 })
70}