mirror of
https://github.com/Dvorinka/SEEN.git
synced 2026-06-05 04:53:01 +00:00
small fix, don't worry about it
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/tdvorak/seen/backend/internal/domain"
|
||||
"github.com/tdvorak/seen/backend/internal/services/auth"
|
||||
"github.com/tdvorak/seen/backend/internal/services/download"
|
||||
"github.com/tdvorak/seen/backend/pkg/httpx"
|
||||
)
|
||||
|
||||
type DownloadHandler struct {
|
||||
service *download.Service
|
||||
authService *auth.Service
|
||||
}
|
||||
|
||||
func NewDownloadHandler(service *download.Service, authService *auth.Service) *DownloadHandler {
|
||||
return &DownloadHandler{
|
||||
service: service,
|
||||
authService: authService,
|
||||
}
|
||||
}
|
||||
|
||||
type createDownloadRequest struct {
|
||||
SourceType string `json:"sourceType"`
|
||||
Source string `json:"source"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
||||
func (h *DownloadHandler) Create(c *gin.Context) {
|
||||
user, ok := h.resolveUser(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var request createDownloadRequest
|
||||
if err := c.ShouldBindJSON(&request); err != nil {
|
||||
httpx.JSONError(c, http.StatusBadRequest, "invalid request body")
|
||||
return
|
||||
}
|
||||
|
||||
job, err := h.service.Create(c.Request.Context(), user.ID, download.CreateInput{
|
||||
SourceType: request.SourceType,
|
||||
Source: request.Source,
|
||||
Title: request.Title,
|
||||
})
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, download.ErrInvalidInput):
|
||||
httpx.JSONError(c, http.StatusBadRequest, err.Error())
|
||||
default:
|
||||
httpx.JSONError(c, http.StatusInternalServerError, "failed to create download job")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
httpx.JSON(c, http.StatusCreated, job)
|
||||
}
|
||||
|
||||
func (h *DownloadHandler) List(c *gin.Context) {
|
||||
user, ok := h.resolveUser(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
items, err := h.service.List(c.Request.Context(), user.ID, download.ListParams{
|
||||
Status: c.Query("status"),
|
||||
Limit: parseIntSafe(c.Query("limit"), 20),
|
||||
Offset: parseIntSafe(c.Query("offset"), 0),
|
||||
})
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, download.ErrInvalidInput):
|
||||
httpx.JSONError(c, http.StatusBadRequest, err.Error())
|
||||
default:
|
||||
httpx.JSONError(c, http.StatusInternalServerError, "failed to list download jobs")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
httpx.JSON(c, http.StatusOK, items)
|
||||
}
|
||||
|
||||
func (h *DownloadHandler) Cancel(c *gin.Context) {
|
||||
user, ok := h.resolveUser(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
jobID := c.Param("id")
|
||||
job, err := h.service.Cancel(c.Request.Context(), user.ID, jobID)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, download.ErrInvalidInput):
|
||||
httpx.JSONError(c, http.StatusBadRequest, err.Error())
|
||||
case errors.Is(err, download.ErrNotFound):
|
||||
httpx.JSONError(c, http.StatusNotFound, err.Error())
|
||||
default:
|
||||
httpx.JSONError(c, http.StatusInternalServerError, "failed to cancel download job")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
httpx.JSON(c, http.StatusOK, job)
|
||||
}
|
||||
|
||||
func (h *DownloadHandler) Events(c *gin.Context) {
|
||||
user, ok := h.resolveUser(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
jobID := c.Param("id")
|
||||
items, err := h.service.Events(c.Request.Context(), user.ID, jobID, download.EventParams{
|
||||
After: c.Query("after"),
|
||||
Limit: parseIntSafe(c.Query("limit"), 100),
|
||||
})
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, download.ErrInvalidInput):
|
||||
httpx.JSONError(c, http.StatusBadRequest, err.Error())
|
||||
case errors.Is(err, download.ErrNotFound):
|
||||
httpx.JSONError(c, http.StatusNotFound, err.Error())
|
||||
default:
|
||||
httpx.JSONError(c, http.StatusInternalServerError, "failed to list download events")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
httpx.JSON(c, http.StatusOK, items)
|
||||
}
|
||||
|
||||
func (h *DownloadHandler) resolveUser(c *gin.Context) (*domain.User, bool) {
|
||||
accessToken, ok := bearerToken(c.GetHeader("Authorization"))
|
||||
if !ok {
|
||||
httpx.JSONError(c, http.StatusUnauthorized, "missing bearer token")
|
||||
return nil, false
|
||||
}
|
||||
|
||||
user, err := h.authService.UserFromAccessToken(c.Request.Context(), accessToken)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, auth.ErrInvalidToken):
|
||||
httpx.JSONError(c, http.StatusUnauthorized, err.Error())
|
||||
default:
|
||||
httpx.JSONError(c, http.StatusInternalServerError, "failed to resolve user")
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return user, true
|
||||
}
|
||||
|
||||
func parseIntSafe(raw string, fallback int) int {
|
||||
if raw == "" {
|
||||
return fallback
|
||||
}
|
||||
|
||||
parsed, err := strconv.Atoi(raw)
|
||||
if err != nil {
|
||||
return fallback
|
||||
}
|
||||
|
||||
return parsed
|
||||
}
|
||||
Reference in New Issue
Block a user