mirror of
https://github.com/lordmathis/lemma.git
synced 2025-11-06 16:04:23 +00:00
Implement file system stats
This commit is contained in:
@@ -3,8 +3,8 @@ package db
|
|||||||
|
|
||||||
import "novamd/internal/models"
|
import "novamd/internal/models"
|
||||||
|
|
||||||
// SystemStats represents system-wide statistics
|
// UserStats represents system-wide statistics
|
||||||
type SystemStats struct {
|
type UserStats struct {
|
||||||
TotalUsers int `json:"totalUsers"`
|
TotalUsers int `json:"totalUsers"`
|
||||||
TotalWorkspaces int `json:"totalWorkspaces"`
|
TotalWorkspaces int `json:"totalWorkspaces"`
|
||||||
ActiveUsers int `json:"activeUsers"` // Users with activity in last 30 days
|
ActiveUsers int `json:"activeUsers"` // Users with activity in last 30 days
|
||||||
@@ -39,8 +39,8 @@ func (db *DB) GetAllUsers() ([]*models.User, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetSystemStats returns system-wide statistics
|
// GetSystemStats returns system-wide statistics
|
||||||
func (db *DB) GetSystemStats() (*SystemStats, error) {
|
func (db *DB) GetSystemStats() (*UserStats, error) {
|
||||||
stats := &SystemStats{}
|
stats := &UserStats{}
|
||||||
|
|
||||||
// Get total users
|
// Get total users
|
||||||
err := db.QueryRow("SELECT COUNT(*) FROM users").Scan(&stats.TotalUsers)
|
err := db.QueryRow("SELECT COUNT(*) FROM users").Scan(&stats.TotalUsers)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ package filesystem
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
@@ -151,3 +152,68 @@ func (fs *FileSystem) DeleteFile(userID, workspaceID int, filePath string) error
|
|||||||
}
|
}
|
||||||
return os.Remove(fullPath)
|
return os.Remove(fullPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FileCountStats holds statistics about files in a workspace
|
||||||
|
type FileCountStats struct {
|
||||||
|
TotalFiles int `json:"totalFiles"`
|
||||||
|
TotalSize int64 `json:"totalSize"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFileStats returns the total number of files and related statistics in a workspace
|
||||||
|
// Parameters:
|
||||||
|
// - userID: the ID of the user who owns the workspace
|
||||||
|
// - workspaceID: the ID of the workspace to count files in
|
||||||
|
// Returns:
|
||||||
|
// - result: statistics about the files in the workspace
|
||||||
|
// - error: any error that occurred during counting
|
||||||
|
func (fs *FileSystem) GetFileStats(userID, workspaceID int) (*FileCountStats, error) {
|
||||||
|
workspacePath := fs.GetWorkspacePath(userID, workspaceID)
|
||||||
|
|
||||||
|
// Check if workspace exists
|
||||||
|
if _, err := os.Stat(workspacePath); os.IsNotExist(err) {
|
||||||
|
return nil, errors.New("workspace directory does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
return fs.countFilesInPath(workspacePath)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *FileSystem) countFilesInPath(directoryPath string) (*FileCountStats, error) {
|
||||||
|
result := &FileCountStats{}
|
||||||
|
|
||||||
|
err := filepath.WalkDir(directoryPath, func(path string, d os.DirEntry, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip the .git directory
|
||||||
|
if d.IsDir() && d.Name() == ".git" {
|
||||||
|
return filepath.SkipDir
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only count regular files
|
||||||
|
if !d.IsDir() {
|
||||||
|
// Get relative path from workspace root
|
||||||
|
relPath, err := filepath.Rel(directoryPath, path)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get relative path: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get file info for size
|
||||||
|
info, err := d.Info()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get file info for %s: %w", relPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.TotalFiles++
|
||||||
|
result.TotalSize += info.Size()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error counting files: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,3 +33,8 @@ func (fs *FileSystem) ValidatePath(userID, workspaceID int, path string) (string
|
|||||||
|
|
||||||
return cleanPath, nil
|
return cleanPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetTotalFileStats returns the total file statistics for the file system.
|
||||||
|
func (fs *FileSystem) GetTotalFileStats() (*FileCountStats, error) {
|
||||||
|
return fs.countFilesInPath(fs.RootDir)
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package handlers
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"novamd/internal/db"
|
||||||
|
"novamd/internal/filesystem"
|
||||||
"novamd/internal/httpcontext"
|
"novamd/internal/httpcontext"
|
||||||
"novamd/internal/models"
|
"novamd/internal/models"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -27,7 +29,7 @@ type UpdateUserRequest struct {
|
|||||||
|
|
||||||
// AdminListUsers returns a list of all users
|
// AdminListUsers returns a list of all users
|
||||||
func (h *Handler) AdminListUsers() http.HandlerFunc {
|
func (h *Handler) AdminListUsers() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, _ *http.Request) {
|
||||||
users, err := h.DB.GetAllUsers()
|
users, err := h.DB.GetAllUsers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Failed to list users", http.StatusInternalServerError)
|
http.Error(w, "Failed to list users", http.StatusInternalServerError)
|
||||||
@@ -202,15 +204,32 @@ func (h *Handler) AdminDeleteUser() http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SystemStats holds system-wide statistics
|
||||||
|
type SystemStats struct {
|
||||||
|
*db.UserStats
|
||||||
|
*filesystem.FileCountStats
|
||||||
|
}
|
||||||
|
|
||||||
// AdminGetSystemStats returns system-wide statistics for admins
|
// AdminGetSystemStats returns system-wide statistics for admins
|
||||||
func (h *Handler) AdminGetSystemStats() http.HandlerFunc {
|
func (h *Handler) AdminGetSystemStats() http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, _ *http.Request) {
|
||||||
stats, err := h.DB.GetSystemStats()
|
userStats, err := h.DB.GetSystemStats()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Failed to get system stats", http.StatusInternalServerError)
|
http.Error(w, "Failed to get user stats", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileStats, err := h.FS.GetTotalFileStats()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Failed to get file stats", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stats := &SystemStats{
|
||||||
|
UserStats: userStats,
|
||||||
|
FileCountStats: fileStats,
|
||||||
|
}
|
||||||
|
|
||||||
respondJSON(w, stats)
|
respondJSON(w, stats)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user