diff options
author | Feross Aboukhadijeh <feross@feross.org> | 2015-08-22 15:46:16 +0300 |
---|---|---|
committer | Feross Aboukhadijeh <feross@feross.org> | 2015-08-22 15:46:16 +0300 |
commit | 958f30a0341ca323c7cef794b00fe38eed845297 (patch) | |
tree | e8a0248aa350c7d3638365b771f0975027c8ae21 /lib/file.js | |
parent | 89645ebe81cf46d61e4d7be423cb8c7a32283b2b (diff) |
BREAKING: Use abstract-chunk-store for storage
Part of an effort to share more code with `torrent-stream` by
@mafintosh:
https://github.com/mafintosh/torrent-stream/pull/133
https://github.com/mafintosh/torrent-stream/pull/132
Storage is now based on:
https://www.npmjs.com/package/fs-chunk-store (in node)
https://www.npmjs.com/package/memory-chunk-store (in the browser)
and:
https://www.npmjs.com/package/immediate-chunk-store
https://www.npmjs.com/package/torrent-piece
This is a BREAKING change, since users who pass in custom storage
engine with `opts.storage` will need to update their storage backend to
be `abstract-chunk-store` compliant:
https://www.npmjs.com/package/abstract-chunk-store
There are also likely other miscellaneous BREAKING API changes, since
this was a huge refactor of the codebase.
Diffstat (limited to 'lib/file.js')
-rw-r--r-- | lib/file.js | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/lib/file.js b/lib/file.js new file mode 100644 index 0000000..d85784c --- /dev/null +++ b/lib/file.js @@ -0,0 +1,120 @@ +module.exports = File + +var appendTo = require('./append-to') +var eos = require('end-of-stream') +var EventEmitter = require('events').EventEmitter +var FileStream = require('./file-stream') +var inherits = require('inherits') +var mime = require('./mime.json') +var path = require('path') + +inherits(File, EventEmitter) + +/** + * @param {Torrent} torrent torrent that the file belongs to + * @param {Object} file file object from the parsed torrent + */ +function File (torrent, file) { + EventEmitter.call(this) + + this._torrent = torrent + + this.name = file.name + this.path = file.path + this.length = file.length + this.offset = file.offset + + this.done = (this.length === 0) + + var start = file.offset + var end = start + file.length - 1 + + this._startPiece = start / this._torrent.pieceLength | 0 + this._endPiece = end / this._torrent.pieceLength | 0 +} + +/** + * Selects the file to be downloaded, but at a lower priority than files with streams. + * Useful if you know you need the file at a later stage. + */ +File.prototype.select = function () { + if (this.length === 0) return + this._torrent.select(this._startPiece, this._endPiece, false) +} + +/** + * Deselects the file, which means it won't be downloaded unless someone creates a stream + * for it. + */ +File.prototype.deselect = function () { + if (this.length === 0) return + this._torrent.deselect(this._startPiece, this._endPiece, false) +} + +/** + * Create a readable stream to the file. Pieces needed by the stream will be prioritized + * highly and fetched from the swarm first. + * + * @param {Object} opts + * @param {number} opts.start stream slice of file, starting from this byte (inclusive) + * @param {number} opts.end stream slice of file, ending with this byte (inclusive) + * @return {FileStream} + */ +File.prototype.createReadStream = function (opts) { + var self = this + var stream = new FileStream(self, opts) + self._torrent.select(stream._startPiece, stream._endPiece, true, function () { + stream._notify() + }) + eos(stream, function () { + self._torrent.deselect(stream._startPiece, stream._endPiece, true) + }) + return stream +} + +/** + * @param {function} cb + */ +File.prototype.getBuffer = function (cb) { + var buf = new Buffer(this.length) + var offset = 0 + this.createReadStream() + .on('data', function (chunk) { + console.log('data') + chunk.copy(buf, offset) + offset += chunk.length + }) + .on('end', function () { + console.log('END') + cb(null, buf) + }) + .on('error', cb) +} + +/** + * @param {function} cb + */ +File.prototype.getBlobURL = function (cb) { + var self = this + if (typeof window === 'undefined') throw new Error('browser-only method') + + self.getBuffer(function (err, buffer) { + if (err) return cb(err) + var ext = path.extname(self.name).toLowerCase() + var type = mime[ext] + var blob = new window.Blob([ buffer ], type && { type: type }) + var url = window.URL.createObjectURL(blob) + cb(null, url) + }) +} + +/** + * Show the file in a the browser by appending it to the DOM. + * @param {Element|string} elem + * @param {function} cb + */ +File.prototype.appendTo = function (elem, cb) { + if (typeof window === 'undefined') throw new Error('browser-only method') + if (typeof elem === 'string') elem = document.querySelector(elem) + appendTo(this, elem, cb) +} |