package controllers import ( "net/http" "os" "path/filepath" "strings" "github.com/gin-gonic/gin" "github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/disk" "github.com/shirou/gopsutil/mem" ) type FolderStat struct { Name string `json:"Name"` Path string `json:"Path"` Size int64 `json:"Size"` IsDir bool `json:"IsDir"` Children []FolderStat `json:"Children,omitempty"` } type SystemStats struct { CPUUsage float64 `json:"CPUUsage"` TotalRAM uint64 `json:"TotalRAM"` UsedRAM uint64 `json:"UsedRAM"` FreeRAM uint64 `json:"FreeRAM"` UsedRAMPct float64 `json:"UsedRAMPct"` DiskTotal uint64 `json:"DiskTotal"` DiskFree uint64 `json:"DiskFree"` DiskUsed uint64 `json:"DiskUsed"` DiskUsedPct float64 `json:"DiskUsedPct"` } // calcule récursivement la taille d’un dossier func getFolderStats(absPath, relPath string) (FolderStat, error) { info, err := os.Stat(absPath) if err != nil { return FolderStat{}, err } stat := FolderStat{ Name: info.Name(), Path: relPath, IsDir: info.IsDir(), Size: 0, } if !info.IsDir() { stat.Size = info.Size() return stat, nil } entries, err := os.ReadDir(absPath) if err != nil { return stat, err } var total int64 for _, entry := range entries { childAbs := filepath.Join(absPath, entry.Name()) childRel := filepath.Join(relPath, entry.Name()) childStat, err := getFolderStats(childAbs, childRel) if err != nil { continue } stat.Children = append(stat.Children, childStat) total += childStat.Size } stat.Size = total return stat, nil } // Handler principal func FolderStatsHandler() gin.HandlerFunc { return func(c *gin.Context) { base := "upload" rel := c.Query("path") if rel == "" { rel = "" } rel = filepath.Clean("/" + rel) rel = strings.TrimPrefix(rel, "/") absPath := filepath.Join(base, rel) baseAbs, _ := filepath.Abs(base) absPath, _ = filepath.Abs(absPath) if !strings.HasPrefix(absPath, baseAbs) { c.JSON(http.StatusForbidden, gin.H{"error": "Chemin invalide"}) return } // stats dossier folderStats, err := getFolderStats(absPath, rel) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Impossible de calculer les stats"}) return } // stats système cpuPercent, _ := cpu.Percent(0, false) memStats, _ := mem.VirtualMemory() diskStats, _ := disk.Usage(baseAbs) sysStats := SystemStats{ CPUUsage: cpuPercent[0], TotalRAM: memStats.Total, UsedRAM: memStats.Used, FreeRAM: memStats.Available, UsedRAMPct: memStats.UsedPercent, DiskTotal: diskStats.Total, DiskFree: diskStats.Free, DiskUsed: diskStats.Used, DiskUsedPct: diskStats.UsedPercent, } // réponse c.JSON(http.StatusOK, gin.H{ "folderStats": folderStats, "systemStats": sysStats, }) } }