Compare commits
2 Commits
a9bf4d7403
...
1940fde7cc
| Author | SHA1 | Date | |
|---|---|---|---|
| 1940fde7cc | |||
| 773ea9dc13 |
@ -6,76 +6,126 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"canguidev/shelfy/internal/models"
|
||||
)
|
||||
|
||||
// Synchronise le disque avec la base : Film, Série, Manga, Magazine.
|
||||
// - Disque : crée "upload/<Nom>" si manquant
|
||||
// - DB : 1 ligne unique par nom (Path="<Nom>", PathName="<Nom>")
|
||||
func CreateDefaultFolder(db *gorm.DB) {
|
||||
type item struct {
|
||||
Name string
|
||||
}
|
||||
defs := []item{
|
||||
{Name: "Film"},
|
||||
{Name: "Série"},
|
||||
{Name: "Manga"},
|
||||
{Name: "Magazine"},
|
||||
targets := []string{"Film", "Série", "Manga", "Magazine"}
|
||||
|
||||
// 0) Normalise les entrées existantes (upload/X -> X) et dédoublonne
|
||||
if err := normalizeExistingPaths(db); err != nil {
|
||||
log.Printf("[DB] Avertissement: normalisation partielle: %v", err)
|
||||
}
|
||||
|
||||
for _, it := range defs {
|
||||
path := filepath.Join("upload", it.Name)
|
||||
|
||||
// 1) Dossier : on s'assure qu'il existe
|
||||
if err := os.MkdirAll(path, 0o755); err != nil {
|
||||
log.Printf("[FOLDER] Erreur création '%s' : %v", path, err)
|
||||
for _, name := range targets {
|
||||
// 1) Dossier physique
|
||||
diskPath := filepath.Join("upload", name)
|
||||
if err := os.MkdirAll(diskPath, 0o755); err != nil {
|
||||
log.Printf("[FOLDER] Erreur création '%s' : %v", diskPath, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// 2) Base : chercher une ligne existante par path OU path_name
|
||||
var existing models.PathDownload
|
||||
err := db.Where("path = ? OR path_name = ?", path, it.Name).First(&existing).Error
|
||||
// 2) DB : cherche toute ligne liée à ce nom (avec/ 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 {
|
||||
case errors.Is(err, gorm.ErrRecordNotFound):
|
||||
// 2a) Pas trouvé -> on crée
|
||||
row := models.PathDownload{
|
||||
Path: path,
|
||||
PathName: it.Name,
|
||||
}
|
||||
switch len(rows) {
|
||||
case 0:
|
||||
// crée proprement
|
||||
row := models.PathDownload{Path: name, PathName: name}
|
||||
if err := db.Create(&row).Error; err != nil {
|
||||
log.Printf("[DB] Échec création PathDownload(%s, %s) : %v", path, it.Name, err)
|
||||
log.Printf("[DB] Création PathDownload('%s') KO : %v", name, err)
|
||||
} else {
|
||||
log.Printf("[DB] Ligne créée PathDownload id=%v (%s | %s)", row.ID, row.PathName, row.Path)
|
||||
log.Printf("[DB] Créé PathDownload id=%v (%s)", row.ID, name)
|
||||
}
|
||||
|
||||
case err != nil:
|
||||
// 2b) Erreur DB
|
||||
log.Printf("[DB] Erreur recherche PathDownload(%s | %s) : %v", path, it.Name, err)
|
||||
|
||||
default:
|
||||
// 2c) Trouvé -> on normalise si besoin
|
||||
updates := map[string]interface{}{}
|
||||
if existing.Path != path {
|
||||
updates["path"] = path
|
||||
}
|
||||
if existing.PathName != it.Name {
|
||||
updates["path_name"] = it.Name
|
||||
}
|
||||
if len(updates) > 0 {
|
||||
if err := db.Model(&existing).Updates(updates).Error; err != nil {
|
||||
log.Printf("[DB] Échec mise à jour PathDownload id=%v : %v", existing.ID, err)
|
||||
// garde la première, normalise, supprime doublons
|
||||
main := rows[0]
|
||||
if main.Path != name || main.PathName != name {
|
||||
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] Mis à jour PathDownload id=%v -> %#v", existing.ID, updates)
|
||||
log.Printf("[DB] Normalisé id=%v -> (%s|%s)", main.ID, name, name)
|
||||
}
|
||||
}
|
||||
if len(rows) > 1 {
|
||||
var dupIDs []int64
|
||||
for _, r := range rows[1:] {
|
||||
dupIDs = append(dupIDs, r.ID) // ID en int64
|
||||
}
|
||||
if err := db.Where("id IN ?", dupIDs).Delete(&models.PathDownload{}).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
log.Printf("[DB] Suppression doublons (%v) KO : %v", dupIDs, err)
|
||||
} else {
|
||||
log.Printf("[DB] Doublons supprimés pour '%s' : %v", name, dupIDs)
|
||||
}
|
||||
} else {
|
||||
log.Printf("[DB] OK PathDownload id=%v déjà synchro (%s | %s)", existing.ID, existing.PathName, existing.Path)
|
||||
}
|
||||
}
|
||||
|
||||
// 3) (Facultatif) log côté fichiers
|
||||
if fi, err := os.Stat(path); err == nil && fi.IsDir() {
|
||||
fmt.Printf("[FOLDER] OK : %s\n", path)
|
||||
}
|
||||
log.Printf("[FOLDER] OK : %s (DB='%s')", diskPath, name)
|
||||
}
|
||||
}
|
||||
|
||||
// Met à jour toutes les lignes path="upload/..." -> path="...",
|
||||
// aligne path_name si nécessaire, puis supprime les doublons.
|
||||
func normalizeExistingPaths(db *gorm.DB) error {
|
||||
// 1) Normalisation des paths
|
||||
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) Déduplication par path (on garde le plus petit id)
|
||||
type rec struct {
|
||||
ID int64 // <-- int64
|
||||
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]int64)
|
||||
var dupIDs []int64
|
||||
for _, r := range all {
|
||||
if _, ok := seen[r.Path]; ok {
|
||||
dupIDs = append(dupIDs, r.ID)
|
||||
} 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
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user