internal/api/images.go (view raw)
1package api
2
3import (
4 "net/http"
5 "strconv"
6
7 "github.com/mjensen/weimar/internal/db"
8)
9
10func (a *API) HandleListImages(w http.ResponseWriter, r *http.Request) {
11 tags := r.URL.Query()["tags"]
12
13 page, _ := strconv.Atoi(r.URL.Query().Get("page"))
14 if page < 1 {
15 page = 1
16 }
17 perPage, _ := strconv.Atoi(r.URL.Query().Get("per_page"))
18 if perPage < 1 || perPage > 100 {
19 perPage = 20
20 }
21 offset := (page - 1) * perPage
22
23 result, err := a.DB.ListImages(r.Context(), tags, perPage, offset)
24 if err != nil {
25 writeError(w, http.StatusInternalServerError, "failed to list images")
26 return
27 }
28
29 // Load tags and uploader for each image.
30 for i := range result.Images {
31 img := &result.Images[i]
32
33 tags, err := a.DB.GetImageTags(r.Context(), img.ID)
34 if err == nil {
35 img.Tags = tags
36 }
37
38 user, err := a.DB.GetUserByID(r.Context(), img.UploadedBy)
39 if err == nil {
40 img.UploaderUsername = user.Username
41 if user.AvatarPath != nil {
42 img.AvatarURL = "/api/users/" + strconv.FormatInt(img.UploadedBy, 10) + "/avatar"
43 }
44 }
45 }
46
47 writeJSON(w, http.StatusOK, map[string]any{
48 "images": result.Images,
49 "total": result.Total,
50 "page": page,
51 "per_page": perPage,
52 })
53}
54
55func (a *API) HandleGetImage(w http.ResponseWriter, r *http.Request) {
56 idStr := r.PathValue("id")
57 id, err := strconv.ParseInt(idStr, 10, 64)
58 if err != nil {
59 writeError(w, http.StatusBadRequest, "invalid image id")
60 return
61 }
62
63 img, err := a.DB.GetImageByID(r.Context(), id)
64 if err != nil {
65 writeError(w, http.StatusNotFound, "image not found")
66 return
67 }
68
69 tagsDetail, err := a.DB.GetImageTagsWithCounts(r.Context(), id)
70 if err != nil {
71 tagsDetail = make([]db.Tag, 0)
72 }
73
74 uploaderUsername := ""
75 avatarURL := ""
76 user, err := a.DB.GetUserByID(r.Context(), img.UploadedBy)
77 if err == nil {
78 uploaderUsername = user.Username
79 if user.AvatarPath != nil {
80 avatarURL = "/api/users/" + strconv.FormatInt(img.UploadedBy, 10) + "/avatar"
81 }
82 }
83
84 writeJSON(w, http.StatusOK, map[string]any{
85 "id": img.ID,
86 "filename": img.Filename,
87 "storage_path": img.StoragePath,
88 "thumbnail_path": img.ThumbnailPath,
89 "uploaded_by": img.UploadedBy,
90 "uploader_username": uploaderUsername,
91 "avatar_url": avatarURL,
92 "file_size": img.FileSize,
93 "width": img.Width,
94 "height": img.Height,
95 "mime_type": img.MimeType,
96 "created_at": img.CreatedAt,
97 "updated_at": img.UpdatedAt,
98 "tags": img.Tags,
99 "tags_detail": tagsDetail,
100 })
101}