Spaces:
Sleeping
Sleeping
| 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() | |
| } | |
| } | |
| } | |