Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No examples of bootstrapping a torrent from a file on disk. #218

Closed
james-lawrence opened this issue Dec 27, 2017 · 13 comments
Closed

No examples of bootstrapping a torrent from a file on disk. #218

james-lawrence opened this issue Dec 27, 2017 · 13 comments

Comments

@james-lawrence
Copy link
Contributor

james-lawrence commented Dec 27, 2017

I've spent all day trying to figure out how to take a binary file on disk and seed it to other nodes without the use of a tracker.

var (
  b []byte
)

info := metainfo.Info{PieceLength: 256 * 1024}

if err = info.BuildFromFilePath(path); err != nil {
  log.Fatalln(err)
}

if b, err = bencode.Marshal(info); err != nil {
  log.Fatalln(err)
}

mi = metainfo.MetaInfo{
  InfoBytes: b,
}
mi.SetDefaults()

tor, err := client.AddTorrent(mi)
if err != nil {
  log.Fatalln(err)
}
client.DHT().Announce(mi.HashInfoBytes(), 0, true)

// try to download at this point from another client

it seems like the other nodes block because the source node doesn't think it has the parts....
calling tor.BytesCompleted() returns 0 on the source node.

a working example that demonstrates how to load a file from disk and have it be seeded to other nodes would be a huge help.

based on some of your comments in other issues it seems like the assumption here is that a torrent always bootstraps from a remote endpoint.

@anacrolix
Copy link
Owner

Have you seed Seed = true in the Client Config?

@james-lawrence
Copy link
Contributor Author

Yup, turns out it was a mismatch between where I was placing the file and where the library expected it.

TBH there isn't a way to easily make a valid torrent instances from an IO source, which would vastly simply alot of code.

@anacrolix
Copy link
Owner

Do you mean the BuildFromFilePath? Creating torrents hasn't really been a focus for me with the repo, I've been using torrents already made. The documentation isn't clear on it, but if you set up PieceLength and Files or Name correctly, you can call Info.GeneratePieces with a callback that provides a ReadCloser to fill the hashes in Pieces. https://godoc.org/github.com/anacrolix/torrent/metainfo#Info.GeneratePieces, which is used by BuildFromFilePath internally. I'm open to better interface suggestions to match your requirements.

There's also github.com/anacrolix/torrent/cmd/torrent-create to create a metainfo externally.

@anacrolix
Copy link
Owner

I'd appreciate PRs for docs/comments to help others who might run into the original issue here you described.

@anacrolix
Copy link
Owner

I've improved some of the documentation around the metainfo.Info methods.

@james-lawrence
Copy link
Contributor Author

james-lawrence commented Dec 30, 2017

Yes, I was referring to BuildFromFilePath.

here are my initial thoughts when dealing with the library the other day.

first I'd remove most of the torrent related methods off the client.
there are just want too many of them. poorly documented, and its unclear which ones should be used and when.

func (cl *Client) AddMagnet(uri string) (T *Torrent, err error) {}
func (cl *Client) AddTorrentFromFile(filename string) (T *Torrent, err error) {}
func (cl *Client) AddTorrent(mi *metainfo.MetaInfo) (T *Torrent, err error) {}
func (cl *Client) AddTorrentInfoHash(infoHash metainfo.Hash) (t *Torrent, new bool) {}
func (cl *Client) AddTorrentInfoHashWithStorage(infoHash metainfo.Hash, specStorage storage.ClientImpl) (t *Torrent, new bool) {}
func (cl *Client) AddTorrentSpec(spec *TorrentSpec) (t *Torrent, new bool, err error) {}

I would likely remove all of them except for AddTorrent, I'd expose DropTorrent instead of having it on the torrent structure:

func (cl *Client) AddTorrent(T *TorrentSpec) (new bool, err error) {}
func (cl *Client) DropTorrent(T *TorrentSpec) error {}
  • only expose one: Torrent or TorrentSpec. outside of a client the distinction doesn't matter.
  • remove Drop() from Torrent, I believe its better represented on the client.

I would add the following helper methods that generate torrent specs.

type TorrentSpecOption func(*TorrentSpec)
// TorrentSpecData provide the source data to the torrent, nil can represent no local data.
type TorrentSpecData(d TorrentImpl) TorrentSpecOption {
  return func(t *TorrentSpec) {
    t.TorrentImpl = d
  }
}

// New create a torrent from the metainfo.Info and any additional options.
func New(mi metainfo.Info, options ...TorrentSpecOption) (*TorrentSpec, error) {}

// NewFromData creates a torrent from the raw data the torrent will represent.
func NewFromData(r io.Reader, options ...TorrentSpecOption) (*TorrentSpec, error) {}

// NewFromFile convience method to create a torrent from a file. see NewFromData for
// more information.
func NewFromFile(path string, options ...TorrentSpecOption) (*TorrentSpec, err error) {}

// NewFromMetadata creates a torrent from metadata stored in a file based format.
func NewFromMetadata(r io.ReadCloser, options ...TorrentSpecOption) (*TorrentSpec, error) {}

// NewFromMagnet create a torrent from a magnet URL.
func NewFromMagnet(s string, options ...TorrentSpecOption) (*TorrentSpec, error) {}

@anacrolix
Copy link
Owner

Let's open another issue for redesign of the API. What's the status of this issue? Do you still think the documentation needs improving?

@TongxiJi
Copy link

But where is the example of bootstrapping a torrent from a file on disk now?

@elgatito
Copy link
Contributor

@TongxiJi
Copy link

But where's the real local file or dir setting?

@elgatito
Copy link
Contributor

@TongxiJi full path to torrent file as an argument.

@anacrolix
Copy link
Owner

@TongxiJi I think you want to seed files directly from the filesystem, and have a torrent file created for it on the fly? Open an issue if it's something like this, it would make a great example cmd.

@TongxiJi
Copy link

@anacrolix Yes,i wana a example about that.I opened a new issue here #300.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants