초기화
This commit is contained in:
@@ -1,140 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/savethenurse/ai-media-hub/backend/models"
|
||||
"github.com/savethenurse/ai-media-hub/backend/services"
|
||||
)
|
||||
|
||||
// SearchAndFilter handles Zone A logic
|
||||
func SearchAndFilter(c *fiber.Ctx) error {
|
||||
query := c.Query("q")
|
||||
if query == "" {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Query required"})
|
||||
}
|
||||
|
||||
// 1. Send search query to CSE
|
||||
urls, err := services.PerformSearch(query)
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
if len(urls) == 0 {
|
||||
return c.JSON(fiber.Map{"recommended": []string{}})
|
||||
}
|
||||
|
||||
// 2. Filter with Gemini
|
||||
result, err := services.FilterImagesWithGemini(query, urls)
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
return c.JSON(result)
|
||||
}
|
||||
|
||||
// UploadMedia handles Zone B logic
|
||||
func UploadMedia(c *fiber.Ctx) error {
|
||||
file, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "File upload required"})
|
||||
}
|
||||
|
||||
downloadsDir := os.Getenv("DOWNLOADS_DIR")
|
||||
if downloadsDir == "" {
|
||||
downloadsDir = "/app/downloads"
|
||||
}
|
||||
|
||||
dest := filepath.Join(downloadsDir, file.Filename)
|
||||
if err := c.SaveFile(file, dest); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
|
||||
// Logging to DB
|
||||
models.DB.Create(&models.MediaHistory{
|
||||
SourceURL: file.Filename, // Just to log it, though not a URL
|
||||
FilePath: dest,
|
||||
Status: "success",
|
||||
Type: "upload",
|
||||
})
|
||||
|
||||
return c.JSON(fiber.Map{"status": "success", "filename": file.Filename})
|
||||
}
|
||||
|
||||
// DownloadMedia handles Zone C logic
|
||||
func DownloadMedia(c *fiber.Ctx) error {
|
||||
type Request struct {
|
||||
URL string `json:"url"`
|
||||
Start string `json:"start"`
|
||||
End string `json:"end"`
|
||||
}
|
||||
|
||||
var req Request
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid JSON"})
|
||||
}
|
||||
|
||||
// Check duplicates
|
||||
var hist models.MediaHistory
|
||||
res := models.DB.Where("source_url = ?", req.URL).First(&hist)
|
||||
if res.RowsAffected > 0 && c.Query("confirm") != "true" {
|
||||
return c.Status(statusConflict).JSON(fiber.Map{"error": "Duplicate", "need_confirm": true})
|
||||
}
|
||||
|
||||
downloadsDir := os.Getenv("DOWNLOADS_DIR")
|
||||
if downloadsDir == "" {
|
||||
downloadsDir = "/app/downloads"
|
||||
}
|
||||
|
||||
// Execute Python worker asynchronously or synchronously
|
||||
// For simplicity, we'll do it synchronously and broadcast progress via WS if we capture it.
|
||||
// But it's easier to just run the command and wait.
|
||||
BroadcastProgress("Downloading: " + req.URL)
|
||||
|
||||
go func() {
|
||||
args := []string{"./worker/downloader.py", "--url", req.URL, "--outdir", downloadsDir}
|
||||
if req.Start != "" {
|
||||
args = append(args, "--start", req.Start)
|
||||
}
|
||||
if req.End != "" {
|
||||
args = append(args, "--end", req.End)
|
||||
}
|
||||
|
||||
cmd := exec.Command("python", args...)
|
||||
fmt.Printf("[DEBUG Go Exec] Command: %v\n", cmd.String())
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
fmt.Printf("[DEBUG Go Exec] Output:\n%s\n", string(output))
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("[DEBUG Go Exec] Download error: %v\n", string(output))
|
||||
BroadcastProgress("Error: " + err.Error())
|
||||
models.DB.Create(&models.MediaHistory{
|
||||
SourceURL: req.URL,
|
||||
Status: "error",
|
||||
Type: "download",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var result map[string]interface{}
|
||||
json.Unmarshal(output, &result)
|
||||
|
||||
BroadcastProgress(fmt.Sprintf("Download Success: %v", req.URL))
|
||||
models.DB.Create(&models.MediaHistory{
|
||||
SourceURL: req.URL,
|
||||
Status: "success",
|
||||
Type: "download",
|
||||
FilePath: fmt.Sprintf("%v", result["filepath"]),
|
||||
})
|
||||
}()
|
||||
|
||||
return c.JSON(fiber.Map{"status": "started", "message": "Download process started"})
|
||||
}
|
||||
|
||||
const statusConflict = 409
|
||||
@@ -1,47 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"log"
|
||||
"sync"
|
||||
|
||||
"github.com/gofiber/websocket/v2"
|
||||
)
|
||||
|
||||
var clients = make(map[*websocket.Conn]bool)
|
||||
var clientsMutex sync.Mutex
|
||||
|
||||
func WsHandler(c *websocket.Conn) {
|
||||
clientsMutex.Lock()
|
||||
clients[c] = true
|
||||
clientsMutex.Unlock()
|
||||
|
||||
defer func() {
|
||||
clientsMutex.Lock()
|
||||
delete(clients, c)
|
||||
clientsMutex.Unlock()
|
||||
c.Close()
|
||||
}()
|
||||
|
||||
for {
|
||||
// Just keep alive, ignore incoming messages
|
||||
_, _, err := c.ReadMessage()
|
||||
if err != nil {
|
||||
log.Println("ws error:", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BroadcastProgress(message string) {
|
||||
clientsMutex.Lock()
|
||||
defer clientsMutex.Unlock()
|
||||
|
||||
for client := range clients {
|
||||
err := client.WriteMessage(websocket.TextMessage, []byte(message))
|
||||
if err != nil {
|
||||
log.Println("ws broadcast error:", err)
|
||||
client.Close()
|
||||
delete(clients, client)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user