1package view
2
3import (
4 "net/http"
5 "strconv"
6 "strings"
7
8 "git.sr.ht/~gabrielgio/img/pkg/database/repository"
9 "git.sr.ht/~gabrielgio/img/pkg/ext"
10 "git.sr.ht/~gabrielgio/img/templates"
11)
12
13type (
14 MediaView struct {
15 mediaRepository repository.MediaRepository
16 userRepository repository.UserRepository
17 settingsRepository repository.SettingsRepository
18 }
19)
20
21func getPagination(r *http.Request) *repository.Pagination {
22 var (
23 size int
24 page int
25 albumID *uint
26 sizeStr = r.FormValue("size")
27 pageStr = r.FormValue("page")
28 albumIDStr = r.FormValue("albumId")
29 )
30
31 if sizeStr == "" {
32 size = 100
33 } else if s, err := strconv.Atoi(sizeStr); err != nil {
34 size = 100
35 } else {
36 size = s
37 }
38
39 if pageStr == "" {
40 page = 0
41 } else if p, err := strconv.Atoi(pageStr); err != nil {
42 page = 0
43 } else {
44 page = p
45 }
46
47 if albumIDStr == "" {
48 albumID = nil
49 } else if p, err := strconv.Atoi(albumIDStr); err == nil {
50 id := uint(p)
51 albumID = &id
52 }
53
54 return &repository.Pagination{
55 Page: page,
56 Size: size,
57 AlbumID: albumID,
58 }
59}
60
61func NewMediaView(
62 mediaRepository repository.MediaRepository,
63 userRepository repository.UserRepository,
64 settingsRepository repository.SettingsRepository,
65) *MediaView {
66 return &MediaView{
67 mediaRepository: mediaRepository,
68 userRepository: userRepository,
69 settingsRepository: settingsRepository,
70 }
71}
72
73func (self *MediaView) Index(w http.ResponseWriter, r *http.Request) error {
74 p := getPagination(r)
75 user := ext.GetUserFromCtx(r)
76
77 userPath, err := self.userRepository.GetPathFromUserID(r.Context(), user.ID)
78 if err != nil {
79 return err
80 }
81
82 p.Path = userPath
83 medias, err := self.mediaRepository.List(r.Context(), p)
84 if err != nil {
85 return err
86 }
87
88 settings, err := self.settingsRepository.Load(r.Context())
89 if err != nil {
90 return err
91 }
92
93 page := &templates.MediaPage{
94 Medias: medias,
95 Next: &repository.Pagination{
96 Size: p.Size,
97 Page: p.Page + 1,
98 },
99 Settings: settings,
100 }
101
102 templates.WritePageTemplate(w, page, user.IsAdmin)
103
104 return nil
105}
106
107func (self *MediaView) Detail(w http.ResponseWriter, r *http.Request) error {
108 user := ext.GetUserFromCtx(r)
109
110 userPath, err := self.userRepository.GetPathFromUserID(r.Context(), user.ID)
111 if err != nil {
112 return err
113 }
114
115 pathHash := r.FormValue("path_hash")
116
117 media, err := self.mediaRepository.Get(r.Context(), pathHash)
118 if err != nil {
119 return err
120 }
121
122 if !strings.Contains(media.Path, userPath) {
123 ext.NotFound(w)
124 return nil
125 }
126
127 settings, err := self.settingsRepository.Load(r.Context())
128 if err != nil {
129 return err
130 }
131
132 page := &templates.DetailPage{
133 Settings: settings,
134 Media: media,
135 }
136
137 templates.WritePageTemplate(w, page, user.IsAdmin)
138
139 return nil
140}
141
142func (self *MediaView) GetImage(w http.ResponseWriter, r *http.Request) error {
143 pathHash := r.FormValue("path_hash")
144
145 media, err := self.mediaRepository.Get(r.Context(), pathHash)
146 if err != nil {
147 return err
148 }
149
150 w.Header().Set("Content-Type", media.MIMEType)
151 http.ServeFile(w, r, media.Path)
152 return nil
153}
154
155func (self *MediaView) GetThumbnail(w http.ResponseWriter, r *http.Request) error {
156 pathHash := r.FormValue("path_hash")
157
158 path, err := self.mediaRepository.GetThumbnailPath(r.Context(), pathHash)
159 if err != nil {
160 http.Redirect(w, r, "/media/image?path_hash="+pathHash, http.StatusTemporaryRedirect)
161 // nolint: nilerr
162 return nil
163 }
164
165 w.Header().Set("Content-Type", "image/jpeg")
166 http.ServeFile(w, r, path)
167 return nil
168}
169
170func (self *MediaView) SetMyselfIn(r *ext.Router) {
171 r.GET("/media", self.Index)
172 r.POST("/media", self.Index)
173
174 r.GET("/detail", self.Detail)
175 r.POST("/detail", self.Detail)
176
177 r.GET("/media/image", self.GetImage)
178 r.GET("/media/thumbnail", self.GetThumbnail)
179}