Skip to content

Commit

Permalink
Fix list totals row and add up/down statuses
Browse files Browse the repository at this point in the history
Update all relevant columns to use string instead of numbers so, for
example, ID can be blank.

Up and Down columns now show statuses like "Stopped", etc. instead of
just 0.0 if they're not downloading or seeding.
  • Loading branch information
Chris Young committed Jun 22, 2020
1 parent 51247fb commit 3d19c74
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 36 deletions.
17 changes: 8 additions & 9 deletions cmd/trpc/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ import (
)

func format(torrent *torrent.Torrent, _ *config.Config) string {
format := `{{printf "%4v" .ID}} ` +
format := `{{printf "%4s" .ID}} ` +
`{{.Error}} ` +
`{{printf "%6.1f" .Percent}}% ` +
`{{printf "%12s" .Size}} ` +
`{{printf "%12s" .SizeWhenDone}} ` +
`{{printf "%-8s" .Eta}} ` +
`{{printf "%7.1f" .Up}} ` +
`{{printf "%7.1f" .Down}} ` +
`{{printf "%8s" .Up}} ` +
`{{printf "%8s" .Down}} ` +
`{{printf "%6.1f" .Ratio}} ` +
`{{printf "%-6s" .Priority}} ` +
`{{printf "%-4s" .Trackershortname}} ` +
Expand Down Expand Up @@ -48,7 +48,7 @@ func List(c *Command) {
opts, ok := c.Options.(listOptions)
optionsCheck(ok)

var total torrent.Torrent
total := torrent.NewForTotal()

total.Error = " "

Expand All @@ -66,13 +66,12 @@ func List(c *Command) {
"isFinished",
}, func(transmissionrpcTorrent *transmissionrpc.Torrent) {
result := torrent.NewFrom(transmissionrpcTorrent, conf)
total.Size += result.Size
total.Up += result.Up
total.Down += result.Down
total.UpdateTotal(result)

formattedTorrent := format(result, conf)
fmt.Println(formattedTorrent)
})

formattedTotal := format(&total, conf)
formattedTotal := format(total, conf)
fmt.Println(formattedTotal)
}
116 changes: 89 additions & 27 deletions internal/torrent/torrent.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package torrent
import (
"fmt"
"net/url"
"strconv"
"strings"

"github.com/shric/trpc/internal/config"
Expand Down Expand Up @@ -32,15 +33,24 @@ const (
EiB
)

func (torrent Torrent) eta() string {
if *torrent.original.LeftUntilDone == 0 {
return "Done"
func statusStr(torrent Torrent) *string {
statusStrings := map[transmissionrpc.TorrentStatus]string{
transmissionrpc.TorrentStatusStopped: "Stopped",
transmissionrpc.TorrentStatusCheckWait: "To Hash",
transmissionrpc.TorrentStatusCheck: "Hashing",
transmissionrpc.TorrentStatusDownloadWait: "Queued",
transmissionrpc.TorrentStatusSeedWait: "Queued",
transmissionrpc.TorrentStatusIsolated: "No peers",
}

if *torrent.original.Eta == -1 {
return "Unknown"
if val, ok := statusStrings[*torrent.original.Status]; ok {
return &val
}

return nil
}

func etastr(eta int64) string {
units := []unitMap{
{86400 * 365.25, "years"},
{86400 * 365.25 / 12, "months"},
Expand All @@ -50,32 +60,44 @@ func (torrent Torrent) eta() string {
{60, "mins"},
}

eta := float64(*torrent.original.Eta)
secs := float64(eta)

for _, u := range units {
if eta > u.Amount*3 {
return fmt.Sprintf("%d %s", int(eta/u.Amount), u.Name)
if secs > u.Amount*3 {
return fmt.Sprintf("%d %s", int(secs/u.Amount), u.Name)
}
}

return fmt.Sprintf("%d secs", int64(eta))
return fmt.Sprintf("%d secs", int64(secs))
}

func (torrent Torrent) eta() string {
if torrent.LeftUntilDone == 0 {
return "Done"
}

if *torrent.original.Eta == -1 {
return "Unknown"
}

return etastr(*torrent.original.Eta)
}

func (torrent Torrent) have() int64 {
return int64(torrent.original.SizeWhenDone.Byte()) - *torrent.original.LeftUntilDone
return int64(torrent.SizeWhenDone.Byte()) - torrent.LeftUntilDone
}

func (torrent Torrent) progress() float64 {
if *torrent.original.RecheckProgress != 0 {
return 100.0 * *torrent.original.RecheckProgress
if torrent.RecheckProgress != 0 {
return 100.0 * torrent.RecheckProgress
}

return 100.0 * float64(torrent.have()) / torrent.original.SizeWhenDone.Byte()
return 100.0 * float64(torrent.have()) / torrent.SizeWhenDone.Byte()
}

func (torrent Torrent) ratio() float64 {
// Returns +Inf on positive/0 or NaN on 0/0.
return float64(*torrent.original.UploadedEver) / torrent.original.SizeWhenDone.Byte()
return float64(torrent.UploadedEver) / torrent.SizeWhenDone.Byte()
}

func (torrent Torrent) priority() string {
Expand Down Expand Up @@ -112,16 +134,44 @@ func (torrent Torrent) trackershortname(conf *config.Config) string {
return "UNK"
}

// UpdateTotal updates the Torrent carrying a total sum of torrents.
func (torrent *Torrent) UpdateTotal(result *Torrent) {
torrent.up += result.up
torrent.down += result.down
torrent.SizeWhenDone += result.SizeWhenDone
torrent.LeftUntilDone += result.LeftUntilDone
torrent.Percent = torrent.progress()
torrent.Up = fmt.Sprintf("%7.1f", torrent.up/float64(KiB))
torrent.Down = fmt.Sprintf("%7.1f", torrent.down/float64(KiB))
torrent.UploadedEver += result.UploadedEver
torrent.Ratio = torrent.ratio()

if torrent.LeftUntilDone != 0 && torrent.down != 0 {
torrent.Eta = etastr(torrent.LeftUntilDone / int64(torrent.down))
}
}

// NewForTotal returns a Torrent used to store the totals.
func NewForTotal() *Torrent {
torrent := &Torrent{
Error: " ",
}

return torrent
}

// NewFrom takes a transmissionrpc Torrent and provides useful human readable fields.
func NewFrom(transmissionrpcTorrent *transmissionrpc.Torrent, conf *config.Config) *Torrent {
torrent := &Torrent{
original: transmissionrpcTorrent,
ID: *transmissionrpcTorrent.ID,
Name: *transmissionrpcTorrent.Name,
Size: *transmissionrpcTorrent.SizeWhenDone,
Status: *transmissionrpcTorrent.Status,
LeftUntilDone: *transmissionrpcTorrent.LeftUntilDone,
Error: " ",
original: transmissionrpcTorrent,
ID: strconv.FormatInt(*transmissionrpcTorrent.ID, 10),
Name: *transmissionrpcTorrent.Name,
SizeWhenDone: *transmissionrpcTorrent.SizeWhenDone,
Status: *transmissionrpcTorrent.Status,
LeftUntilDone: *transmissionrpcTorrent.LeftUntilDone,
RecheckProgress: *transmissionrpcTorrent.RecheckProgress,
UploadedEver: *transmissionrpcTorrent.UploadedEver,
Error: " ",
}

if *torrent.original.Error != 0 {
Expand All @@ -130,30 +180,42 @@ func NewFrom(transmissionrpcTorrent *transmissionrpc.Torrent, conf *config.Confi

torrent.Percent = torrent.progress()
torrent.Eta = torrent.eta()
torrent.Up = float64(*torrent.original.RateUpload) / float64(KiB)
torrent.Down = float64(*torrent.original.RateDownload) / float64(KiB)
torrent.up = float64(*torrent.original.RateUpload)
torrent.Up = fmt.Sprintf("%7.1f", torrent.up/float64(KiB))
torrent.down = float64(*torrent.original.RateDownload)
torrent.Down = fmt.Sprintf("%7.1f", torrent.down/float64(KiB))
torrent.Ratio = torrent.ratio()
torrent.Priority = torrent.priority()
torrent.Trackershortname = torrent.trackershortname(conf)

status := statusStr(*torrent)
if status != nil {
torrent.Up = *status
torrent.Down = *status
}

return torrent
}

// Torrent contains all the fields of transmissionrpc.Torrent but with non-pointer values
// useful for formatted output.
type Torrent struct {
ID int64
ID string
Error string
Name string
Percent float64
Size cunits.Bits
SizeWhenDone cunits.Bits
Eta string
Up float64
Down float64
up float64
Up string
down float64
Down string
Ratio float64
Priority string
Trackershortname string
LeftUntilDone int64
RecheckProgress float64
UploadedEver int64
Status transmissionrpc.TorrentStatus
original *transmissionrpc.Torrent
}

0 comments on commit 3d19c74

Please sign in to comment.