package main import ( "context" "fmt" "log" "os" "sort" "time" "github.com/hekmon/cunits/v2" "github.com/hyperreal64/transmissionrpc" "github.com/olekukonko/tablewriter" ) func byteCountIEC(b int64) string { const unit = 1024 if b < unit { return fmt.Sprintf("%d B", b) } div, exp := int64(unit), 0 for n := b / unit; n >= unit; n /= unit { div *= unit exp++ } return fmt.Sprintf("%.1f %ciB", float64(b)/float64(div), "KMGTPE"[exp]) } func convertTime(seconds int64) string { switch { case seconds > 86400: day := seconds / 86400 remainder := seconds % 86400 hour := remainder / 3600 remainder = remainder % 3600 minutes := remainder / 60 remainder = remainder % 60 return fmt.Sprintf("%d days, %d hours, %d minutes, %d seconds", day, hour, minutes, remainder) case seconds < 86400 && seconds > 3600: hour := seconds / 3600 remainder := seconds % 3600 minutes := remainder / 60 remainder = remainder % 60 return fmt.Sprintf("%d hours, %d minutes, %d seconds", hour, minutes, remainder) case seconds < 3600 && seconds > 60: minutes := seconds / 60 remainder := seconds % 60 return fmt.Sprintf("%d minutes, %d seconds", minutes, remainder) default: return fmt.Sprintf("%d seconds", seconds) } } type trackerStats struct { LeecherCount int64 `json:"leecherCount"` SeederCount int64 `json:"seederCount"` } type TorrentInfo struct { Name string ActivityDate time.Time TotalSize cunits.Bits Leechers int64 Seeders int64 } func renderTable(data [][]string) { table := tablewriter.NewWriter(os.Stdout) table.SetAlignment(tablewriter.ALIGN_LEFT) table.AppendBulk(data) table.Render() } func main() { fmt.Println("20 text/gemini\r") fmt.Println("```") transmissionbt, err := transmissionrpc.New(os.Getenv("TRANSMISSION_RPC_URL"), os.Getenv("TRANSMISSION_RPC_USER"), os.Getenv("TRANSMISSION_RPC_PASSWORD"), nil) if err != nil { log.Fatalln(err) } stats, err := transmissionbt.SessionStats(context.TODO()) if err != nil { log.Fatalln(err) } sessionStats := [][]string{ {"Active torrent count", fmt.Sprintf("%d", stats.ActiveTorrentCount)}, {"Download speed", fmt.Sprintf("%s/sec", byteCountIEC(stats.DownloadSpeed))}, {"Upload speed", fmt.Sprintf("%s/sec", byteCountIEC(stats.UploadSpeed))}, {"Paused torrent count", fmt.Sprintf("%d", stats.PausedTorrentCount)}, {"Torrent count", fmt.Sprintf("%d", stats.TorrentCount)}, } fmt.Println("SESSION STATS") renderTable(sessionStats) fmt.Println() currentStats := [][]string{ {"Uploaded bytes", byteCountIEC(stats.CurrentStats.UploadedBytes)}, {"Downloaded bytes", byteCountIEC(stats.CurrentStats.DownloadedBytes)}, {"Files added", fmt.Sprintf("%d", stats.CurrentStats.FilesAdded)}, {"Session count", fmt.Sprintf("%d", stats.CurrentStats.SessionCount)}, {"Time active", convertTime(stats.CurrentStats.SecondsActive)}, } fmt.Println("CURRENT STATS") renderTable(currentStats) fmt.Println() cumulativeStats := [][]string{ {"Uploaded bytes", byteCountIEC(stats.CumulativeStats.UploadedBytes)}, {"Downloaded bytes", byteCountIEC(stats.CumulativeStats.DownloadedBytes)}, {"Files added", fmt.Sprintf("%d", stats.CumulativeStats.FilesAdded)}, {"Session count", fmt.Sprintf("%d", stats.CumulativeStats.SessionCount)}, {"Time active", convertTime(stats.CumulativeStats.SecondsActive)}, } fmt.Println("CUMULATIVE STATS") renderTable(cumulativeStats) fmt.Println() var torrentInfo = []TorrentInfo{} var ( leecherCount int64 seederCount int64 ) fmt.Println("TORRENT STATS") torrents, err := transmissionbt.TorrentGet(context.TODO(), []string{ "activityDate", "name", "totalSize", "trackerStats", }, nil) if err != nil { fmt.Fprintln(os.Stderr, err) } else { for _, torrent := range torrents { for _, stat := range torrent.TrackerStats { leecherCount = stat.LeecherCount seederCount = stat.SeederCount } torrentInfo = append(torrentInfo, TorrentInfo{ Name: *torrent.Name, ActivityDate: *torrent.ActivityDate, TotalSize: *torrent.TotalSize, Leechers: leecherCount, Seeders: seederCount, }) } } sort.Slice(torrentInfo, func(i, j int) bool { return torrentInfo[i].Name < torrentInfo[j].Name }) torrentStats := [][]string{ {"Name", "Activity Date", "Total Size", "Leechers", "Seeders"}, } for _, torrent := range torrentInfo { torrentStats = append(torrentStats, []string{torrent.Name, torrent.ActivityDate.String(), torrent.TotalSize.GiBString(), fmt.Sprintf("%d", torrent.Leechers), fmt.Sprintf("%d", torrent.Seeders)}) } renderTable(torrentStats) }