diff --git a/cmd/app/app.go b/cmd/app/app.go index ecdd57c..d707a1c 100644 --- a/cmd/app/app.go +++ b/cmd/app/app.go @@ -18,5 +18,6 @@ func AppCmd() *cobra.Command { cmd.AddCommand(subcommands.UpdateAppCmd) cmd.AddCommand(subcommands.UninstallAppCmd) cmd.AddCommand(subcommands.StartAllCmd) + cmd.AddCommand(subcommands.ListAppBackupsCmd) return cmd } \ No newline at end of file diff --git a/cmd/app/subcommands/list-backups.go b/cmd/app/subcommands/list-backups.go new file mode 100644 index 0000000..b3772c7 --- /dev/null +++ b/cmd/app/subcommands/list-backups.go @@ -0,0 +1,64 @@ +package subcommands + +import ( + "fmt" + "os" + "path" + "strconv" + "strings" + "time" + + "github.com/aquasecurity/table" + "github.com/spf13/cobra" + "github.com/steveiliop56/runtipi-cli-go/internal/constants" + "github.com/steveiliop56/runtipi-cli-go/internal/utils" +) + +var ListAppBackupsCmd = &cobra.Command{ + Use: "list-backups [app]", + Short: "List app backups", + Long: "Lists all the backups of an app", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + // Get root folder + rootFolder, osErr := os.Getwd() + + if osErr != nil { + fmt.Printf("%s Failed to get root folder\n", constants.Red("✗")) + fmt.Printf("Error: %s\n", osErr) + os.Exit(1) + } + + // Define paths + backupPath := path.Join(rootFolder, "backups", args[0]) + + // Check if folder exists + _, pathCheckErr := os.Stat(backupPath) + if pathCheckErr != nil { + fmt.Printf("%s App backup path doesn't exist\n", constants.Red("✗")) + fmt.Printf("Error: %s\n", pathCheckErr) + os.Exit(1) + } + + // Read directory + backups, readErr := os.ReadDir(backupPath) + if readErr != nil { + fmt.Printf("%s Failed to read app backups folder\n", constants.Red("✗")) + fmt.Printf("Error: %s\n", pathCheckErr) + os.Exit(1) + } + + // List backups + backupsTable := table.New(os.Stdout) + backupsTable.SetHeaders("Name", "Size", "Date Created") + for _, backup := range backups { + backupInfo, _ := backup.Info() + backupSize := utils.FormatFileSize(float64(backupInfo.Size())) + backupDateIso, _ := strconv.ParseInt(strings.Replace(strings.Replace(strings.Replace(backup.Name(), args[0], "", 1), ".tar.gz", "", 1), "-", "", 1), 10, 64) + backupDate := time.UnixMilli(backupDateIso).String() + backupsTable.AddRow(backup.Name(), backupSize, backupDate) + } + + backupsTable.Render() + }, +} \ No newline at end of file diff --git a/cmd/debug.go b/cmd/debug.go index 20e528a..d5e79df 100644 --- a/cmd/debug.go +++ b/cmd/debug.go @@ -17,6 +17,7 @@ import ( "github.com/steveiliop56/runtipi-cli-go/internal/constants" "github.com/steveiliop56/runtipi-cli-go/internal/env" "github.com/steveiliop56/runtipi-cli-go/internal/system" + "github.com/steveiliop56/runtipi-cli-go/internal/utils" ) func init() { @@ -85,7 +86,7 @@ var debugCmd = &cobra.Command{ sysInfoTable := table.New(os.Stdout) sysInfoTable.AddRow("OS", operatingSystem) sysInfoTable.AddRow("OS Version", string(kernel[:])) - sysInfoTable.AddRow("Memory (GB)", fmt.Sprintf("%.2f", float64(memory.Total)/(1<<30))) + sysInfoTable.AddRow("Memory (GB)", utils.FormatFileSize(float64(memory.Total))) sysInfoTable.AddRow("Architecture", arch) sysInfoTable.Render() fmt.Println() diff --git a/cmd/system/subcommands/status.go b/cmd/system/subcommands/status.go index 41ca448..46e2184 100644 --- a/cmd/system/subcommands/status.go +++ b/cmd/system/subcommands/status.go @@ -55,8 +55,8 @@ var StatusCmd = &cobra.Command{ spinner.Stop() // Print status - fmt.Printf("Your CPU usage is %s %% \n", constants.Blue(fmt.Sprintf("%.2f", status.Data.CpuLoad))) - fmt.Printf("Your Disk size is %s GB, you are using %s GB which is %s %% \n", constants.Blue(status.Data.DiskSize), constants.Blue(status.Data.DiskUsed), constants.Blue(status.Data.PercentUsed)) - fmt.Printf("Your Memory size is %s GB and you are using %s %% \n", constants.Blue(status.Data.MemoryTotal), constants.Blue(status.Data.PercentUsedMemory)) + fmt.Printf("Your CPU usage is %s\n", constants.Blue(fmt.Sprintf("%.2f%%", status.Data.CpuLoad))) + fmt.Printf("Your Disk size is %s, you are using %s which is %s\n", constants.Blue(fmt.Sprintf("%dGB", status.Data.DiskSize)), constants.Blue(fmt.Sprintf("%dGB", status.Data.DiskUsed)), constants.Blue(fmt.Sprintf("%0.f%%", status.Data.PercentUsed))) + fmt.Printf("Your Memory size is %s and you are using %s\n", constants.Blue(fmt.Sprintf("%dGB", status.Data.MemoryTotal)), constants.Blue(fmt.Sprintf("%0.f%%", status.Data.PercentUsedMemory))) }, } \ No newline at end of file diff --git a/internal/schemas/schemas.go b/internal/schemas/schemas.go index 4cd34af..c25cdd9 100644 --- a/internal/schemas/schemas.go +++ b/internal/schemas/schemas.go @@ -20,15 +20,15 @@ type Settings struct { type SystemStatus struct { // Disk - DiskUsed float64 `json:"diskUsed"` - DiskSize float64 `json:"diskSize"` + DiskUsed int64 `json:"diskUsed"` + DiskSize int64 `json:"diskSize"` PercentUsed float64 `json:"percentUsed"` // Cpu CpuLoad float64 `json:"cpuLoad"` // Memory - MemoryTotal int `json:"memoryTotal"` + MemoryTotal int64 `json:"memoryTotal"` PercentUsedMemory float64 `json:"percentUsedMemory"` } diff --git a/internal/utils/utils.go b/internal/utils/utils.go new file mode 100644 index 0000000..62da61f --- /dev/null +++ b/internal/utils/utils.go @@ -0,0 +1,21 @@ +package utils + +import ( + "fmt" + "strconv" +) + +func FormatFileSize(fileSize float64) (string) { + if fileSize < (1<<10) { + return fmt.Sprintf("%sB", strconv.Itoa(int(fileSize))) + } else if fileSize > (1<<10) && fileSize < (1<<20) { + return fmt.Sprintf("%.2fKB", fileSize/(1<<10)) + } else if fileSize > (1<<20) && fileSize < (1<<30) { + return fmt.Sprintf("%2.fMB", fileSize/(1<<20)) + } else if fileSize > (1<<30) && fileSize < (1<<40) { + return fmt.Sprintf("%.2fGB", fileSize/(1<<30)) + } else if fileSize > (1<<40) { + return fmt.Sprintf("%.2fTB", fileSize/(1<<40)) + } + return fmt.Sprintf("%sB", strconv.Itoa(int(fileSize))) +} \ No newline at end of file