]> Sergey Matveev's repositories - btrtrc.git/blob - cmd/torrent/serve.go
Track latest bargle
[btrtrc.git] / cmd / torrent / serve.go
1 package main
2
3 import (
4         "fmt"
5         "net/http"
6         "path/filepath"
7
8         "github.com/anacrolix/bargle"
9         "github.com/anacrolix/log"
10         "github.com/anacrolix/torrent"
11         "github.com/anacrolix/torrent/bencode"
12         "github.com/anacrolix/torrent/metainfo"
13         "github.com/anacrolix/torrent/storage"
14 )
15
16 func serve() (cmd bargle.Command) {
17         filePath := &bargle.Positional[string]{}
18         cmd.Positionals = append(cmd.Positionals, filePath)
19         cmd.DefaultAction = func() error {
20                 cfg := torrent.NewDefaultClientConfig()
21                 cfg.Seed = true
22                 cl, err := torrent.NewClient(cfg)
23                 if err != nil {
24                         return fmt.Errorf("new torrent client: %w", err)
25                 }
26                 defer cl.Close()
27                 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
28                         cl.WriteStatus(w)
29                 })
30                 totalLength, err := totalLength(filePath)
31                 if err != nil {
32                         return fmt.Errorf("calculating total length of %q: %v", filePath, err)
33                 }
34                 pieceLength := metainfo.ChoosePieceLength(totalLength)
35                 info := metainfo.Info{
36                         PieceLength: pieceLength,
37                 }
38                 err = info.BuildFromFilePath(filePath.Value)
39                 if err != nil {
40                         return fmt.Errorf("building info from path %q: %w", filePath.Value, err)
41                 }
42                 for _, fi := range info.Files {
43                         log.Printf("added %q", fi.Path)
44                 }
45                 mi := metainfo.MetaInfo{
46                         InfoBytes: bencode.MustMarshal(info),
47                 }
48                 pc, err := storage.NewDefaultPieceCompletionForDir(".")
49                 if err != nil {
50                         return fmt.Errorf("new piece completion: %w", err)
51                 }
52                 defer pc.Close()
53                 ih := mi.HashInfoBytes()
54                 to, _ := cl.AddTorrentOpt(torrent.AddTorrentOpts{
55                         InfoHash: ih,
56                         Storage: storage.NewFileOpts(storage.NewFileClientOpts{
57                                 ClientBaseDir: filePath.Value,
58                                 FilePathMaker: func(opts storage.FilePathMakerOpts) string {
59                                         return filepath.Join(opts.File.Path...)
60                                 },
61                                 TorrentDirMaker: nil,
62                                 PieceCompletion: pc,
63                         }),
64                 })
65                 defer to.Drop()
66                 err = to.MergeSpec(&torrent.TorrentSpec{
67                         InfoBytes: mi.InfoBytes,
68                         Trackers: [][]string{{
69                                 `wss://tracker.btorrent.xyz`,
70                                 `wss://tracker.openwebtorrent.com`,
71                                 "http://p4p.arenabg.com:1337/announce",
72                                 "udp://tracker.opentrackr.org:1337/announce",
73                                 "udp://tracker.openbittorrent.com:6969/announce",
74                         }},
75                 })
76                 if err != nil {
77                         return fmt.Errorf("setting trackers: %w", err)
78                 }
79                 fmt.Printf("%v: %v\n", to, to.Metainfo().Magnet(&ih, &info))
80                 select {}
81         }
82         return
83 }