mirror of
https://github.com/photoprism/photoprism.git
synced 2026-07-18 00:59:38 +00:00
Mirror the lens make/model editing surface for cameras: entity UpdateMakeModel/SaveForm, form validation, query, search, the GET/PUT /api/v1/cameras endpoints, and the cameras CLI command, plus a cameras ACL resource and scope. Also tidy the lens surface for parity: self-validating SaveForm, empty make/model guard, X-Count search header, service-role grant, the empty-id/slug docs, and order cameras before lenses everywhere.
81 lines
2 KiB
Go
81 lines
2 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"github.com/photoprism/photoprism/internal/auth/acl"
|
|
"github.com/photoprism/photoprism/internal/entity/query"
|
|
"github.com/photoprism/photoprism/internal/form"
|
|
"github.com/photoprism/photoprism/pkg/clean"
|
|
"github.com/photoprism/photoprism/pkg/i18n"
|
|
)
|
|
|
|
// UpdateCamera updates camera make and model properties.
|
|
//
|
|
// PUT /api/v1/cameras/:id
|
|
//
|
|
// @Summary updates camera name
|
|
// @Id UpdateCamera
|
|
// @Tags Cameras
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Success 200 {object} entity.Camera
|
|
// @Failure 401,403,404,429 {object} i18n.Response
|
|
// @Param id path string true "Camera ID"
|
|
// @Param camera body form.Camera true "Properties to be updated, only Make and Model supported"
|
|
// @Router /api/v1/cameras/{id} [put]
|
|
func UpdateCamera(router *gin.RouterGroup) {
|
|
router.PUT("/cameras/:id", func(c *gin.Context) {
|
|
s := Auth(c, acl.ResourceCameras, acl.ActionUpdate)
|
|
|
|
if s.Abort(c) {
|
|
return
|
|
}
|
|
|
|
// Find camera by ID. A non-numeric id parses to 0 and is rejected as not found below,
|
|
// so the parse error is intentionally ignored.
|
|
cameraId, _ := strconv.ParseUint(clean.Token(c.Param("id")), 10, 32)
|
|
m := query.FindCameraByID(uint(cameraId))
|
|
|
|
if m == nil {
|
|
Abort(c, http.StatusNotFound, i18n.ErrCameraNotFound)
|
|
return
|
|
}
|
|
|
|
// Create new camera form.
|
|
frm, frmErr := form.NewCamera(m)
|
|
|
|
if frmErr != nil {
|
|
Abort(c, http.StatusBadRequest, i18n.ErrBadRequest)
|
|
return
|
|
}
|
|
|
|
// Set form values from request.
|
|
LimitRequestBodyBytes(c, MaxMutationRequestBytes)
|
|
|
|
if frmErr = c.BindJSON(frm); frmErr != nil {
|
|
if IsRequestBodyTooLarge(frmErr) {
|
|
AbortRequestTooLarge(c, i18n.ErrBadRequest)
|
|
return
|
|
}
|
|
|
|
AbortBadRequest(c, frmErr)
|
|
return
|
|
} else if frmErr = frm.Validate(); frmErr != nil {
|
|
AbortInvalidName(c)
|
|
return
|
|
}
|
|
|
|
// Save camera and return new model values if successful.
|
|
if err := m.SaveForm(frm); err != nil {
|
|
log.Errorf("camera: %s", clean.Error(err))
|
|
AbortSaveFailed(c)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, m)
|
|
})
|
|
}
|