lens @ 1e4613aa1113b373a8d841c28e222599237a33c5

 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.BatchProcessor[*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}