shelfy-v2/internal/utils/lib.go
2025-08-18 21:41:40 +02:00

136 lines
4.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package utils
import (
"errors"
"fmt"
"log"
"os"
"path/filepath"
"strings"
"gorm.io/gorm"
"canguidev/shelfy/internal/models"
)
func CreateDefaultFolder(db *gorm.DB) {
// noms “logiques” attendus en base
targets := []string{"Film", "Série", "Manga", "Magazine"}
// 0) Nettoyage global : si des lignes ont path "upload/XXX", on les normalise en "XXX"
if err := normalizeExistingPaths(db); err != nil {
log.Printf("[DB] Warning: normalisation initiale partielle: %v", err)
}
for _, name := range targets {
diskPath := filepath.Join("upload", name) // répertoire physique
// 1) Toujours créer le dossier physique
if err := os.MkdirAll(diskPath, 0o755); err != nil {
log.Printf("[FOLDER] Erreur création '%s' : %v", diskPath, err)
continue
}
// 2) En base : on veut UNE ligne unique avec Path=Name et PathName=Name
// On cherche tout ce qui pourrait correspondre à ce nom (avec ou sans "upload/")
var rows []models.PathDownload
if err := db.Where("path = ? OR path = ? OR path_name = ? OR path_name = ?",
name, "upload/"+name, name, "upload/"+name,
).Find(&rows).Error; err != nil {
log.Printf("[DB] Lookup '%s' échouée : %v", name, err)
continue
}
switch len(rows) {
case 0:
// 2a) Rien trouvé → créer la ligne normalisée
row := models.PathDownload{Path: name, PathName: name}
if err := db.Create(&row).Error; err != nil {
log.Printf("[DB] Création PathDownload('%s') KO : %v", name, err)
} else {
log.Printf("[DB] Créé PathDownload id=%v (%s)", row.ID, name)
}
default:
// 2b) On a des lignes → on les normalise et on garde une seule
// 1) mettre à jour la première ligne en Path=Name, PathName=Name
main := rows[0]
needUpdate := (main.Path != name) || (main.PathName != name)
if needUpdate {
if err := db.Model(&main).Updates(map[string]any{
"path": name,
"path_name": name,
}).Error; err != nil {
log.Printf("[DB] Update id=%v -> (%s|%s) KO : %v", main.ID, name, name, err)
} else {
log.Printf("[DB] Normalisé id=%v -> (%s|%s)", main.ID, name, name)
}
}
// 2) supprimer les doublons résiduels (même nom logique)
if len(rows) > 1 {
var dupIDs []uint
for _, r := range rows[1:] {
dupIDs = append(dupIDs, r.ID)
}
if err := db.Where("id IN ?", dupIDs).Delete(&models.PathDownload{}).Error; err != nil {
log.Printf("[DB] Suppression doublons (%v) KO : %v", dupIDs, err)
} else {
log.Printf("[DB] Doublons supprimés pour '%s' : %v", name, dupIDs)
}
}
}
log.Printf("[FOLDER] OK : %s (DB='%s')", diskPath, name)
}
}
// normalizeExistingPaths met à jour toutes les lignes dont path commence par "upload/"
// en supprimant ce préfixe, et aligne path_name si nécessaire. Elle supprime aussi
// déventuels doublons créés par cette normalisation.
func normalizeExistingPaths(db *gorm.DB) error {
// 1) Récupérer les lignes impactées
var rows []models.PathDownload
if err := db.Where("path LIKE ?", "upload/%").Find(&rows).Error; err != nil {
return err
}
for _, r := range rows {
trimmed := strings.TrimPrefix(r.Path, "upload/")
updates := map[string]any{"path": trimmed}
if r.PathName == "" || strings.HasPrefix(r.PathName, "upload/") {
updates["path_name"] = trimmed
}
if err := db.Model(&r).Updates(updates).Error; err != nil {
return fmt.Errorf("update id=%v (%s -> %s) : %w", r.ID, r.Path, trimmed, err)
}
}
// 2) Éliminer déventuels doublons (même path normalisé), on garde le plus petit id
type rec struct {
ID uint
Path string
}
var all []rec
if err := db.Model(&models.PathDownload{}).Select("id, path").Order("path, id").Scan(&all).Error; err != nil {
return err
}
seen := make(map[string]uint)
var dupIDs []uint
for _, r := range all {
if keep, ok := seen[r.Path]; ok {
// doublon : on marque pour suppression
dupIDs = append(dupIDs, r.ID)
_ = keep
} else {
seen[r.Path] = r.ID
}
}
if len(dupIDs) > 0 {
if err := db.Where("id IN ?", dupIDs).Delete(&models.PathDownload{}).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return fmt.Errorf("delete dups %v : %w", dupIDs, err)
}
log.Printf("[DB] Doublons supprimés après normalisation: %v", dupIDs)
}
return nil
}