Socket
Socket
Sign inDemoInstall

create-torrent

Package Overview
Dependencies
Maintainers
1
Versions
139
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

create-torrent - npm Package Compare versions

Comparing version 1.2.0 to 2.0.0

bin/cmd.js

210

index.js

@@ -0,9 +1,13 @@

module.exports = createTorrent
var bencode = require('bencode')
var BlockStream = require('block-stream')
var bencode = require('bencode')
var calcPieceLength = require('piece-length')
var corePath = require('path')
var crypto = require('crypto')
var FileReadStream = require('filestream/read')
var flatten = require('lodash.flatten')
var fs = require('fs')
var inherits = require('inherits')
var MultiStream = require('multistream')
var once = require('once')

@@ -13,51 +17,71 @@ var parallel = require('run-parallel')

inherits(MultiFileStream, stream.Readable)
var DEFAULT_ANNOUNCE_LIST = [
['udp://tracker.publicbt.com:80/announce'],
['udp://tracker.openbittorrent.com:80/announce']
]
function MultiFileStream (paths, opts) {
stream.Readable.call(this, opts)
/**
* Create a torrent.
* @param {string|File|FileList|Array.<File>} input
* @param {Object} opts
* @param {string=} opts.name
* @param {string=} opts.comment
* @param {string=} opts.createdBy
* @param {boolean|number=} opts.private
* @param {number=} opts.pieceLength
* @param {Array.<Array.<string>>=} opts.announceList
* @param {function} cb
* @return {Buffer} buffer of .torrent file data
*/
function createTorrent (input, opts, cb) {
if (typeof opts === 'function') {
cb = opts
opts = {}
}
var files
this._paths = paths
this._currentPath = -1
if (paths.length === 0) {
this._stream = null
this.push(null)
} else {
this._nextStream()
if (isFile(input)) {
input = [ input ]
}
}
MultiFileStream.prototype._read = function () {}
if (Array.isArray(input) && input.length > 0) {
opts.name = opts.name || input[0].name
files = input.map(function (item) {
if (isFile(item)) {
return {
length: item.size,
path: [ item.name ],
stream: new FileReadStream(item)
}
} else {
// TODO: support an array of paths
throw new Error('Array must contain only File objects')
}
})
onFiles(files, opts, cb)
} else if (typeof input === 'string') {
opts.name = opts.name || corePath.basename(input)
MultiFileStream.prototype._nextStream = function () {
this._currentPath += 1
traversePath(getFileInfo, input, function (err, files) {
if (err) return cb(err)
if (this._currentPath === this._paths.length) {
this._stream = null
this.push(null)
return
}
if (Array.isArray(files)) {
files = flatten(files)
} else {
files = [ files ]
}
this._stream = fs.createReadStream(this._paths[this._currentPath])
var dirName = corePath.normalize(input) + corePath.sep
files.forEach(function (file) {
file.stream = fs.createReadStream(file.path)
file.path = file.path.replace(dirName, '').split(corePath.sep)
})
var self = this
this._stream.on('readable', function () {
while (chunk = self._stream.read()) {
self.push(chunk)
}
})
this._stream.on('end', function () {
self._stream.removeAllListeners()
self._nextStream()
})
this._stream.on('error', function (err) {
self.emit('error', err)
})
onFiles(files, opts, cb)
})
} else {
throw new Error('invalid input type')
}
}
var DEFAULT_ANNOUNCE_LIST = [
['udp://tracker.publicbt.com:80/announce'],
['udp://tracker.openbittorrent.com:80/announce']
]
function each (arr, fn, cb) {

@@ -105,13 +129,16 @@ var tasks = arr.map(function (item) {

var paths = files.map(function (file) { return file.path })
var streams = files.map(function (file) {
return file.stream
})
;(new MultiFileStream(paths))
new MultiStream(streams)
.pipe(new BlockStream(pieceLength, { nopad: true }))
.on('data', function (chunk) {
pieces.push(crypto.createHash('sha1').update(chunk).digest())
pieces.push(sha1(chunk))
})
.on('end', function () {
cb(null, pieces)
cb(null, Buffer.concat(pieces))
})
.on('error', function (err) {
console.error(err)
cb(err)

@@ -121,21 +148,4 @@ })

/**
* Create a torrent.
* @param {string} path
* @param {Object} opts
* @param {string=} opts.comment
* @param {string=} opts.createdBy
* @param {boolean|number=} opts.private
* @param {number=} opts.pieceLength
* @param {Array.<Array.<string>>=} opts.announceList
* @param {function} cb
* @return {Buffer} buffer of .torrent file data
*/
module.exports = function (path, opts, cb) {
if (typeof opts === 'function') {
cb = opts
opts = {}
}
var announceList = (opts.announceList !== undefined)
function onFiles (files, opts, cb) {
var announceList = opts.announceList !== undefined
? opts.announceList

@@ -146,14 +156,12 @@ : DEFAULT_ANNOUNCE_LIST

info: {
name: corePath.basename(path)
name: opts.name
},
announce: announceList[0][0],
'announce-list': announceList,
'creation date': Date.now(),
'creation date': Number(opts.creationDate) || Date.now(),
encoding: 'UTF-8'
}
var dirName = corePath.normalize(path) + corePath.sep
if (opts.comment !== undefined) {
torrent.info.comment = comment
torrent.info.comment = opts.comment
}

@@ -169,40 +177,54 @@

traversePath(getFileInfo, path, function (err, files) {
if (err) return cb(err)
var singleFile = files.length === 1
var singleFile = !Array.isArray(files)
var length = files.reduce(sumLength, 0)
var pieceLength = opts.pieceLength || calcPieceLength(length)
torrent.info['piece length'] = pieceLength
if (singleFile) {
files = [ files ]
}
if (singleFile) {
torrent.info.length = length
}
files = flatten(files)
getPieceList(files, pieceLength, function (err, pieces) {
if (err) return cb(err)
torrent.info.pieces = pieces
var length = files.reduce(sumLength, 0)
files.forEach(function (file) {
delete file.stream
})
if (singleFile) {
torrent.info.length = length
if (!singleFile) {
torrent.info.files = files
}
var pieceLength = opts.pieceLength || calcPieceLength(length)
torrent.info['piece length'] = pieceLength
getPieceList(files, pieceLength, function (err, pieces) {
torrent.info.pieces = Buffer.concat(pieces)
if (!singleFile) {
files.forEach(function (file) {
file.path = file.path.replace(dirName, '').split(corePath.sep)
})
torrent.info.files = files
}
cb(null, bencode.encode(torrent))
})
cb(null, bencode.encode(torrent))
})
}
/**
* Accumulator to sum file lengths
* @param {number} sum
* @param {Object} file
* @return {number}
*/
function sumLength (sum, file) {
return sum + file.length
}
/**
* Check if `obj` is a W3C File object
* @param {*} obj
* @return {boolean}
*/
function isFile (obj) {
return typeof File !== 'undefined' && obj instanceof File
}
/**
* Compute a SHA1 hash
* @param {Buffer} buf
* @return {Buffer}
*/
function sha1 (buf) {
return crypto.createHash('sha1').update(buf).digest()
}
{
"name": "create-torrent",
"description": "Create .torrent files",
"version": "1.2.0",
"version": "2.0.0",
"author": "Feross Aboukhadijeh <feross@feross.org> (http://feross.org/)",
"bin": {
"create-torrent": "./bin/cmd.js"
},
"browser": {
"minimist": false
},
"bugs": {

@@ -12,4 +18,7 @@ "url": "https://github.com/feross/create-torrent/issues"

"block-stream": "^0.0.7",
"filestream": "git://github.com/feross/filestream",
"inherits": "^2.0.1",
"lodash.flatten": "^2.4.1",
"minimist": "^0.2.0",
"multistream": "^1.0.0",
"once": "^1.3.0",

@@ -20,2 +29,3 @@ "piece-length": "^0.0.0",

"devDependencies": {
"brfs": "^1.1.2",
"parse-torrent": "^1.1.0",

@@ -46,3 +56,19 @@ "tape": "^2.5.0"

"test": "tape test/*.js"
},
"testling": {
"files": "test/browser/*.js",
"browsers": [
"ie/9..latest",
"chrome/25..latest",
"chrome/canary",
"firefox/20..latest",
"firefox/nightly",
"safari/6..latest",
"opera/15.0..latest",
"opera/next",
"ipad/6.0..latest",
"iphone/6.0..latest",
"android-browser/4.2..latest"
]
}
}

@@ -5,5 +5,7 @@ # create-torrent [![travis](https://img.shields.io/travis/feross/create-torrent.svg)](https://travis-ci.org/feross/create-torrent) [![npm](https://img.shields.io/npm/v/create-torrent.svg)](https://npmjs.org/package/create-torrent) [![gittip](https://img.shields.io/gittip/feross.svg)](https://www.gittip.com/feross/)

[![browser support](https://ci.testling.com/feross/create-torrent.png)](https://ci.testling.com/feross/create-torrent)
![creation](https://raw.githubusercontent.com/feross/create-torrent/master/img.jpg)
This module is used by [WebTorrent](http://webtorrent.io).
This module is used by [WebTorrent](http://webtorrent.io). Works in the browser with [browserify](http://browserify.org/)!

@@ -37,17 +39,24 @@ ### install

#### `createTorrent(path, [opts], function callback (err, torrent) {})`
#### `createTorrent(input, [opts], function callback (err, torrent) {})`
Create a new `.torrent` file.
`path` is the path to the file or folder to use.
`input` can be any of the following:
`opts` is optional and allows you to set special settings for the .torrent.
- path to the file or folder on filesystem (string)
- W3C [File](https://developer.mozilla.org/en-US/docs/Web/API/File) object (from an <input> or drag and drop)
- W3C [FileList](https://developer.mozilla.org/en-US/docs/Web/API/FileList) object (basically an array of `File` objects)
- Array of `File` objects
`opts` is optional and allows you to set special settings on the produced .torrent file.
``` js
{
comment: '', // free-form textual comments of the author (string)
createdBy: '', // name and version of the program used to create the .torrent (string)
private: false, // is this a private .torrent? (boolean or integer)
pieceLength: 32768 // force a custom piece length (number of bytes)
announceList: [[]] // custom trackers to use (array of arrays of strings) (see [bep12](http://www.bittorrent.org/beps/bep_0012.html))
name: String, // name of the torrent (default = basename of `path`)
comment: String, // free-form textual comments of the author
createdBy: String, // name and version of program used to create torrent
creationDate: Date // creation time in UNIX epoch format (default = now)
private: Boolean, // is this a private .torrent? (default = false)
pieceLength: Number // force a custom piece length (number of bytes)
announceList: [[String]] // custom trackers (array of arrays of strings) (see [bep12](http://www.bittorrent.org/beps/bep_0012.html))
}

@@ -59,4 +68,15 @@ ```

### command line
```
usage: create-torrent <directory OR file> {-o outfile.torrent}
Create a torrent file from a directory or file.
If an output file isn\'t specified with `-o`, the torrent file will be
written to stdout.
```
### license
MIT. Copyright (c) [Feross Aboukhadijeh](http://feross.org).

@@ -70,3 +70,2 @@ var createTorrent = require('../')

test('create multi file torrent', function (t) {

@@ -118,3 +117,2 @@ t.plan(16)

])
t.equals(sha1(parsedTorrent.infoBuffer), '80562f38656b385ea78959010e51a2cc9db41ea0')

@@ -121,0 +119,0 @@ })

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc