From 465255748e3f86e1cab5d66cbf0838cedc883201 Mon Sep 17 00:00:00 2001
From: Sergey Matveev <stargrave@stargrave.org>
Date: Mon, 28 Nov 2022 18:26:30 +0300
Subject: [PATCH] fifos/top-seed

---
 cmd/btrtrc/USAGE    |  1 +
 cmd/btrtrc/fifos.go | 42 ++++++++++++++++++++++++++++++++++++++++++
 cmd/btrtrc/main.go  |  1 +
 cmd/btrtrc/sort.go  | 14 ++++++++++++++
 4 files changed, 58 insertions(+)

diff --git a/cmd/btrtrc/USAGE b/cmd/btrtrc/USAGE
index 40d58782..8800d9b3 100644
--- a/cmd/btrtrc/USAGE
+++ b/cmd/btrtrc/USAGE
@@ -46,6 +46,7 @@ fifos subdirectory will be created with following FIFO files:
   * amount of downloaded/uploaded traffic during current session
   * remote address with port
   * client's name
+* fifos/top-seed -- list torrents sorted by total transfer data amount
 
 For each torrent, corresponding .torrent file will be created.
 Additional symbolic link with torrent's name will lead to HASH.torrent.
diff --git a/cmd/btrtrc/fifos.go b/cmd/btrtrc/fifos.go
index cb6139c8..c7466926 100644
--- a/cmd/btrtrc/fifos.go
+++ b/cmd/btrtrc/fifos.go
@@ -223,6 +223,47 @@ func fifoDHTList(c *torrent.Client) {
 	}
 }
 
+type topTorrent struct {
+	infoHash metainfo.Hash
+	name     string
+	tx       int64
+}
+
+func fifoTopSeed(c *torrent.Client) {
+	pth := path.Join(FIFOsDir, "top-seed")
+	recreateFIFO(pth)
+	for {
+		fd, err := os.OpenFile(pth, os.O_WRONLY|os.O_APPEND, os.FileMode(0666))
+		if err != nil {
+			log.Println("OpenFile:", pth, err)
+			time.Sleep(time.Second)
+			continue
+		}
+		var ts []*topTorrent
+		for _, t := range c.Torrents() {
+			if t.Info() == nil {
+				continue
+			}
+			ts = append(ts, &topTorrent{
+				infoHash: t.InfoHash(),
+				name:     t.Name(),
+				tx:       TxStats[t.InfoHash()],
+			})
+		}
+		sort.Sort(ByTxTraffic(ts))
+		for _, t := range ts {
+			fmt.Fprintf(fd,
+				"%s%s%s %s%40s%s %s\n",
+				Blue, t.infoHash.HexString(), Reset,
+				Green, shortenName(t.name), Reset,
+				humanize.IBytes(uint64(t.tx)),
+			)
+		}
+		fd.Close()
+		time.Sleep(time.Second)
+	}
+}
+
 type stringAddr string
 
 func (stringAddr) Network() string   { return "" }
@@ -358,6 +399,7 @@ func fifosCleanup() {
 	os.Remove(path.Join(FIFOsDir, "dht"))
 	os.Remove(path.Join(FIFOsDir, "add"))
 	os.Remove(path.Join(FIFOsDir, "del"))
+	os.Remove(path.Join(FIFOsDir, "top-seed"))
 	os.RemoveAll(path.Join(FIFOsDir, PeersDir))
 	os.RemoveAll(path.Join(FIFOsDir, FilesDir))
 }
diff --git a/cmd/btrtrc/main.go b/cmd/btrtrc/main.go
index 880348be..63e6c4ff 100644
--- a/cmd/btrtrc/main.go
+++ b/cmd/btrtrc/main.go
@@ -81,6 +81,7 @@ func main() {
 	Jobs.Add(1)
 	go overallStatus(client)
 	go fifoList(client)
+	go fifoTopSeed(client)
 	go fifoDHTList(client)
 	go fifoAdd(client)
 	go fifoDel(client)
diff --git a/cmd/btrtrc/sort.go b/cmd/btrtrc/sort.go
index cfb6478c..5b1ad858 100644
--- a/cmd/btrtrc/sort.go
+++ b/cmd/btrtrc/sort.go
@@ -20,6 +20,20 @@ func (a ByInfoHash) Less(i, j int) bool {
 	return a[i].InfoHash().HexString() < a[j].InfoHash().HexString()
 }
 
+type ByTxTraffic []*topTorrent
+
+func (a ByTxTraffic) Len() int {
+	return len(a)
+}
+
+func (a ByTxTraffic) Swap(i, j int) {
+	a[i], a[j] = a[j], a[i]
+}
+
+func (a ByTxTraffic) Less(i, j int) bool {
+	return a[i].tx < a[j].tx
+}
+
 type ByPeerID []*torrent.PeerConn
 
 func (a ByPeerID) Len() int {
-- 
2.51.0