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)
}