package main import ( "encoding/json" "fmt" "os" "text/tabwriter" "time" "warpbox/lib/boxstore" "warpbox/lib/models" ) // ── List output ────────────────────────────────────────────── func formatBoxSummariesTable(summaries []models.BoxSummary) error { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) fmt.Fprintln(w, "ID\tFiles\tSize\tCreated\tExpires\tPassword\tOne-Time\tExpired") for _, s := range summaries { expires := "-" if !s.ExpiresAt.IsZero() { expires = s.ExpiresAt.Format("2006-01-02 15:04:05") } created := s.CreatedAt.Format("2006-01-02 15:04:05") fmt.Fprintf(w, "%s\t%d\t%s\t%s\t%s\t%v\t%v\t%v\n", s.ID, s.FileCount, s.TotalSizeLabel, created, expires, s.PasswordProtected, s.OneTimeDownload, s.Expired) } return w.Flush() } func formatBoxSummariesJSON(summaries []models.BoxSummary) error { type summaryOut struct { ID string `json:"id"` FileCount int `json:"file_count"` TotalSize int64 `json:"total_size"` TotalSizeLabel string `json:"total_size_label"` CreatedAt time.Time `json:"created_at"` ExpiresAt time.Time `json:"expires_at"` Expired bool `json:"expired"` OneTimeDownload bool `json:"one_time_download"` PasswordProtected bool `json:"password_protected"` } out := make([]summaryOut, len(summaries)) for i, s := range summaries { out[i] = summaryOut{ ID: s.ID, FileCount: s.FileCount, TotalSize: s.TotalSize, TotalSizeLabel: s.TotalSizeLabel, CreatedAt: s.CreatedAt, ExpiresAt: s.ExpiresAt, Expired: s.Expired, OneTimeDownload: s.OneTimeDownload, PasswordProtected: s.PasswordProtected, } } enc := json.NewEncoder(os.Stdout) enc.SetIndent("", " ") return enc.Encode(out) } // ── View output ────────────────────────────────────────────── func formatBoxSummaryJSON(s *models.BoxSummary) error { type summaryOut struct { ID string `json:"id"` FileCount int `json:"file_count"` TotalSize int64 `json:"total_size"` TotalSizeLabel string `json:"total_size_label"` CreatedAt time.Time `json:"created_at"` ExpiresAt time.Time `json:"expires_at"` Expired bool `json:"expired"` OneTimeDownload bool `json:"one_time_download"` PasswordProtected bool `json:"password_protected"` } out := summaryOut{ ID: s.ID, FileCount: s.FileCount, TotalSize: s.TotalSize, TotalSizeLabel: s.TotalSizeLabel, CreatedAt: s.CreatedAt, ExpiresAt: s.ExpiresAt, Expired: s.Expired, OneTimeDownload: s.OneTimeDownload, PasswordProtected: s.PasswordProtected, } enc := json.NewEncoder(os.Stdout) enc.SetIndent("", " ") return enc.Encode(out) } func printBoxSummary(s *models.BoxSummary) { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) fmt.Fprintf(w, "ID:\t%s\n", s.ID) fmt.Fprintf(w, "Files:\t%d\n", s.FileCount) fmt.Fprintf(w, "Total Size:\t%s\n", s.TotalSizeLabel) if !s.CreatedAt.IsZero() { fmt.Fprintf(w, "Created:\t%s\n", s.CreatedAt.Format(time.RFC3339)) } if !s.ExpiresAt.IsZero() { fmt.Fprintf(w, "Expires:\t%s\n", s.ExpiresAt.Format(time.RFC3339)) } fmt.Fprintf(w, "Expired:\t%v\n", s.Expired) fmt.Fprintf(w, "Password Protected:\t%v\n", s.PasswordProtected) fmt.Fprintf(w, "One-Time Download:\t%v\n", s.OneTimeDownload) w.Flush() } // ── Get output ─────────────────────────────────────────────── func formatBoxGetJSON(boxID string, manifest models.BoxManifest) error { type getOut struct { BoxID string `json:"box_id"` URL string `json:"url"` CreatedAt time.Time `json:"created_at,omitempty"` ExpiresAt time.Time `json:"expires_at,omitempty"` Expired bool `json:"expired"` PasswordProtected bool `json:"password_protected"` OneTimeDownload bool `json:"one_time_download"` RetentionKey string `json:"retention_key,omitempty"` RetentionLabel string `json:"retention_label,omitempty"` } out := getOut{ BoxID: boxID, URL: "/box/" + boxID, Expired: boxstore.IsExpired(manifest), } if !manifest.CreatedAt.IsZero() { out.CreatedAt = manifest.CreatedAt } if !manifest.ExpiresAt.IsZero() { out.ExpiresAt = manifest.ExpiresAt } out.PasswordProtected = boxstore.IsPasswordProtected(manifest) out.OneTimeDownload = manifest.OneTimeDownload out.RetentionKey = manifest.RetentionKey out.RetentionLabel = manifest.RetentionLabel enc := json.NewEncoder(os.Stdout) enc.SetIndent("", " ") return enc.Encode(out) } // ── Change output ──────────────────────────────────────────── func formatChangeResultJSON(boxID string, manifest models.BoxManifest) error { type changeOut struct { BoxID string `json:"box_id"` Updated bool `json:"updated"` CreatedAt time.Time `json:"created_at,omitempty"` ExpiresAt time.Time `json:"expires_at,omitempty"` Expired bool `json:"expired"` PasswordProtected bool `json:"password_protected"` OneTimeDownload bool `json:"one_time_download"` DisableZip bool `json:"disable_zip"` RetentionKey string `json:"retention_key,omitempty"` RetentionLabel string `json:"retention_label,omitempty"` RetentionSeconds int64 `json:"retention_seconds,omitempty"` FileCount int `json:"file_count"` } out := changeOut{ BoxID: boxID, Updated: true, Expired: boxstore.IsExpired(manifest), PasswordProtected: boxstore.IsPasswordProtected(manifest), OneTimeDownload: manifest.OneTimeDownload, DisableZip: manifest.DisableZip, RetentionKey: manifest.RetentionKey, RetentionLabel: manifest.RetentionLabel, RetentionSeconds: manifest.RetentionSecs, FileCount: len(manifest.Files), } if !manifest.CreatedAt.IsZero() { out.CreatedAt = manifest.CreatedAt } if !manifest.ExpiresAt.IsZero() { out.ExpiresAt = manifest.ExpiresAt } enc := json.NewEncoder(os.Stdout) enc.SetIndent("", " ") return enc.Encode(out) } // ── Retention options ──────────────────────────────────────── func printRetentionOptions() { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) fmt.Fprintln(w, "Key\tLabel\tSeconds") for _, opt := range boxstore.RetentionOptions() { fmt.Fprintf(w, "%s\t%s\t%d\n", opt.Key, opt.Label, opt.Seconds) } w.Flush() }