// NewClient creates a new torrent client based on a magnet or a torrent file. // If the torrent file is on http, we try downloading it. func NewClient(torrentPath string, port int, seed bool) (client Client, err error) { var t torrent.Torrent var c *torrent.Client client.Port = port // Create client. c, err = torrent.NewClient(&torrent.Config{ DataDir: os.TempDir(), NoUpload: !seed, Seed: seed, }) if err != nil { return client, ClientError{Type: "creating torrent client", Origin: err} } client.Client = c // Add torrent. // Add as magnet url. if strings.HasPrefix(torrentPath, "magnet:") { if t, err = c.AddMagnet(torrentPath); err != nil { return client, ClientError{Type: "adding torrent", Origin: err} } } else { // Otherwise add as a torrent file. // If it's online, we try downloading the file. if isHTTP.MatchString(torrentPath) { if torrentPath, err = downloadFile(torrentPath); err != nil { return client, ClientError{Type: "downloading torrent file", Origin: err} } } // Check if the file exists. if _, err = os.Stat(torrentPath); err != nil { return client, ClientError{Type: "file not found", Origin: err} } if t, err = c.AddTorrentFromFile(torrentPath); err != nil { return client, ClientError{Type: "adding torrent to the client", Origin: err} } } client.Torrent = t go func() { <-t.GotInfo() t.DownloadAll() // Prioritize first 5% of the file. client.getLargestFile().PrioritizeRegion(0, int64(t.NumPieces()/100*5)) }() go client.addBlocklist() return }
func torrentBar(t *torrent.Torrent) { bar := uiprogress.AddBar(1) bar.AppendCompleted() bar.AppendFunc(func(*uiprogress.Bar) (ret string) { select { case <-t.GotInfo(): default: return "getting info" } if t.Seeding() { return "seeding" } else if t.BytesCompleted() == t.Info().TotalLength() { return "completed" } else { return fmt.Sprintf("downloading (%s/%s)", humanize.Bytes(uint64(t.BytesCompleted())), humanize.Bytes(uint64(t.Info().TotalLength()))) } }) bar.PrependFunc(func(*uiprogress.Bar) string { return t.Name() }) go func() { <-t.GotInfo() bar.Total = int(t.Info().TotalLength()) for { bc := t.BytesCompleted() bar.Set(int(bc)) time.Sleep(time.Second) } }() }
// NewClient creates a new torrent client based on a magnet or a torrent file. // If the torrent file is on http, we try downloading it. func NewClient(cfg ClientConfig) (client Client, err error) { var t *torrent.Torrent var c *torrent.Client client.Config = cfg // Create client. c, err = torrent.NewClient(&torrent.Config{ DataDir: os.TempDir(), NoUpload: !cfg.Seed, Seed: cfg.Seed, DisableTCP: !cfg.TCP, ListenAddr: fmt.Sprintf(":%d", cfg.TorrentPort), }) if err != nil { return client, ClientError{Type: "creating torrent client", Origin: err} } client.Client = c // Add torrent. // Add as magnet url. if strings.HasPrefix(cfg.TorrentPath, "magnet:") { if t, err = c.AddMagnet(cfg.TorrentPath); err != nil { return client, ClientError{Type: "adding torrent", Origin: err} } } else { // Otherwise add as a torrent file. // If it's online, we try downloading the file. if isHTTP.MatchString(cfg.TorrentPath) { if cfg.TorrentPath, err = downloadFile(cfg.TorrentPath); err != nil { return client, ClientError{Type: "downloading torrent file", Origin: err} } } if t, err = c.AddTorrentFromFile(cfg.TorrentPath); err != nil { return client, ClientError{Type: "adding torrent to the client", Origin: err} } } client.Torrent = t client.Torrent.SetMaxEstablishedConns(cfg.MaxConnections) go func() { <-t.GotInfo() t.DownloadAll() // Prioritize first 5% of the file. client.getLargestFile().PrioritizeRegion(0, int64(t.NumPieces()/100*5)) }() go client.addBlocklist() return }
// NewClient creates a new torrent client based on a magnet or a torrent file. // If the torrent file is on http, we try downloading it. func NewClient(torrentPath string) (client Client, err error) { var t torrent.Torrent var c *torrent.Client // Create client. c, err = torrent.NewClient(&torrent.Config{ DataDir: os.TempDir(), NoUpload: !(*seed), }) if err != nil { return client, ClientError{Type: "creating torrent client", Origin: err} } client.Client = c // Add torrent. // Add as magnet url. if strings.HasPrefix(torrentPath, "magnet:") { if t, err = c.AddMagnet(torrentPath); err != nil { return client, ClientError{Type: "adding torrent", Origin: err} } } else { // Otherwise add as a torrent file. // If it's online, we try downloading the file. if isHTTP.MatchString(torrentPath) { if torrentPath, err = downloadFile(torrentPath); err != nil { return client, ClientError{Type: "downloading torrent file", Origin: err} } } // Check if the file exists. if _, err = os.Stat(torrentPath); err != nil { return client, ClientError{Type: "file not found", Origin: err} } if t, err = c.AddTorrentFromFile(torrentPath); err != nil { return client, ClientError{Type: "adding torrent to the client", Origin: err} } } client.Torrent = t go func() { <-t.GotInfo() t.DownloadAll() }() return }
func (c *Client) NewTorrent(torrentPath string) (error, chan bool) { c.DropTorrent() c.Ready = false c.TorrentPath = torrentPath readyChan := make(chan bool) var t *torrent.Torrent client := c.Client // Add as magnet url. var err error if strings.HasPrefix(torrentPath, "magnet:") { if t, err = client.AddMagnet(torrentPath); err != nil { return ClientError{Type: "adding torrent", Origin: err}, nil } } else { // Otherwise add as a torrent file. // Check if the file exists. if _, err = os.Stat(torrentPath); err != nil { return ClientError{Type: "file not found", Origin: err}, nil } if t, err = client.AddTorrentFromFile(torrentPath); err != nil { return ClientError{Type: "adding torrent to the client", Origin: err}, nil } } go func() { // Wait for the torrent info and start to download immediately <-t.GotInfo() c.Ready = true // Publish torrent info readyChan <- true }() return nil, readyChan }
// Add Torrent/Magnet func add(w http.ResponseWriter, r *http.Request) { c := Add{} if e := json.NewDecoder(r.Body).Decode(&c); e != nil { httpd.Error(w, e, "Invalid input.") return } if c.User == "" { httpd.Error(w, nil, "No user.") return } if c.Dir == "" { httpd.Error(w, nil, "No dir.") return } if strings.Contains(c.Dir, "..") { httpd.Error(w, nil, "Dir hack.") return } if _, ok := clients[c.User]; !ok { dlDir := fmt.Sprintf(config.C.Basedir + c.Dir) if _, e := os.Stat(config.C.Basedir); os.IsNotExist(e) { if e := os.Mkdir(dlDir, os.ModeDir); e != nil { config.L.Printf("CRIT: %s", e.Error()) httpd.Error(w, e, "Permission error.") return } } // https://github.com/anacrolix/torrent/blob/master/config.go#L9 cl, e := torrent.NewClient(&torrent.Config{ DataDir: config.C.Basedir + c.Dir, // IPBlocklist => http://john.bitsurge.net/public/biglist.p2p.gz }) if e != nil { httpd.Error(w, e, "Client init failed") return } clients[c.User] = cl } client := clients[c.User] var ( t torrent.Torrent e error ) if len(c.Magnet) > 0 { t, e = client.AddMagnet(c.Magnet) if e != nil { httpd.Error(w, e, "Magnet add failed") return } } else if len(c.Torrent) > 0 { // strip base64 b, e := base64.StdEncoding.DecodeString(c.Torrent) if e != nil { httpd.Error(w, e, "Failed base64 decode torrent input") return } m, e := metainfo.Load(bytes.NewReader(b)) if e != nil { httpd.Error(w, e, "Failed base64 decode torrent input") return } t, e = client.AddTorrent(m) if e != nil { httpd.Error(w, e, "Failed adding torrent") return } } else { httpd.Error(w, nil, "No magnet nor torrent.") return } // queue go func() { <-t.GotInfo() t.DownloadAll() }() // (cl *Client) AddTorrentSpec(spec *TorrentSpec) (T Torrent, new bool, err error) { // TorrentSpecFromMagnetURI(uri string) (spec *TorrentSpec, err error) { // TorrentSpecFromMetaInfo(mi *metainfo.MetaInfo) (spec *TorrentSpec) { // (me *Client) AddMagnet(uri string) (T Torrent, err error) { // (me *Client) AddTorrent(mi *metainfo.MetaInfo) (T Torrent, err error) { msg := fmt.Sprintf(`{"status": true, "hash": "%s", "text": "Queued."}`, t.InfoHash().HexString()) w.Header().Set("Content-Type", "application/json") if _, e := w.Write([]byte(msg)); e != nil { httpd.Error(w, e, "Flush failed") return } }