v0.1.43: Add WebTorrent seeding

This commit is contained in:
Mitra Ardron 2019-05-07 12:02:39 +10:00
parent d612331e0b
commit dbcd47fe8e
4 changed files with 42 additions and 15 deletions

View File

@ -126,6 +126,7 @@ See [Dweb document index](./DOCUMENTINDEX.md) for a list of the repos that make
### Release Notes ### Release Notes
* 0.1.43: Add WebTorrent seeding
* 0.1.42: Better behavior when cant see gateway * 0.1.42: Better behavior when cant see gateway
* 0.1.41: Remove createReadStream for browser (it was added for node in 0.1.40), add fetch(url,opts,cb) * 0.1.41: Remove createReadStream for browser (it was added for node in 0.1.40), add fetch(url,opts,cb)
* 0.1.40: Bug fix in httpfetch({count=0}), * 0.1.40: Bug fix in httpfetch({count=0}),

View File

@ -9,7 +9,8 @@ Y Lists have listeners and generate events - see docs at ...
const WebTorrent = require('webtorrent'); const WebTorrent = require('webtorrent');
const stream = require('readable-stream'); const stream = require('readable-stream');
const Url = require('url'); const Url = require('url');
const debugwt = require('debug')('dweb-transports:webtorrent'); const path = require('path');
const debug = require('debug')('dweb-transports:webtorrent');
// Other Dweb modules // Other Dweb modules
const errors = require('./Errors'); // Standard Dweb Errors const errors = require('./Errors'); // Standard Dweb Errors
@ -33,7 +34,7 @@ class TransportWEBTORRENT extends Transport {
this.options = options; // Dictionary of options this.options = options; // Dictionary of options
this.name = "WEBTORRENT"; // For console log etc this.name = "WEBTORRENT"; // For console log etc
this.supportURLs = ['magnet']; this.supportURLs = ['magnet'];
this.supportFunctions = ['fetch', 'createReadStream']; this.supportFunctions = ['fetch', 'createReadStream', "seed"];
this.status = Transport.STATUS_LOADED; this.status = Transport.STATUS_LOADED;
} }
@ -45,7 +46,7 @@ class TransportWEBTORRENT extends Transport {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.webtorrent = new WebTorrent(this.options); this.webtorrent = new WebTorrent(this.options);
this.webtorrent.once("ready", () => { this.webtorrent.once("ready", () => {
debugwt("ready"); debug("ready");
resolve(); resolve();
}); });
this.webtorrent.once("error", (err) => reject(err)); this.webtorrent.once("error", (err) => reject(err));
@ -60,7 +61,7 @@ class TransportWEBTORRENT extends Transport {
First part of setup, create obj, add to Transports but dont attempt to connect, typically called instead of p_setup if want to parallelize connections. First part of setup, create obj, add to Transports but dont attempt to connect, typically called instead of p_setup if want to parallelize connections.
*/ */
let combinedoptions = Transport.mergeoptions(defaultoptions, options.webtorrent); let combinedoptions = Transport.mergeoptions(defaultoptions, options.webtorrent);
debugwt("setup0: options=%o", combinedoptions); debug("setup0: options=%o", combinedoptions);
let t = new TransportWEBTORRENT(combinedoptions); let t = new TransportWEBTORRENT(combinedoptions);
Transports.addtransport(t); Transports.addtransport(t);
@ -81,6 +82,22 @@ class TransportWEBTORRENT extends Transport {
return this; return this;
} }
p_stop(refreshstatus) {
return new Promise((resolve, reject) => {
this.webtorrent.destroy((err) => {
this.status = Transport.STATUS_FAILED;
if (refreshstatus) refreshstatus(this);
if (err) {
debug("Webtorrent error during stopping %o", err);
reject(err);
} else {
debug("Webtorrent stopped");
resolve();
}
});
})
}
async p_status() { async p_status() {
/* /*
Return a string for the status of a transport. No particular format, but keep it short as it will probably be in a small area of the screen. Return a string for the status of a transport. No particular format, but keep it short as it will probably be in a small area of the screen.
@ -196,13 +213,22 @@ class TransportWEBTORRENT extends Transport {
}); });
} }
seed({relFilePath, directoryPath, torrentRelativePath }, cb) { seed({fileRelativePath, directoryPath, torrentRelativePath }, cb) {
/* Add a file to webTorrent - this will be called each time a file is cached and adds the torrent to WT handling so its seeding this (and other) files in directory */ /* Add a file to webTorrent - this will be called each time a file is cached and adds the torrent to WT handling so its seeding this (and other) files in directory */
const torrentfile = path.join(directoryPath, torrentRelativePath); if (!torrentRelativePath) { // If no torrentfile available then just skip WebTorrent, MirrorFS will often seed the file (eg to IPFS) while its fetching the torrent and then seed that.
this.p_addTorrentFromTorrentFile(torrentfile, directoryPath) cb(null);
.then(res => { debug("Added %s to webtorrent", relFilePath); cb(null)}) } else {
.catch(err => { const torrentfile = path.join(directoryPath, torrentRelativePath);
debug("addWebTorrent failed %s", relFilePath); cb(err); } ); this.p_addTorrentFromTorrentFile(torrentfile, directoryPath)
.then(res => { debug("Added %s/%s to webtorrent", directoryPath, fileRelativePath); cb(null)})
.catch(err => {
if (err.message.includes("Cannot add duplicate torrent")) { // Ignore silently if already added
cb(null);
} else {
debug("addWebTorrent failed %s/%s", directoryPath, fileRelativePath); cb(err);
}
});
}
} }
async _p_fileTorrentFromUrl(url) { async _p_fileTorrentFromUrl(url) {
@ -289,7 +315,7 @@ class TransportWEBTORRENT extends Transport {
:param opts: { start: byte to start from; end: optional end byte } :param opts: { start: byte to start from; end: optional end byte }
:returns stream: The readable stream. :returns stream: The readable stream.
*/ */
debugwt("reading from stream %s %o", file.name, opts); debug("reading from stream %s %o", file.name, opts);
let through; let through;
try { try {
through = new stream.PassThrough(); through = new stream.PassThrough();
@ -297,7 +323,7 @@ class TransportWEBTORRENT extends Transport {
fileStream.pipe(through); fileStream.pipe(through);
return through; return through;
} catch(err) { } catch(err) {
debugwt("createReadStream error %s", err); debug("createReadStream error %s", err);
if (typeof through.destroy === 'function') if (typeof through.destroy === 'function')
through.destroy(err); through.destroy(err);
else through.emit('error', err) else through.emit('error', err)
@ -310,7 +336,7 @@ class TransportWEBTORRENT extends Transport {
let filet = await this._p_fileTorrentFromUrl(url); let filet = await this._p_fileTorrentFromUrl(url);
return new ReadableStream({ return new ReadableStream({
start (controller) { start (controller) {
debugwt("start %s %o", url, opts); debug("start %s %o", url, opts);
// Create a webtorrent file stream // Create a webtorrent file stream
const filestream = filet.createReadStream(opts); const filestream = filet.createReadStream(opts);
// When data comes out of webtorrent node.js style stream, put it into the WHATWG stream // When data comes out of webtorrent node.js style stream, put it into the WHATWG stream

File diff suppressed because one or more lines are too long

View File

@ -53,5 +53,5 @@
"test": "cd src; node ./test.js", "test": "cd src; node ./test.js",
"help": "echo 'test (test it)'; echo 'build (creates dweb-transports-bundle)'" "help": "echo 'test (test it)'; echo 'build (creates dweb-transports-bundle)'"
}, },
"version": "0.1.42" "version": "0.1.43"
} }