76
internal/handler/upload.go
Normal file
76
internal/handler/upload.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"ci/internal/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// UploadHandler handles file upload endpoints.
|
||||
type UploadHandler struct {
|
||||
Svc *service.ProjectService
|
||||
}
|
||||
|
||||
func NewUploadHandler(svc *service.ProjectService) *UploadHandler {
|
||||
return &UploadHandler{Svc: svc}
|
||||
}
|
||||
|
||||
// UploadFiles handles source file upload for a project (zip/tar.gz).
|
||||
func (h *UploadHandler) UploadFiles(c *gin.Context) {
|
||||
id, err := parseID(c)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid project id"})
|
||||
return
|
||||
}
|
||||
|
||||
// Verify project exists and is upload mode
|
||||
project, err := h.Svc.GetProject(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "project not found"})
|
||||
return
|
||||
}
|
||||
|
||||
file, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "no file provided"})
|
||||
return
|
||||
}
|
||||
|
||||
// Validate file extension
|
||||
ext := strings.ToLower(filepath.Ext(file.Filename))
|
||||
valid := false
|
||||
if ext == ".zip" {
|
||||
valid = true
|
||||
}
|
||||
if strings.HasSuffix(strings.ToLower(file.Filename), ".tar.gz") || strings.HasSuffix(strings.ToLower(file.Filename), ".tgz") {
|
||||
valid = true
|
||||
}
|
||||
|
||||
if !valid {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "only .zip and .tar.gz files are supported"})
|
||||
return
|
||||
}
|
||||
|
||||
// Save uploaded file to temp location
|
||||
tmpPath := filepath.Join(h.Svc.Workspace.ProjectDir(project.ID), file.Filename)
|
||||
if err := c.SaveUploadedFile(file, tmpPath); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to save file: %v", err)})
|
||||
return
|
||||
}
|
||||
|
||||
// Extract to src directory
|
||||
if err := h.Svc.Workspace.ExtractArchive(project.ID, tmpPath); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to extract: %v", err)})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "file uploaded and extracted successfully",
|
||||
"filename": file.Filename,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user