diff --git a/api/devices_create.go b/api/devices_create.go new file mode 100644 index 0000000..6ee2b65 --- /dev/null +++ b/api/devices_create.go @@ -0,0 +1,15 @@ +package api + +import ( + "context" + + "github.com/tigorlazuardi/redmage/db/queries" +) + +type DeviceCreateParams = queries.DeviceCreateParams + +func (api *API) DevicesCreate(ctx context.Context, params DeviceCreateParams) (queries.Device, error) { + ctx, span := tracer.Start(ctx, "*API.DevicesCreate") + defer span.End() + return api.queries.DeviceCreate(ctx, params) +} diff --git a/db/queries/devices.sql b/db/queries/devices.sql index a04c759..9d36b0d 100644 --- a/db/queries/devices.sql +++ b/db/queries/devices.sql @@ -23,6 +23,6 @@ ORDER BY name LIMIT ? OFFSET ?; -- name: DeviceCreate :one -INSERT INTO devices (name, resolution_x, resolution_y, aspect_ratio_tolerance, min_x, min_y, max_x, max_y, nsfw, windows_wallpaper_mode) -VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) +INSERT INTO devices (name, slug, resolution_x, resolution_y, aspect_ratio_tolerance, min_x, min_y, max_x, max_y, nsfw, windows_wallpaper_mode) +VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING *; diff --git a/server/routes/api_device_create.go b/server/routes/api_device_create.go new file mode 100644 index 0000000..650686c --- /dev/null +++ b/server/routes/api_device_create.go @@ -0,0 +1,72 @@ +package routes + +import ( + "encoding/json" + "errors" + "fmt" + "net/http" + + "github.com/tigorlazuardi/redmage/api" + "github.com/tigorlazuardi/redmage/pkg/log" + "github.com/tigorlazuardi/redmage/pkg/telemetry" +) + +func (routes *Routes) APIDeviceCreate(rw http.ResponseWriter, r *http.Request) { + var err error + ctx, span := tracer.Start(r.Context(), "*Routes.APIDeviceCreate") + defer func() { telemetry.EndWithStatus(span, err) }() + + var body api.DeviceCreateParams + + if err = json.NewDecoder(r.Body).Decode(&body); err != nil { + log.New(ctx).Err(err).Error("failed to decode json body") + rw.WriteHeader(http.StatusBadRequest) + _ = json.NewEncoder(rw).Encode(map[string]string{"error": fmt.Sprintf("cannot decode json body: %s", err)}) + return + } + + if err = validateDeviceCreateParams(body); err != nil { + rw.WriteHeader(http.StatusBadRequest) + _ = json.NewEncoder(rw).Encode(map[string]string{"error": err.Error()}) + return + } + + device, err := routes.API.DevicesCreate(ctx, body) + if err != nil { + rw.WriteHeader(http.StatusInternalServerError) + _ = json.NewEncoder(rw).Encode(map[string]string{"error": err.Error()}) + return + } + + if err := json.NewEncoder(rw).Encode(device); err != nil { + log.New(ctx).Err(err).Error("failed to marshal json api devices") + } +} + +func validateDeviceCreateParams(params api.DeviceCreateParams) error { + if params.Name == "" { + return errors.New("name is required") + } + if params.Slug == "" { + return errors.New("slug is required") + } + if params.ResolutionX < 1 { + return errors.New("device width resolution is required") + } + if params.ResolutionY < 1 { + return errors.New("device height resolution is required") + } + if params.MaxX < 0 { + params.MaxX = 0 + } + if params.MaxY < 0 { + params.MaxY = 0 + } + if params.MinX < 0 { + params.MinX = 0 + } + if params.MinY < 0 { + params.MinY = 0 + } + return nil +} diff --git a/server/routes/routes.go b/server/routes/routes.go index 21864d8..0e844a5 100644 --- a/server/routes/routes.go +++ b/server/routes/routes.go @@ -36,6 +36,7 @@ func (routes *Routes) registerV1APIRoutes(router chi.Router) { router.Get("/subreddits", routes.SubredditsListAPI) router.Get("/devices", routes.APIDeviceList) + router.Post("/devices", routes.APIDeviceCreate) } func (routes *Routes) registerWWWRoutes(router chi.Router) {