aboutsummaryrefslogtreecommitdiff
path: root/pkg/worker/scanner
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/worker/scanner')
-rw-r--r--pkg/worker/scanner/album_scanner.go98
-rw-r--r--pkg/worker/scanner/exif_scanner.go2
-rw-r--r--pkg/worker/scanner/thumbnail_scanner.go2
3 files changed, 100 insertions, 2 deletions
diff --git a/pkg/worker/scanner/album_scanner.go b/pkg/worker/scanner/album_scanner.go
new file mode 100644
index 0000000..618a184
--- /dev/null
+++ b/pkg/worker/scanner/album_scanner.go
@@ -0,0 +1,98 @@
+package scanner
+
+import (
+ "context"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+
+ "git.sr.ht/~gabrielgio/img/pkg/database/repository"
+ "git.sr.ht/~gabrielgio/img/pkg/worker"
+)
+
+type (
+ AlbumScanner struct {
+ repository repository.MediaRepository
+ }
+)
+
+var _ worker.ListProcessor[*repository.Media] = &AlbumScanner{}
+
+func NewAlbumScanner(repository repository.MediaRepository) *AlbumScanner {
+ return &AlbumScanner{
+ repository: repository,
+ }
+}
+
+func (e *AlbumScanner) Query(ctx context.Context) ([]*repository.Media, error) {
+ return e.repository.ListEmptyAlbums(ctx, &repository.Pagination{
+ Page: 0,
+ Size: 100,
+ })
+}
+
+// This process will optmize for file over folder, which means it will assume that there will be
+// more file then folder in the overall library.
+// So will try to make as cheap as possible to look for fetching many files in a folder
+// meaning it will start from checking from left to right in the path since it will assume
+// that the path to that point has been registered already, resulting in a single lookup for the media
+func (e *AlbumScanner) Process(ctx context.Context, m *repository.Media) error {
+ // we don't need the name of the file, only its path
+ filePath, _ := path.Split(m.Path)
+
+ parts := strings.Split(filePath, string(os.PathSeparator))
+
+ subPaths := FanInwards(parts)
+ album, err := e.GetAndCreateNestedAlbuns(ctx, subPaths)
+ if err != nil {
+ return err
+ }
+
+ return e.repository.CreateAlbumFile(ctx, &repository.CreateAlbumFile{
+ MediaID: m.ID,
+ AlbumID: album.ID,
+ })
+}
+
+func (e *AlbumScanner) GetAndCreateNestedAlbuns(ctx context.Context, paths []string) (*repository.Album, error) {
+ if len(paths) == 1 {
+ // end of trail, we should create a album without parent
+ return e.repository.CreateAlbum(ctx, &repository.CreateAlbum{
+ ParentID: nil,
+ Name: filepath.Base(paths[0]),
+ Path: paths[0],
+ })
+ }
+
+ exists, err := e.repository.ExistsAlbumByAbsolutePath(ctx, paths[0])
+ if err != nil {
+ return nil, err
+ }
+
+ if exists {
+ return e.repository.GetAlbumByAbsolutePath(ctx, paths[0])
+ }
+
+ //album does not exist, create it and get its parent id
+ a, err := e.GetAndCreateNestedAlbuns(ctx, paths[1:])
+ if err != nil {
+ return nil, err
+ }
+
+ return e.repository.CreateAlbum(ctx, &repository.CreateAlbum{
+ ParentID: &a.ID,
+ Name: filepath.Base(paths[0]),
+ Path: paths[0],
+ })
+
+}
+
+func FanInwards(paths []string) []string {
+ result := make([]string, 0, len(paths))
+ for i := (len(paths) - 1); i >= 0; i-- {
+ subPaths := paths[0:i]
+ result = append(result, path.Join(subPaths...))
+ }
+ return result
+}
diff --git a/pkg/worker/scanner/exif_scanner.go b/pkg/worker/scanner/exif_scanner.go
index 47d717f..da63c0b 100644
--- a/pkg/worker/scanner/exif_scanner.go
+++ b/pkg/worker/scanner/exif_scanner.go
@@ -15,7 +15,7 @@ type (
}
)
-var _ worker.BatchProcessor[*repository.Media] = &EXIFScanner{}
+var _ worker.ListProcessor[*repository.Media] = &EXIFScanner{}
func NewEXIFScanner(repository repository.MediaRepository) *EXIFScanner {
return &EXIFScanner{
diff --git a/pkg/worker/scanner/thumbnail_scanner.go b/pkg/worker/scanner/thumbnail_scanner.go
index 9f75464..6446c53 100644
--- a/pkg/worker/scanner/thumbnail_scanner.go
+++ b/pkg/worker/scanner/thumbnail_scanner.go
@@ -19,7 +19,7 @@ type (
}
)
-var _ worker.BatchProcessor[*repository.Media] = &EXIFScanner{}
+var _ worker.ListProcessor[*repository.Media] = &EXIFScanner{}
func NewThumbnailScanner(cachePath string, repository repository.MediaRepository) *ThumbnailScanner {
return &ThumbnailScanner{