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

Using metainfo.NewInfoFromFilePath on a directory results in "error copying" #1

Closed
eyedeekay opened this issue Feb 7, 2021 · 3 comments

Comments

@eyedeekay
Copy link

I am attempting to learn your library and am getting started by writing a .torrent file generation tool for your bttools suite. I am attempting to produce the bytes required to populate the metainfo.MetaInfo.InfoBytes field by creating the metainfo.Info object using metainfo.NewInfoFromFilePath function on a directory, then loop over the pieces and concatenate them together. This approach works if I'm creating a single-file torrent, but when I try to create a multi-file torrent from a directory, I get:

    error generating pieces: error copying .: read www: is a directory

You can see the code here:

xgfone/bttools@master...eyedeekay:create

func CreateTorrent(ctx *cli.Context) error {
	dirs := ctx.Args().Slice()
	if len(dirs) > 1 {
		return fmt.Errorf("Input invalid, please use only one file or directory at ta time.")
	}
	info, err := metainfo.NewInfoFromFilePath(dirs[0], int64(ctx.Int("length")))
	if err != nil {
		return err
	}
	log.Println(info.CountPieces(), "pieces")
	var pieces []byte
	for n := 0; n < info.CountPieces(); n++ {
		pieces = append(pieces, info.Piece(n).Hash().Bytes()...)
	}
	meta := &metainfo.MetaInfo{
		InfoBytes: pieces,
	}
	infoc, err := meta.Info()
	if err != nil {
		return err
	}
	log.Println("Info generated", infoc.Name)
	return nil
}

The documentation says NewInfoFromFilePath returns a new Info from a file or directory so I think this must be unintentional, or I am misusing the function.

Thanks in advance for your help.

@xgfone
Copy link
Owner

xgfone commented Feb 8, 2021

Thank you for your test!

It is a bug when reading a directory to create a new Info instance. And It has been fixed @fd3825a.


  1. The function NewInfoFromFilePath() makes a file or directory into a Info struct, then you can get the torrent info bytes by using bencode.EncodeBytes(info), that's the value of the field InfoBytes of the struct type MetaInfo.
  2. The function MetaInfo.Info() decodes the torrent info bytes to the struct type Info.
  3. They are the opposite operations.

For the new command create, you want to generate a .torrent file from a file or directory. Right? You can do it like this:

func CreateTorrent(ctx *cli.Context) error {
	dirs := ctx.Args().Slice()
	if len(dirs) > 1 {
		return fmt.Errorf("Input invalid, please use only one file or directory at ta time.")
	}

	info, err := metainfo.NewInfoFromFilePath(dirs[0], int64(ctx.Int("length")))
	if err != nil {
		return err
	}

	var mi metainfo.MetaInfo
	mi.InfoBytes, err = bencode.EncodeBytes(info)
	if err != nil {
		return err
	}

	// Set the announce information.
	announces := ctx.StringSlice("announce")
	switch len(announces) {
	case 0:
	case 1:
		mi.Announce = announces[0]
	default:
		mi.AnnounceList = metainfo.AnnounceList{announces}
	}
	/// TODO: set the webseed information like above.
	/// TODO: set other fields of MetaInfo.

	var output io.WriteCloser = os.Stdout
	if o := ctx.String("output"); o != "" {
		output, err = os.OpenFile(o, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
		if err != nil {
			return err
		}
		defer output.Close()
	}

	return mi.Write(output)
}

@eyedeekay
Copy link
Author

I see, that helps a lot. Changed my implementation to match the correct way to use the Info and now the create command works! Sent a PR over in bttools, looking forward to hearing from you there.

@xgfone
Copy link
Owner

xgfone commented Feb 12, 2021

The bug has been fixed. See Release v0.4.1.

@xgfone xgfone closed this as completed Feb 12, 2021
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

2 participants