package main import ( "fmt" "html/template" "os" "sort" "strconv" "time" "github.com/hekmon/transmissionrpc" ) 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 SessionStat struct { Label string Value string } type TorrentInfo struct { Name string HashString string DateAdded time.Time UploadedEver string } type TorrentStatsPageData struct { Date string SessionStats []SessionStat CurrentStats []SessionStat CumulativeStats []SessionStat TorrentInfo []TorrentInfo } func main() { transmissionbt, err := transmissionrpc.New("", "", "", nil) if err != nil { panic(err) } stats, err := transmissionbt.SessionStats() if err != nil { panic(err) } sessionStats := []SessionStat{ {Label: "Active torrent count", Value: fmt.Sprintf("%d", *&stats.ActiveTorrentCount)}, {Label: "Download speed", Value: fmt.Sprintf("%s/sec", byteCountIEC(*&stats.DownloadSpeed))}, {Label: "Upload speed", Value: fmt.Sprintf("%s/sec", byteCountIEC(*&stats.UploadSpeed))}, {Label: "Paused torrent count", Value: fmt.Sprintf("%d", *&stats.PausedTorrentCount)}, {Label: "Torrent count", Value: fmt.Sprintf("%d", *&stats.TorrentCount)}, } currentStats := []SessionStat{ {Label: "Uploaded bytes", Value: fmt.Sprintf("%s", byteCountIEC(*&stats.CurrentStats.UploadedBytes))}, {Label: "Downloaded bytes", Value: fmt.Sprintf("%s", byteCountIEC(*&stats.CurrentStats.DownloadedBytes))}, {Label: "Uploaded/Downloaded ratio", Value: fmt.Sprintf("%d", *&stats.CurrentStats.UploadedBytes / *&stats.CurrentStats.DownloadedBytes)}, {Label: "Files added", Value: fmt.Sprintf("%d", *&stats.CurrentStats.FilesAdded)}, {Label: "Session count", Value: fmt.Sprintf("%d", *&stats.CurrentStats.SessionCount)}, {Label: "Seconds active", Value: convertTime(*&stats.CurrentStats.SecondsActive)}, } cumulativeStats := []SessionStat{ {Label: "Uploaded bytes", Value: fmt.Sprintf("%s", byteCountIEC(*&stats.CumulativeStats.UploadedBytes))}, {Label: "Downloaded bytes", Value: fmt.Sprintf("%s", byteCountIEC(*&stats.CumulativeStats.DownloadedBytes))}, {Label: "Uploaded/Downloaded ratio", Value: fmt.Sprintf("%d", *&stats.CumulativeStats.UploadedBytes / *&stats.CumulativeStats.DownloadedBytes)}, {Label: "Files added", Value: fmt.Sprintf("%d", *&stats.CumulativeStats.FilesAdded)}, {Label: "Session count", Value: fmt.Sprintf("%d", *&stats.CumulativeStats.SessionCount)}, {Label: "Seconds active", Value: convertTime(*&stats.CumulativeStats.SecondsActive)}, } var torrentInfo = []TorrentInfo{} torrents, err := transmissionbt.TorrentGet([]string{"name", "hashString", "addedDate", "uploadedEver"}, nil) if err != nil { fmt.Fprintln(os.Stderr, err) } else { for _, torrent := range torrents { torrentInfo = append(torrentInfo, TorrentInfo{Name: *torrent.Name, HashString: *torrent.HashString, DateAdded: *torrent.AddedDate, UploadedEver: strconv.FormatInt(*torrent.UploadedEver, 10)}) } } sort.Slice(torrentInfo, func(i, j int) bool { iInt, err := strconv.ParseInt(torrentInfo[i].UploadedEver, 10, 64) if err != nil { panic(err) } jInt, err := strconv.ParseInt(torrentInfo[j].UploadedEver, 10, 64) if err != nil { panic(err) } return iInt > jInt }) for i := range torrentInfo { parsedInt, err := strconv.ParseInt(torrentInfo[i].UploadedEver, 10, 64) if err != nil { panic(err) } torrentInfo[i].UploadedEver = byteCountIEC(parsedInt) } data := TorrentStatsPageData{ Date: time.Now().Format(time.UnixDate), SessionStats: sessionStats, CurrentStats: currentStats, CumulativeStats: cumulativeStats, TorrentInfo: torrentInfo, } t, err := template.ParseFiles("template.html") err = t.Execute(os.Stdout, data) }