Skip to content

Commit

Permalink
improve torrents list output style
Browse files Browse the repository at this point in the history
  • Loading branch information
sagan committed Feb 20, 2024
1 parent 7a219f7 commit 862a575
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 56 deletions.
57 changes: 40 additions & 17 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package client

import (
"fmt"
"os"
"regexp"
"slices"
"strings"
"sync"

log "github.com/sirupsen/logrus"
"golang.org/x/term"

"github.com/sagan/ptool/config"
"github.com/sagan/ptool/util"
Expand Down Expand Up @@ -372,11 +374,13 @@ func PrintTorrentFiles(files []TorrentContentFile, showRaw bool) {
if showRaw {
fmt.Printf("%-5d %-5d %-10d %-5s %s\n", i+1, file.Index, file.Size, isDone, file.Path)
} else {
fmt.Printf("%-5d %-5d %-10s %-5s %s\n", i+1, file.Index, util.BytesSize(float64(file.Size)), isDone, file.Path)
fmt.Printf("%-5d %-5d %-10s %-5s %s\n",
i+1, file.Index, util.BytesSize(float64(file.Size)), isDone, file.Path)
}
}
if ignoredFilesCnt > 0 {
fmt.Printf("// Note: some files (marked with -) are ignored (not_download). Download / Ignore / All files: %d / %d / %d\n",
fmt.Printf("// Note: some files (marked with -) are ignored (not_download). "+
"Download / Ignore / All files: %d / %d / %d\n",
len(files)-int(ignoredFilesCnt), ignoredFilesCnt, len(files))
}
}
Expand Down Expand Up @@ -412,13 +416,20 @@ func PrintTorrent(torrent *Torrent) {
}

// showSum: 0 - no; 1 - yes; 2 - sum only
func PrintTorrents(torrents []Torrent, filter string, showSum int64) {
func PrintTorrents(torrents []Torrent, filter string, showSum int64, dense bool) {
width, _, _ := term.GetSize(int(os.Stdout.Fd()))
if width < config.CLIENT_TORRENTS_WIDTH {
width = config.CLIENT_TORRENTS_WIDTH
}
widthExcludingName := 109 // 40+6+5+6+6+5+5+20+8*2
widthName := width - widthExcludingName
cnt := int64(0)
var cntPaused, cntDownloading, cntSeeding, cntCompleted, cntOthers int64
size := int64(0)
sizeUnfinished := int64(0)
if showSum < 2 {
fmt.Printf("%-25s %-40s %-8s %-5s %-8s %-8s %-5s %-5s %-20s\n", "Name", "InfoHash", "Size", "State", "↓S(/s)", "↑S(/s)", "Seeds", "Peers", "Tracker")
fmt.Printf("%-*s %-40s %-6s %-5s %-6s %-6s %-5s %-5s %-20s\n",
widthName, "Name", "InfoHash", "Size", "State", "↓S(/s)", "↑S(/s)", "Seeds", "Peers", "Tracker")
}
for _, torrent := range torrents {
if filter != "" && !util.ContainsI(torrent.Name, filter) && !util.ContainsI(torrent.InfoHash, filter) {
Expand All @@ -439,22 +450,34 @@ func PrintTorrents(torrents []Torrent, filter string, showSum int64) {
}
size += torrent.Size
sizeUnfinished += torrent.Size - torrent.SizeCompleted
if showSum < 2 {
util.PrintStringInWidth(torrent.Name, 25, true)
fmt.Printf(" %-40s %-8s %-5s %-8s %-8s %-5d %-5d %-20s\n",
torrent.InfoHash,
util.BytesSize(float64(torrent.Size)),
torrent.StateIconText(),
util.BytesSize(float64(torrent.DownloadSpeed)),
util.BytesSize(float64(torrent.UploadSpeed)),
torrent.Seeders,
torrent.Leechers,
torrent.TrackerDomain,
)
if showSum >= 2 {
continue
}
remain := util.PrintStringInWidth(torrent.Name, int64(widthName), true)
fmt.Printf(" %-40s %-6s %-5s %-6s %-6s %-5d %-5d %-20s\n",
torrent.InfoHash,
util.BytesSizeAround(float64(torrent.Size)),
torrent.StateIconText(),
util.BytesSizeAround(float64(torrent.DownloadSpeed)),
util.BytesSizeAround(float64(torrent.UploadSpeed)),
torrent.Seeders,
torrent.Leechers,
torrent.TrackerDomain,
)
if dense {
for {
remain = strings.TrimSpace(remain)
if remain == "" {
break
}
remain = util.PrintStringInWidth(remain, int64(widthName), true)
fmt.Printf("\n")
}
}
}
if showSum > 0 {
fmt.Printf("// Summary - Cnt / Size / SizeUnfinished: %d / %s / %s\n", cnt, util.BytesSize(float64(size)), util.BytesSize(float64(sizeUnfinished)))
fmt.Printf("// Summary - Cnt / Size / SizeUnfinished: %d / %s / %s\n",
cnt, util.BytesSize(float64(size)), util.BytesSize(float64(sizeUnfinished)))
fmt.Printf("// Torrents: ↓%d / -%d / ↑%d / ✓%d / +%d\n",
cntDownloading, cntPaused, cntSeeding, cntCompleted, cntOthers)
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/delete/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func delete(cmd *cobra.Command, args []string) error {
})
}
if !force {
client.PrintTorrents(torrents, "", 1)
client.PrintTorrents(torrents, "", 1, false)
fmt.Printf("\n")
if !util.AskYesNoConfirm(fmt.Sprintf("Above %d torrents will be deteled (Preserve disk files = %t)",
len(torrents), preserve)) {
Expand Down
29 changes: 23 additions & 6 deletions cmd/search/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,31 @@ var (
maxResults = int64(0)
perSiteMaxResults = int64(0)
baseUrl = ""
minTorrentSizeStr = ""
maxTorrentSizeStr = ""
)

func init() {
command.Flags().BoolVarP(&dense, "dense", "", false, "Dense mode: show full torrent title & subtitle")
command.Flags().BoolVarP(&largestFlag, "largest", "l", false, "Sort search result by torrent size in desc order")
command.Flags().BoolVarP(&newestFlag, "newest", "n", false, "Sort search result by torrent time in desc order")
command.Flags().BoolVarP(&showJson, "json", "", false, "Show output in json format")
command.Flags().Int64VarP(&maxResults, "max-results", "", 100, "Number limit of search result of all sites combined. -1 == no limit")
command.Flags().Int64VarP(&perSiteMaxResults, "per-site-max-results", "", -1, "Number limit of search result of any single site. -1 == no limit")
command.Flags().StringVarP(&baseUrl, "base-url", "", "", "Manually set the base url of search page. e.g.: adult.php, special.php")
command.Flags().Int64VarP(&maxResults, "max-results", "", 100,
"Number limit of search result of all sites combined. -1 == no limit")
command.Flags().Int64VarP(&perSiteMaxResults, "per-site-max-results", "", -1,
"Number limit of search result of any single site. -1 == no limit")
command.Flags().StringVarP(&baseUrl, "base-url", "", "",
"Manually set the base url of search page. e.g.: adult.php, special.php")
command.Flags().StringVarP(&minTorrentSizeStr, "min-torrent-size", "", "-1",
"Skip torrent with size smaller than (<) this value. -1 == no limit")
command.Flags().StringVarP(&maxTorrentSizeStr, "max-torrent-size", "", "-1",
"Skip torrent with size larger than (>) this value. -1 == no limit")
cmd.RootCmd.AddCommand(command)
}

func search(cmd *cobra.Command, args []string) error {
minTorrentSize, _ := util.RAMInBytes(minTorrentSizeStr)
maxTorrentSize, _ := util.RAMInBytes(maxTorrentSizeStr)
sitenames := config.ParseGroupAndOtherNames(strings.Split(args[0], ",")...)
keyword := strings.Join(args[1:], " ")
siteInstancesMap := map[string]site.Site{}
Expand Down Expand Up @@ -98,7 +109,13 @@ func search(cmd *cobra.Command, args []string) error {
if perSiteMaxResults >= 0 && len(siteTorrents) > int(perSiteMaxResults) {
siteTorrents = siteTorrents[:perSiteMaxResults]
}
torrents = append(torrents, siteTorrents...)
for _, torrent := range siteTorrents {
if minTorrentSize > 0 && torrent.Size < minTorrentSize ||
maxTorrentSize > 0 && torrent.Size > maxTorrentSize {
continue
}
torrents = append(torrents, torrent)
}
}
}
if largestFlag {
Expand Down Expand Up @@ -134,8 +151,8 @@ func search(cmd *cobra.Command, args []string) error {
fmt.Println(string(bytes))
return nil
}
fmt.Printf("Done searching %d sites. Success / NoResult / Error sites: %d / %d / %d. Showing %d result\n", cntSuccessSites+cntErrorSites+cntNoResultSites,
cntSuccessSites, cntNoResultSites, cntErrorSites, len(torrents))
fmt.Printf("Done searching %d sites. Success / NoResult / Error sites: %d / %d / %d. Showing %d result\n",
cntSuccessSites+cntErrorSites+cntNoResultSites, cntSuccessSites, cntNoResultSites, cntErrorSites, len(torrents))
if errorStr != "" {
log.Warnf("Errors encountered: %s", errorStr)
}
Expand Down
22 changes: 15 additions & 7 deletions cmd/show/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var (
tracker = ""
minTorrentSizeStr = ""
maxTorrentSizeStr = ""
dense = false
showAll = false
showRaw = false
showJson = false
Expand All @@ -48,8 +49,11 @@ var (
)

func init() {
command.Flags().Int64VarP(&maxTorrents, "max-torrents", "", -1, "Show at most this number of torrents. -1 == no limit")
command.Flags().BoolVarP(&largestFlag, "largest", "l", false, "Show largest torrents first. Equavalent with '--sort size --order desc'")
command.Flags().Int64VarP(&maxTorrents, "max-torrents", "", -1,
"Show at most this number of torrents. -1 == no limit")
command.Flags().BoolVarP(&dense, "dense", "", false, "Dense mode: show full torrent title & subtitle")
command.Flags().BoolVarP(&largestFlag, "largest", "l", false,
"Show largest torrents first. Equavalent with '--sort size --order desc'")
command.Flags().BoolVarP(&showAll, "all", "a", false, "Show all torrents. Equavalent with pass a '_all' arg")
command.Flags().BoolVarP(&showRaw, "raw", "", false, "Show torrent size in raw format")
command.Flags().BoolVarP(&showJson, "json", "", false, "Show output in json format")
Expand All @@ -59,10 +63,13 @@ func init() {
command.Flags().BoolVarP(&showFiles, "show-files", "", false, "Show torrent content files info")
command.Flags().StringVarP(&filter, "filter", "", "", "Filter torrents by name")
command.Flags().StringVarP(&category, "category", "", "", "Filter torrents by category")
command.Flags().StringVarP(&tag, "tag", "", "", "Filter torrents by tag. Comma-separated string list. Torrent which tags contain any one in the list will match")
command.Flags().StringVarP(&tag, "tag", "", "",
"Filter torrents by tag. Comma-separated string list. Torrent which tags contain any one in the list match")
command.Flags().StringVarP(&tracker, "tracker", "", "", "Filter torrents by tracker domain")
command.Flags().StringVarP(&minTorrentSizeStr, "min-torrent-size", "", "-1", "Skip torrent with size smaller than (<) this value. -1 == no limit")
command.Flags().StringVarP(&maxTorrentSizeStr, "max-torrent-size", "", "-1", "Skip torrent with size larger than (>) this value. -1 == no limit")
command.Flags().StringVarP(&minTorrentSizeStr, "min-torrent-size", "", "-1",
"Skip torrent with size smaller than (<) this value. -1 == no limit")
command.Flags().StringVarP(&maxTorrentSizeStr, "max-torrent-size", "", "-1",
"Skip torrent with size larger than (>) this value. -1 == no limit")
cmd.AddEnumFlagP(command, &sortFlag, "sort", "", common.ClientTorrentSortFlag)
cmd.AddEnumFlagP(command, &orderFlag, "order", "", common.OrderFlag)
cmd.RootCmd.AddCommand(command)
Expand Down Expand Up @@ -92,7 +99,8 @@ func show(cmd *cobra.Command, args []string) error {
minTorrentSize, _ := util.RAMInBytes(minTorrentSizeStr)
maxTorrentSize, _ := util.RAMInBytes(maxTorrentSizeStr)

noConditionFlags := category == "" && tag == "" && filter == "" && tracker == "" && minTorrentSize < 0 && maxTorrentSize < 0
noConditionFlags := category == "" && tag == "" && filter == "" && tracker == "" &&
minTorrentSize < 0 && maxTorrentSize < 0
var torrents []client.Torrent
if showAll {
torrents, err = client.QueryTorrents(clientInstance, "", "", "")
Expand Down Expand Up @@ -217,7 +225,7 @@ func show(cmd *cobra.Command, args []string) error {
if showSum {
showSummary = 2
}
client.PrintTorrents(torrents, "", showSummary)
client.PrintTorrents(torrents, "", showSummary, dense)
} else {
for i, torrent := range torrents {
if i > 0 {
Expand Down
13 changes: 13 additions & 0 deletions cmd/status/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package status

import (
"fmt"
"sort"

"github.com/sagan/ptool/client"
"github.com/sagan/ptool/cmd/brush/strategy"
Expand Down Expand Up @@ -35,6 +36,18 @@ func fetchClientStatus(clientInstance client.Client, showTorrents bool, showAllT

if showTorrents {
clientTorrents, err := clientInstance.GetTorrents("", category, showAllTorrents)
if showAllTorrents {
sort.Slice(clientTorrents, func(i, j int) bool {
if clientTorrents[i].Name != clientTorrents[j].Name {
return clientTorrents[i].Name < clientTorrents[j].Name
}
return clientTorrents[i].InfoHash < clientTorrents[j].InfoHash
})
} else {
sort.Slice(clientTorrents, func(i, j int) bool {
return clientTorrents[i].Atime > clientTorrents[j].Atime
})
}
response.ClientTorrents = clientTorrents
if err != nil {
response.Error = fmt.Errorf("cann't get client %s torrents: %v", clientInstance.GetName(), err)
Expand Down
8 changes: 5 additions & 3 deletions cmd/status/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ func init() {
command.Flags().BoolVarP(&showAll, "all", "a", false, "Show all clients and sites")
command.Flags().BoolVarP(&showAllClients, "clients", "c", false, "Show all clients")
command.Flags().BoolVarP(&showAllSites, "sites", "s", false, "Show all sites")
command.Flags().BoolVarP(&showTorrents, "torrents", "t", false, "Show torrents (active torrents for client / latest torrents for site)")
command.Flags().BoolVarP(&showTorrents, "torrents", "t", false,
"Show torrents (active torrents for client / latest torrents for site)")
command.Flags().BoolVarP(&showFull, "full", "f", false, "Show full info of each client or site")
command.Flags().BoolVarP(&showScore, "score", "", false, "Show brush score of site torrents")
command.Flags().BoolVarP(&largestFlag, "largest", "l", false, `Sort site torrents by size in desc order"`)
command.Flags().BoolVarP(&newestFlag, "newest", "n", false, `Sort site torrents by time in desc order (newest first)"`)
command.Flags().BoolVarP(&newestFlag, "newest", "n", false,
`Sort site torrents by time in desc order (newest first)"`)
cmd.RootCmd.AddCommand(command)
}

Expand Down Expand Up @@ -167,7 +169,7 @@ func status(cmd *cobra.Command, args []string) error {
}
if response.ClientTorrents != nil {
fmt.Printf("\n")
client.PrintTorrents(response.ClientTorrents, filter, 0)
client.PrintTorrents(response.ClientTorrents, filter, 0, dense)
if i != len(responses)-1 {
fmt.Printf("\n")
}
Expand Down
14 changes: 8 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ import (
)

const (
BRUSH_CAT = "_brush"
XSEED_TAG = "_xseed"
NOADD_TAG = "_noadd"
NOXSEED_TAG = "noxseed" // BT 客户端里含有此 tag 的种子不会被辅种
STATS_FILENAME = "ptool_stats.txt"
HISTORY_FILENAME = "ptool_history"
BRUSH_CAT = "_brush"
XSEED_TAG = "_xseed"
NOADD_TAG = "_noadd"
NOXSEED_TAG = "noxseed" // BT 客户端里含有此 tag 的种子不会被辅种
STATS_FILENAME = "ptool_stats.txt"
HISTORY_FILENAME = "ptool_history"
SITE_TORRENTS_WIDTH = 120 // min width for printing site torrents
CLIENT_TORRENTS_WIDTH = 120 // min width for printing client torrents

DEFAULT_IYUU_DOMAIN = "api.iyuu.cn"
DEFAULT_TIMEOUT = int64(5)
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ require (
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/term v0.17.0
golang.org/x/text v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -396,14 +396,16 @@ golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Expand Down

0 comments on commit 862a575

Please sign in to comment.