diff --git a/renders/renders.go b/renders/renders.go index 00dcfab..e0924cb 100644 --- a/renders/renders.go +++ b/renders/renders.go @@ -710,31 +710,30 @@ var seriesRegex = regexp.MustCompile(`^(.+?)\.S\d{2}E\d{2}`) // HandleAddJobsMultiple gère le débridage de plusieurs liens, auto-création de sous-dossier, et enregistrement func HandleAddJobsMultiple(db *gorm.DB) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - // 1) Parse form data if err := r.ParseForm(); err != nil { http.Error(w, "Requête invalide", http.StatusBadRequest) return } - link := r.FormValue("link") + // Récupère les liens + raw := r.FormValue("links") + lines := strings.Split(raw, "\n") + + // Récupère le dossier principal idStr := r.FormValue("path_id") - parsedID, err := strconv.Atoi(idStr) + baseID, err := strconv.ParseInt(idStr, 10, 64) if err != nil { - http.Error(w, "Chemin invalide", http.StatusBadRequest) + http.Error(w, "ID de chemin invalide", http.StatusBadRequest) return } - - log.Printf("[HTTP] Lien reçu : %s", link) - log.Printf("[HTTP] ID de chemin : %d", parsedID) - - // 2) Fetch the base PathDownload var basePath models.PathDownload - if err := db.First(&basePath, parsedID).Error; err != nil { + if err := db.First(&basePath, baseID).Error; err != nil { http.Error(w, "Dossier principal introuvable", http.StatusBadRequest) return } - ctx := r.Context() + // Prépare client DebridLink + ctx := context.Background() client := debridlink.NewClient(db) account := download.GetFirstActiveAccount(client) if account == nil { @@ -743,60 +742,71 @@ func HandleAddJobsMultiple(db *gorm.DB) http.HandlerFunc { } client.SetAccount(account) - // 3) Debrid and retrieve real links - links, err := client.AddLink(ctx, link) - if err != nil { - log.Printf("[ERROR] Echec lors de l'ajout du lien : %v", err) - http.Error(w, "Erreur côté Debrid-Link", http.StatusInternalServerError) - return - } - - // 4) For each returned link, create subfolder, register job, start download - for _, l := range links { - // Derive subfolder name from filename (e.g.: SeriesName...) - fileName := filepath.Base(l.Name) - re := regexp.MustCompile(`^(?P[A-Za-z0-9\.]+)`) - matches := re.FindStringSubmatch(fileName) - series := fileName - if len(matches) > 1 { - series = matches[1] - } - - // Create filesystem subfolder - dirPath := filepath.Join(basePath.Path, series) - if err := os.MkdirAll(dirPath, os.ModePerm); err != nil { - log.Printf("[ERROR] Création du dossier %s échouée : %v", dirPath, err) - } - - // Default to main folder's ID - assignPathID := int(basePath.ID) - - // Optionally create a new PathDownload record for subfolder - // (Replace 'Title' with your model's actual field for folder name) - sub := models.PathDownload{ - PathName: series, - Path: dirPath, - } - if err := db.Create(&sub).Error; err == nil { - assignPathID = int(sub.ID) - } - - // Register and start job - job := &download.DownloadJob{ - ID: fmt.Sprintf("job-%d", time.Now().UnixNano()), - Link: l.DownloadURL, - Name: sanitizeFileName(fileName), - Status: "pending", - PathID: assignPathID, - } - if err := download.RegisterJobWithDB(job, db); err != nil { - log.Printf("[ERROR] Enregistrement du job échoué : %v", err) + // Boucle sur chaque lien + for _, link := range lines { + link = strings.TrimSpace(link) + if link == "" { continue } - go download.StartDownload(job, job.Link, client, db) - download.Broadcast() + + links, err := client.AddLink(ctx, link) + if err != nil { + log.Printf("Échec débridage de %s: %v", link, err) + continue + } + + for _, l := range links { + // Détermine le nom de la série + name := sanitizeFileName(l.Name) + series := "" + if m := seriesRegex.FindStringSubmatch(name); len(m) == 2 { + series = m[1] + } + + // Définit dossier cible et ID + assignPathID := basePath.ID + finalDir := basePath.Path + + if series != "" { + dirPath := filepath.Join(basePath.Path, series) + if err := os.MkdirAll(dirPath, os.ModePerm); err != nil { + log.Printf("Erreur création dossier %s: %v", dirPath, err) + } + + // Cherche ou crée l'enregistrement PathDownload + var subPath models.PathDownload + if err := db.Where("path = ?", dirPath).First(&subPath).Error; err != nil { + if err == gorm.ErrRecordNotFound { + subPath = models.PathDownload{Path: dirPath, PathName: series} + if err := db.Create(&subPath).Error; err != nil { + log.Printf("Erreur création PathDownload: %v", err) + } + } else { + log.Printf("Erreur lecture PathDownload: %v", err) + } + } + assignPathID = subPath.ID + finalDir = dirPath + } + + // Enregistrement du job + job := &download.DownloadJob{ + ID: fmt.Sprintf("job-%d", time.Now().UnixNano()), + Link: l.DownloadURL, + Name: l.Name, + Status: "waiting", + PathID: assignPathID, + Directory: finalDir, + } + if err := download.RegisterJobWithDB(job, db); err != nil { + log.Printf("Erreur enregistrement job: %v", err) + continue + } + } } + // Notifie le front + download.Broadcast() w.WriteHeader(http.StatusNoContent) } }