Files
zampler/internal/api/samples.go
T
2026-09-01 01:26:54 +01:00

156 lines
3.1 KiB
Go

package api
import (
"fmt"
"net/http"
"strconv"
"code.aneur.in/go/rest"
"code.aneur.in/go/validate"
"code.aneur.in/zampler/zampler/internal/dto"
"github.com/gorilla/mux"
)
const (
MaxLimit = 100
)
func (api *API) GetFile(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
id := vars["id"]
record, err := api.db.Select("files").Where("id = ?", id).QueryRecord()
if err != nil {
rest.WriteErrorJSON(w, err)
return
}
rest.WriteResponseJSON(w, http.StatusOK, record)
}
func (api *API) GetFileByPath(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
record, err := api.db.Select("files").Where("rel_path = ?", fmt.Sprintf("/%s", vars["path"])).QueryRecord()
if err != nil {
rest.WriteErrorJSON(w, err)
}
rest.WriteResponseJSON(w, http.StatusOK, record)
}
func (api *API) ListFiles(w http.ResponseWriter, req *http.Request) {
uq := req.URL.Query()
// Read in params
filename := ""
path := ""
direction := "asc"
sort := "path"
offset := 0
limit := MaxLimit
if uq.Has("filename") {
filename = uq.Get("filename")
} else if uq.Has("path") {
path = uq.Get("path")
}
switch uq.Get("direction") {
case "", "asc":
direction = "asc"
case "desc":
direction = "desc"
default:
rest.ErrBadRequest.WithMessage("invalid sort direction").WriteJSON(w)
return
}
switch uq.Get("sort") {
case "", "path":
sort = "path"
case "filename":
sort = "filename"
default:
rest.ErrBadRequest.WithMessage("invalid sort").WriteJSON(w)
return
}
if uq.Has("offset") {
o, err := strconv.Atoi(uq.Get("offset"))
if err != nil {
rest.ErrBadRequest.WithMessage("invalid offset").WithError(err).WriteJSON(w)
return
}
if err := validate.Min(0, false)(o); err != nil {
rest.ErrBadRequest.WithMessage("invalid offset").WithError(err).WriteJSON(w)
return
}
offset = o
}
if uq.Has("limit") {
l, err := strconv.Atoi(uq.Get("limit"))
if err != nil {
rest.ErrBadRequest.WithMessage("invalid limit").WithError(err).WriteJSON(w)
return
}
if err := validate.All(validate.Min(0, true), validate.Max(MaxLimit, false))(l); err != nil {
rest.ErrBadRequest.WithMessage("invalid limit").WithError(err).WriteJSON(w)
return
}
limit = l
}
// Apply params
query := api.db.Select("files")
switch sort {
case "filename":
query.OrderBy("filename asc")
case "path":
query.OrderBy("abs_path asc")
}
query.Offset(offset).Limit(limit)
rows, err := query.Query()
if err != nil {
rest.WriteErrorJSON(w, err)
return
}
totalCount := 0
for rows.Next() {
totalCount++
}
if err := rows.Err(); err != nil {
rest.WriteErrorJSON(w, err)
return
}
if filename != "" {
query.Where("filename like ?", filename)
} else if path != "" {
query.Where("abs_path like ?", path)
}
records, err := query.QueryRecords()
if err != nil {
rest.WriteErrorJSON(w, err)
return
}
// Output result
output := dto.NewList(records...).
WithTotalCount(totalCount).
WithParam("sort", sort).
WithDirection(direction).
WithParam("offset", offset).
WithParam("limit", limit).
MaybeWithParam("filename", filename).
MaybeWithParam("path", path)
rest.WriteResponseJSON(w, http.StatusOK, output)
}