aboutsummaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorGabriel Arakaki Giovanini <mail@gabrielgio.me>2023-08-13 21:36:42 +0200
committerGabriel Arakaki Giovanini <mail@gabrielgio.me>2023-08-13 21:36:42 +0200
commitc51fb8cc8b850b4915e083d0dd2c30d79f8b632e (patch)
tree527ba9e4f897bc2faf997ff648aeb85cc9c247eb /pkg
parentf99f2bc94808d784c92ec4e58c660a8be3ed7fce (diff)
downloadlens-c51fb8cc8b850b4915e083d0dd2c30d79f8b632e.tar.gz
lens-c51fb8cc8b850b4915e083d0dd2c30d79f8b632e.tar.bz2
lens-c51fb8cc8b850b4915e083d0dd2c30d79f8b632e.zip
feat: Add (yet again) crude album implementation
This is a initial UI album implementation. This should cover the most basic album navigation. This is still plenty to do :)
Diffstat (limited to 'pkg')
-rw-r--r--pkg/database/repository/media.go13
-rw-r--r--pkg/database/sql/media.go46
-rw-r--r--pkg/view/album.go102
-rw-r--r--pkg/view/media.go26
-rw-r--r--pkg/worker/scanner/album_scanner.go1
5 files changed, 171 insertions, 17 deletions
diff --git a/pkg/database/repository/media.go b/pkg/database/repository/media.go
index d6addbf..9915c90 100644
--- a/pkg/database/repository/media.go
+++ b/pkg/database/repository/media.go
@@ -35,7 +35,9 @@ type (
}
Album struct {
- ID uint
+ ID uint
+ Name string
+ Path string
}
MediaThumbnail struct {
@@ -43,9 +45,10 @@ type (
}
Pagination struct {
- Page int
- Size int
- Path string
+ Page int
+ Size int
+ AlbumID *uint
+ Path string
}
CreateMedia struct {
@@ -83,8 +86,10 @@ type (
CreateThumbnail(context.Context, uint, *MediaThumbnail) error
ListEmptyAlbums(context.Context, *Pagination) ([]*Media, error)
+ ListAlbums(context.Context, uint) ([]*Album, error)
ExistsAlbumByAbsolutePath(context.Context, string) (bool, error)
GetAlbumByAbsolutePath(context.Context, string) (*Album, error)
+ GetAlbum(context.Context, uint) (*Album, error)
CreateAlbum(context.Context, *CreateAlbum) (*Album, error)
CreateAlbumFile(context.Context, *CreateAlbumFile) error
}
diff --git a/pkg/database/sql/media.go b/pkg/database/sql/media.go
index 59e39ee..4b48608 100644
--- a/pkg/database/sql/media.go
+++ b/pkg/database/sql/media.go
@@ -23,7 +23,7 @@ type (
gorm.Model
Width *float64
Height *float64
- MediaID uint
+ MediaID uint `gorm:"not null"`
Media Media
Description *string
Camera *string
@@ -43,8 +43,8 @@ type (
MediaThumbnail struct {
gorm.Model
- Path string
- MediaID uint
+ Path string `gorm:"not null;unique"`
+ MediaID uint `gorm:"not null"`
Media Media
}
@@ -53,7 +53,7 @@ type (
ParentID *uint
Parent *MediaAlbum
Name string
- Path string
+ Path string `gorm:"not null; unique"`
}
MediaAlbumFile struct {
@@ -104,7 +104,9 @@ func (m *MediaEXIF) ToModel() *repository.MediaEXIF {
func (a *MediaAlbum) ToModel() *repository.Album {
return &repository.Album{
- ID: a.ID,
+ ID: a.ID,
+ Name: a.Name,
+ Path: a.Path,
}
}
@@ -407,6 +409,22 @@ func (r *MediaRepository) GetAlbumByAbsolutePath(ctx context.Context, path strin
return m.ToModel(), nil
}
+func (r *MediaRepository) GetAlbum(ctx context.Context, albumID uint) (*repository.Album, error) {
+ m := &MediaAlbum{}
+ result := r.db.
+ WithContext(ctx).
+ Model(&MediaAlbum{}).
+ Where("id = ?", albumID).
+ Limit(1).
+ Take(m)
+
+ if result.Error != nil {
+ return nil, result.Error
+ }
+
+ return m.ToModel(), nil
+}
+
func (m *MediaRepository) CreateAlbum(ctx context.Context, createAlbum *repository.CreateAlbum) (*repository.Album, error) {
album := &MediaAlbum{
ParentID: createAlbum.ParentID,
@@ -439,3 +457,21 @@ func (m *MediaRepository) CreateAlbumFile(ctx context.Context, createAlbumFile *
return nil
}
+
+func (m *MediaRepository) ListAlbums(ctx context.Context, albumID uint) ([]*repository.Album, error) {
+ albums := make([]*MediaAlbum, 0)
+
+ result := m.db.
+ WithContext(ctx).
+ Model(&MediaAlbum{}).
+ Where("parent_id = ?", albumID).
+ Find(&albums)
+
+ if result.Error != nil {
+ return nil, result.Error
+ }
+
+ return list.Map(albums, func(a *MediaAlbum) *repository.Album {
+ return a.ToModel()
+ }), nil
+}
diff --git a/pkg/view/album.go b/pkg/view/album.go
new file mode 100644
index 0000000..a96b9bd
--- /dev/null
+++ b/pkg/view/album.go
@@ -0,0 +1,102 @@
+package view
+
+import (
+ "net/http"
+
+ "git.sr.ht/~gabrielgio/img/pkg/database/repository"
+ "git.sr.ht/~gabrielgio/img/pkg/ext"
+ "git.sr.ht/~gabrielgio/img/templates"
+)
+
+type (
+ AlbumView struct {
+ mediaRepository repository.MediaRepository
+ userRepository repository.UserRepository
+ settingsRepository repository.SettingsRepository
+ }
+)
+
+func NewAlbumView(
+ mediaRepository repository.MediaRepository,
+ userRepository repository.UserRepository,
+ settingsRepository repository.SettingsRepository,
+) *AlbumView {
+ return &AlbumView{
+ mediaRepository: mediaRepository,
+ userRepository: userRepository,
+ settingsRepository: settingsRepository,
+ }
+}
+
+func (self *AlbumView) Index(w http.ResponseWriter, r *http.Request) error {
+ p := getPagination(r)
+ token := ext.GetTokenFromCtx(w, r)
+
+ // TODO: optmize call, GetPathFromUserID may no be necessary
+ userPath, err := self.userRepository.GetPathFromUserID(r.Context(), token.UserID)
+ if err != nil {
+ return err
+ }
+
+ var albums []*repository.Album
+ var album *repository.Album
+
+ if p.AlbumID == nil {
+ // use user path as default value
+ p.Path = userPath
+
+ album, err = self.mediaRepository.GetAlbumByAbsolutePath(r.Context(), p.Path)
+ if err != nil {
+ return err
+ }
+
+ albums, err = self.mediaRepository.ListAlbums(r.Context(), album.ID)
+ if err != nil {
+ return err
+ }
+ } else {
+ album, err = self.mediaRepository.GetAlbum(r.Context(), *p.AlbumID)
+ if err != nil {
+ return err
+ }
+
+ // TODO: User can enter a album out of its bounderies
+ p.Path = album.Path
+
+ albums, err = self.mediaRepository.ListAlbums(r.Context(), *p.AlbumID)
+ if err != nil {
+ return err
+ }
+
+ }
+
+ medias, err := self.mediaRepository.List(r.Context(), p)
+ if err != nil {
+ return err
+ }
+
+ settings, err := self.settingsRepository.Load(r.Context())
+ if err != nil {
+ return err
+ }
+
+ page := &templates.AlbumPage{
+ Medias: medias,
+ Albums: albums,
+ Name: album.Name,
+ Next: &repository.Pagination{
+ Size: p.Size,
+ Page: p.Page + 1,
+ },
+ Settings: settings,
+ }
+
+ templates.WritePageTemplate(w, page)
+
+ return nil
+}
+
+func (self *AlbumView) SetMyselfIn(r *ext.Router) {
+ r.GET("/album/", self.Index)
+ r.POST("/album/", self.Index)
+}
diff --git a/pkg/view/media.go b/pkg/view/media.go
index c7d84ec..3124119 100644
--- a/pkg/view/media.go
+++ b/pkg/view/media.go
@@ -17,12 +17,14 @@ type (
}
)
-func getPagination(w http.ResponseWriter, r *http.Request) *repository.Pagination {
+func getPagination(r *http.Request) *repository.Pagination {
var (
- size int
- page int
- sizeStr = r.FormValue("size")
- pageStr = r.FormValue("page")
+ size int
+ page int
+ albumID *uint
+ sizeStr = r.FormValue("size")
+ pageStr = r.FormValue("page")
+ albumIDStr = r.FormValue("albumId")
)
if sizeStr == "" {
@@ -41,9 +43,17 @@ func getPagination(w http.ResponseWriter, r *http.Request) *repository.Paginatio
page = p
}
+ if albumIDStr == "" {
+ page = 0
+ } else if p, err := strconv.Atoi(albumIDStr); err == nil {
+ id := uint(p)
+ albumID = &id
+ }
+
return &repository.Pagination{
- Page: page,
- Size: size,
+ Page: page,
+ Size: size,
+ AlbumID: albumID,
}
}
@@ -60,7 +70,7 @@ func NewMediaView(
}
func (self *MediaView) Index(w http.ResponseWriter, r *http.Request) error {
- p := getPagination(w, r)
+ p := getPagination(r)
token := ext.GetTokenFromCtx(w, r)
userPath, err := self.userRepository.GetPathFromUserID(r.Context(), token.UserID)
diff --git a/pkg/worker/scanner/album_scanner.go b/pkg/worker/scanner/album_scanner.go
index 618a184..04af9bc 100644
--- a/pkg/worker/scanner/album_scanner.go
+++ b/pkg/worker/scanner/album_scanner.go
@@ -92,6 +92,7 @@ func FanInwards(paths []string) []string {
result := make([]string, 0, len(paths))
for i := (len(paths) - 1); i >= 0; i-- {
subPaths := paths[0:i]
+ subPaths = append([]string{"/"}, subPaths...)
result = append(result, path.Join(subPaths...))
}
return result