package main import ( "fmt" "log" "os" "path" "strconv" "sync" "time" "github.com/anacrolix/torrent" "github.com/anacrolix/torrent/metainfo" ) const TxExt = ".tx" var ( TxStats = map[metainfo.Hash]int64{} TxStatsM sync.Mutex TxsDir string ) func txStatsLoad(h metainfo.Hash) { pth := path.Join(TxsDir, h.HexString()+TxExt) data, err := os.ReadFile(pth) if err != nil { return } if len(data) == 0 { return } v, err := strconv.ParseInt(string(data[:len(data)-1]), 10, 64) if err != nil { log.Println("ParseInt:", pth, err) return } TxStatsM.Lock() TxStats[h] = v TxStatsM.Unlock() } func txStatsDel(h metainfo.Hash) { TxStatsM.Lock() delete(TxStats, h) TxStatsM.Unlock() } func txStatsDump(t *torrent.Torrent) { stats := t.Stats() TxStatsM.Lock() s := stats.BytesWrittenData.Int64() + TxStats[t.InfoHash()] pth := path.Join(TxsDir, t.InfoHash().HexString()+TxExt) if err := os.WriteFile(pth, []byte(fmt.Sprintf("%d\n", s)), 0666); err != nil { log.Println("WriteFile:", pth, err) } TxStatsM.Unlock() } func txStatsDumpAll(c *torrent.Client) { for _, t := range c.Torrents() { if t.Info() != nil { txStatsDump(t) } } } func txStatsDumper(c *torrent.Client) { tick := time.Tick(10 * time.Second) for { txStatsDumpAll(c) select { case <-Cancel: Jobs.Done() return case <-tick: } } }