filebrowser/torrent/torrent.go
2025-01-15 09:59:41 +08:00

156 lines
3.8 KiB
Go

package torrent
import (
"fmt"
"io"
"net/http"
"os/exec"
"strings"
"github.com/filebrowser/filebrowser/v2/files"
"github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/users"
)
type Torrent struct {
*settings.Settings
*users.User
}
func (t *Torrent) MakeTorrent(file *files.FileInfo, body users.CreateTorrentBody) error {
fPath := file.RealPath()
tPath := fPath + ".torrent"
// 设置 mktorrent 命令的选项
opts := &TorrentOptions{
Target: fPath,
Announces: body.Announces,
Comment: body.Comment,
Date: body.Date,
Name: body.Name,
OutputFile: tPath,
PieceLen: body.PieceLen,
Private: body.Private,
Source: body.Source,
WebSeeds: body.WebSeeds,
}
// 上传到 R2
if body.R2 {
// var bucketName = "moezakura"
// var accountId = "6a59886e546396fc9076ec50764dc9f3"
// var accessKeyId = "d65f9e3347d046e0583a8d846aa8cb46"
// var accessKeySecret = "a8a57f4d1525eada05f7e553815a89c4da0a3b28745eaddea89e4c52334f056e"
var accountId = t.Settings.Torrent.AccountId
var accessKeyId = t.Settings.Torrent.AccountKeyId
var accessKeySecret = t.Settings.Torrent.AccountKeySecret
var bucketName = t.Settings.Torrent.Bucket
// will only be called once
InitializeClient(accountId, accessKeyId, accessKeySecret)
// remove first slash
var key = file.Path[1:]
sigc := make(chan string)
go uploadHandler(bucketName, key, fPath, sigc)
// result := <-sigc
// fmt.Println(result)
// join domain and key to url
// eg: domain: download.moezakura.click, key: test.txt
// url: https://download.moezakura.click/test.txt
var url = "https://" + t.Torrent.Domain + "/" + key
opts.WebSeeds = append(opts.WebSeeds, url)
}
// 调用 mktorrent 命令
args := buildArgs(opts)
cmd := exec.Command("mktorrent", args...)
err := cmd.Run()
if err != nil {
return err
}
return nil
}
func (t *Torrent) PublishTorrent(torrentPath string, savePath string) error {
qbURL := t.Settings.Torrent.QbUrl
username := t.Settings.Torrent.QbUsername
password := t.Settings.Torrent.QbPassword
client := &http.Client{}
sid, err := login(client, qbURL, username, password)
if err != nil {
return fmt.Errorf("failed to login: %v", err)
}
err = addTorrent(client, qbURL, sid, torrentPath, savePath)
if err != nil {
return fmt.Errorf("failed to add torrent: %v", err)
}
return nil
}
func (t *Torrent) GetDefaultCreateBody(createBody users.CreateTorrentBody) (*users.CreateTorrentBody, error) {
announces, err := fetchTrackerList(t.Settings.Torrent.TrackersListUrl)
if err != nil {
return nil, fmt.Errorf("failed to fetch tracker list: %v", err)
}
if createBody.Announces == nil {
createBody.Announces = []string{}
}
if createBody.WebSeeds == nil {
createBody.WebSeeds = []string{}
}
return &users.CreateTorrentBody{
Announces: announces,
Comment: createBody.Comment,
Date: createBody.Date,
Name: "",
PieceLen: createBody.PieceLen,
Private: createBody.Private,
Source: createBody.Source,
WebSeeds: createBody.WebSeeds,
}, nil
}
func fetchTrackerList(url string) ([]string, error) {
// 发送HTTP GET请求
response, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("failed to fetch trackers: %v", err)
}
defer response.Body.Close()
// 检查响应状态
if response.StatusCode != http.StatusOK {
return nil, fmt.Errorf("failed to fetch trackers: status code %d", response.StatusCode)
}
// 读取响应体
body, err := io.ReadAll(response.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response body: %v", err)
}
// 移除空行
text := string(body)
text = strings.TrimSpace(text)
lines := strings.Split(text, "\n")
var filteredLines []string
for _, line := range lines {
if strings.TrimSpace(line) != "" {
filteredLines = append(filteredLines, line)
}
}
return filteredLines, nil
}