This commit is contained in:
Alexander
2026-04-29 17:29:58 +02:00
parent 3ecc6aee62
commit 945aab82c2
24 changed files with 2038 additions and 822 deletions
+145 -8
View File
@@ -2,6 +2,8 @@ package torrent
import (
"context"
"crypto/sha1"
"encoding/hex"
"fmt"
"os"
"sync"
@@ -11,19 +13,25 @@ import (
type StubClient struct {
logPath string
savePath string
mu sync.Mutex
mu sync.RWMutex
logMu sync.Mutex
torrents map[string]*TorrentInfo
}
func NewStubClient(logPath, savePath string) *StubClient {
return &StubClient{
logPath: logPath,
savePath: savePath,
torrents: make(map[string]*TorrentInfo),
}
}
func (c *StubClient) log(format string, args ...any) {
c.mu.Lock()
defer c.mu.Unlock()
if c.logPath == "" {
return
}
c.logMu.Lock()
defer c.logMu.Unlock()
f, err := os.OpenFile(c.logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
@@ -47,13 +55,29 @@ func (c *StubClient) Disconnect(ctx context.Context) error {
}
func (c *StubClient) ListTorrents(ctx context.Context) ([]TorrentInfo, error) {
c.log("LIST_TORRENTS")
return []TorrentInfo{}, nil
c.mu.RLock()
defer c.mu.RUnlock()
c.log("LIST_TORRENTS count=%d", len(c.torrents))
result := make([]TorrentInfo, 0, len(c.torrents))
for _, t := range c.torrents {
result = append(result, *t)
}
return result, nil
}
func (c *StubClient) GetTorrent(ctx context.Context, hash string) (*TorrentInfo, error) {
c.mu.RLock()
defer c.mu.RUnlock()
c.log("GET_TORRENT hash=%s", hash)
return nil, ErrTorrentNotFound
t, ok := c.torrents[hash]
if !ok {
return nil, ErrTorrentNotFound
}
return t, nil
}
func (c *StubClient) AddTorrentURL(ctx context.Context, url string, savePath *string) error {
@@ -61,7 +85,24 @@ func (c *StubClient) AddTorrentURL(ctx context.Context, url string, savePath *st
if savePath != nil {
path = *savePath
}
c.log("ADD_TORRENT_URL url=%s save_path=%s", url, path)
hash := generateHashFromURL(url)
name := "Torrent-" + hash[:8]
c.mu.Lock()
c.torrents[hash] = &TorrentInfo{
Hash: hash,
Name: name,
Size: 500 * 1024 * 1024,
Progress: 0,
DownloadSpeed: 0,
UploadSpeed: 0,
State: StateQueued,
SavePath: path,
}
c.mu.Unlock()
c.log("ADD_TORRENT_URL url=%s hash=%s save_path=%s", url, hash, path)
return nil
}
@@ -70,21 +111,117 @@ func (c *StubClient) AddTorrentFile(ctx context.Context, data []byte, savePath *
if savePath != nil {
path = *savePath
}
c.log("ADD_TORRENT_FILE size=%d save_path=%s", len(data), path)
hash := generateHashFromData(data)
name := "Torrent-" + hash[:8]
c.mu.Lock()
c.torrents[hash] = &TorrentInfo{
Hash: hash,
Name: name,
Size: uint64(len(data) * 100),
Progress: 0,
DownloadSpeed: 0,
UploadSpeed: 0,
State: StateQueued,
SavePath: path,
}
c.mu.Unlock()
c.log("ADD_TORRENT_FILE size=%d hash=%s save_path=%s", len(data), hash, path)
return nil
}
func (c *StubClient) RemoveTorrent(ctx context.Context, hash string, deleteFiles bool) error {
c.mu.Lock()
delete(c.torrents, hash)
c.mu.Unlock()
c.log("REMOVE_TORRENT hash=%s delete_files=%t", hash, deleteFiles)
return nil
}
func (c *StubClient) PauseTorrent(ctx context.Context, hash string) error {
c.mu.Lock()
if t, ok := c.torrents[hash]; ok {
t.State = StatePaused
t.DownloadSpeed = 0
}
c.mu.Unlock()
c.log("PAUSE_TORRENT hash=%s", hash)
return nil
}
func (c *StubClient) ResumeTorrent(ctx context.Context, hash string) error {
c.mu.Lock()
if t, ok := c.torrents[hash]; ok {
if t.Progress < 1.0 {
t.State = StateDownloading
} else {
t.State = StateSeeding
}
}
c.mu.Unlock()
c.log("RESUME_TORRENT hash=%s", hash)
return nil
}
func (c *StubClient) SetTorrentState(hash string, state TorrentState, progress float64) {
c.mu.Lock()
defer c.mu.Unlock()
if t, ok := c.torrents[hash]; ok {
t.State = state
t.Progress = progress
if state == StateSeeding {
t.Progress = 1.0
}
}
}
func (c *StubClient) SetTorrentName(hash, name string) {
c.mu.Lock()
defer c.mu.Unlock()
if t, ok := c.torrents[hash]; ok {
t.Name = name
}
}
func (c *StubClient) AddTorrentDirect(info TorrentInfo) {
c.mu.Lock()
defer c.mu.Unlock()
c.torrents[info.Hash] = &info
}
func (c *StubClient) Clear() {
c.mu.Lock()
defer c.mu.Unlock()
c.torrents = make(map[string]*TorrentInfo)
}
func (c *StubClient) GetAllTorrents() map[string]*TorrentInfo {
c.mu.RLock()
defer c.mu.RUnlock()
result := make(map[string]*TorrentInfo, len(c.torrents))
for k, v := range c.torrents {
copy := *v
result[k] = &copy
}
return result
}
func generateHashFromURL(url string) string {
h := sha1.New()
h.Write([]byte(url))
return hex.EncodeToString(h.Sum(nil))
}
func generateHashFromData(data []byte) string {
h := sha1.New()
h.Write(data)
return hex.EncodeToString(h.Sum(nil))
}