StarrySkyWorld's picture
Init
8820bb8
package handlers
import (
"encoding/json"
"net/http"
"strconv"
"time"
"fastfileviewer/backend/internal/services"
"github.com/gin-gonic/gin"
)
type TaskHandler struct {
tasks *services.TaskService
}
func NewTaskHandler(tasks *services.TaskService) *TaskHandler {
return &TaskHandler{tasks: tasks}
}
func (h *TaskHandler) CreateDownload(ctx *gin.Context) {
var req struct {
URL string `json:"url"`
TargetPath string `json:"targetPath"`
}
if err := ctx.ShouldBindJSON(&req); err != nil || req.URL == "" || req.TargetPath == "" {
ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid body"})
return
}
task, err := h.tasks.CreateDownloadTask(req.URL, req.TargetPath)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
ctx.JSON(http.StatusAccepted, task)
}
func (h *TaskHandler) CreateExtract(ctx *gin.Context) {
var req struct {
SourcePath string `json:"sourcePath"`
TargetPath string `json:"targetPath"`
}
if err := ctx.ShouldBindJSON(&req); err != nil || req.SourcePath == "" || req.TargetPath == "" {
ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid body"})
return
}
task, err := h.tasks.CreateExtractTask(req.SourcePath, req.TargetPath)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
ctx.JSON(http.StatusAccepted, task)
}
func (h *TaskHandler) List(ctx *gin.Context) {
limit, _ := strconv.Atoi(ctx.DefaultQuery("limit", "50"))
tasks, err := h.tasks.ListTasks(limit)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
ctx.JSON(http.StatusOK, gin.H{"tasks": tasks})
}
func (h *TaskHandler) Get(ctx *gin.Context) {
id, err := strconv.ParseUint(ctx.Param("id"), 10, 64)
if err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
return
}
task, err := h.tasks.GetTask(uint(id))
if err != nil {
ctx.JSON(http.StatusNotFound, gin.H{"error": "task not found"})
return
}
ctx.JSON(http.StatusOK, task)
}
func (h *TaskHandler) Stream(ctx *gin.Context) {
id, err := strconv.ParseUint(ctx.Param("id"), 10, 64)
if err != nil {
ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
return
}
ch, cancel := h.tasks.Subscribe(uint(id))
defer cancel()
ctx.Header("Content-Type", "text/event-stream")
ctx.Header("Cache-Control", "no-cache")
ctx.Header("Connection", "keep-alive")
ctx.Writer.Flush()
ticker := time.NewTicker(15 * time.Second)
defer ticker.Stop()
for {
select {
case <-ctx.Request.Context().Done():
return
case ev := <-ch:
payload, _ := json.Marshal(ev)
ctx.SSEvent("task", string(payload))
ctx.Writer.Flush()
case <-ticker.C:
ctx.SSEvent("heartbeat", "ok")
ctx.Writer.Flush()
}
}
}