Ztorrent/internal/app/controller.go

148 lines
2.7 KiB
Go

package app
import (
"context"
"encoding/hex"
"sync"
"time"
"github.com/veggiedefender/torrent-client/internal/config"
"github.com/veggiedefender/torrent-client/internal/history"
"github.com/veggiedefender/torrent-client/internal/tgbot"
"github.com/veggiedefender/torrent-client/internal/torrent"
)
type Controller struct {
mu sync.Mutex
engine *torrent.Engine
ctx context.Context
cancel context.CancelFunc
currentPath string
currentOut string
}
func NewController() *Controller {
engine := torrent.NewEngine()
ctx, cancel := context.WithCancel(context.Background())
return &Controller{
engine: engine,
ctx: ctx,
cancel: cancel,
}
}
func (c *Controller) StartTorrent(path, outputRoot string) error {
c.mu.Lock()
if c.cancel != nil {
c.cancel()
}
c.ctx, c.cancel = context.WithCancel(context.Background())
c.currentPath = path
c.currentOut = outputRoot
c.mu.Unlock()
err := c.engine.LoadTorrent(path, outputRoot)
if err != nil {
return err
}
c.updateHistory()
go func(ctx context.Context) {
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
c.updateHistory()
}
}
}(c.ctx)
return nil
}
func (c *Controller) StartTorrentDownload() {
c.engine.StartDownload()
}
func (c *Controller) DownloadMagnet(magnetURI string) error {
cfg, _ := config.Load()
outDir := "."
if cfg != nil && cfg.DefaultDir != "" {
outDir = cfg.DefaultDir
}
return c.StartTorrent(magnetURI, outDir)
}
func (c *Controller) InitTelegramBot(token string) error {
if token == "" {
return nil
}
bot, err := tgbot.NewBot(c, token)
if err != nil {
return err
}
if bot != nil {
bot.Start()
}
return nil
}
func (c *Controller) StopTorrent() {
c.mu.Lock()
if c.cancel != nil {
c.cancel()
}
c.mu.Unlock()
c.updateHistory()
c.engine.Stop()
}
func (c *Controller) updateHistory() {
status := c.engine.Status()
if status.Phase == "" {
return
}
hashHex := ""
if len(status.InfoHash) > 0 {
hashHex = hex.EncodeToString(status.InfoHash[:])
}
c.mu.Lock()
path := c.currentPath
out := c.currentOut
c.mu.Unlock()
hItem := history.Item{
InfoHash: hashHex,
Name: status.Name,
TorrentPath: path,
OutputDir: out,
Status: status.Phase,
Progress: c.engine.Progress() * 100, // store as percentage 0-100
Size: status.TotalBytes,
}
history.Update(hItem)
}
func (c *Controller) Progress() float64 {
return c.engine.Progress()
}
func (c *Controller) Status() torrent.Status {
if c.engine == nil {
return torrent.Status{}
}
return c.engine.Status()
}
func (c *Controller) ToggleFilePriority(fileIdx int) {
if c.engine != nil {
c.engine.ToggleFilePriority(fileIdx)
}
}