This commit is contained in:
firebadnofire 2025-05-04 13:30:55 -04:00
parent 4bbddc1579
commit 4a0d1a288b
Signed by: firebadnofire
SSH key fingerprint: SHA256:bnN1TGRauJN84CxL1IZ/2uHNvJualwYkFjOKaaOilJE

77
main.go
View file

@ -1,31 +1,47 @@
package main
import (
"context"
"flag"
"fmt"
"log"
"os"
"strings"
"path/filepath"
"regexp"
"time"
"github.com/anacrolix/torrent"
)
var invalidFilenameChars = regexp.MustCompile(`[<>:"/\\|?*\x00-\x1F]`)
// sanitizeFilename replaces invalid filesystem characters with underscores.
func sanitizeFilename(name string) string {
return invalidFilenameChars.ReplaceAllString(name, "_")
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: ./magnet-to-torrent \"magnet_link\" [output.torrent]")
// Command-line flags
output := flag.String("o", "", "Output .torrent filename (optional)")
timeout := flag.Duration("timeout", 5*time.Minute, "Timeout for metadata retrieval")
upload := flag.Bool("upload", false, "Allow uploading (seeding) after metadata retrieval")
flag.Usage = func() {
fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] magnet_link\nOptions:\n", os.Args[0])
flag.PrintDefaults()
}
flag.Parse()
if flag.NArg() < 1 {
flag.Usage()
os.Exit(1)
}
magnetLink := flag.Arg(0)
magnetLink := os.Args[1]
outputFile := ""
if len(os.Args) == 3 {
outputFile = os.Args[2]
}
// Configure torrent client
clientConfig := torrent.NewDefaultClientConfig()
clientConfig.DataDir = os.TempDir()
clientConfig.NoUpload = true
clientConfig.NoUpload = !*upload
client, err := torrent.NewClient(clientConfig)
if err != nil {
@ -33,35 +49,46 @@ func main() {
}
defer client.Close()
// Add magnet link
t, err := client.AddMagnet(magnetLink)
if err != nil {
log.Fatalf("Error adding magnet link: %v", err)
}
<-t.GotInfo()
info := t.Metainfo()
// Wait for metadata with timeout
ctx, cancel := context.WithTimeout(context.Background(), *timeout)
defer cancel()
if outputFile == "" {
outputFile = strings.ReplaceAll(t.Name(), " ", "_") + ".torrent"
select {
case <-t.GotInfo():
// Metadata received
case <-ctx.Done():
log.Fatalf("Timeout waiting for metadata after %v", *timeout)
}
f, err := os.Create(outputFile)
info := t.Metainfo()
// Determine output filename
outFile := *output
if outFile == "" {
base := sanitizeFilename(t.Name())
outFile = base + ".torrent"
}
outFile = filepath.Clean(outFile)
// Write .torrent file
f, err := os.Create(outFile)
if err != nil {
log.Fatalf("Error creating file: %v", err)
log.Fatalf("Error creating file %s: %v", outFile, err)
}
defer f.Close()
err = info.Write(f)
if err != nil {
if err := info.Write(f); err != nil {
log.Fatalf("Error writing torrent file: %v", err)
}
fmt.Printf("Torrent metadata saved to %s\n", outputFile)
fmt.Printf("Torrent metadata saved to %s\n", outFile)
// Drop the torrent handle; client will close via defer
t.Drop()
client.Close()
// Give client some time to gracefully close
time.Sleep(2 * time.Second)
}