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

Add local file deletion on `torrent.destroy` #1102

Open
wants to merge 4 commits into
base: master
from
Open
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

Add opts to `client.remove` and `torrent.destroy`

Add an optional `opts` to `client.remove` and `torrent.remove`,
if this `opts` set `remove` to `true`, then we call `store.destroy`
instead of `store.close`.
  • Loading branch information
Rowern committed Apr 14, 2017
commit bcda4bdcd5f251f20aaad025761a8b676146b3ab
@@ -162,10 +162,20 @@ destroyed and all torrents are removed and cleaned up when this occurs.

Always listen for the 'error' event.

## `client.remove(torrentId, [function callback (err) {}])`
## `client.remove(torrentId, [opts], [function callback (err) {}])`

Remove a torrent from the client. Destroy all connections to peers and delete all saved
file data. If `callback` is specified, it will be called when file data is removed.
file data.

If `opts` is specified, then the default options (shown below) will be overridden.

```js
{
remove: Boolean // Delete torrent data (default to false)
}
```

If `callback` is specified, it will be called when file data is removed.

## `client.destroy([function callback (err) {}])`

@@ -262,19 +272,20 @@ Number of peers in the torrent swarm.

Torrent download location.

## `torrent.destroy([callback])`
## `torrent.destroy([opts], [callback])`

Alias for `client.remove(torrent)`. If `callback` is provided, it will be called when
the torrent is fully destroyed, i.e. all open sockets are closed, and the storage is
closed.
Alias for `client.remove(torrent)`.

## `torrent.delete([callback])`
If `opts` is specified, then the default options (shown below) will be overridden.

Does the same as `torrent.destroy([callback])`. If `callback` is provided, it will be
called when the torrent is fully destroyed, i.e. all open sockets are closed, the
storage is closed and *torrent data are deleted*.
```js
{
remove: Boolean // Delete torrent data (default to false)
}
```

*Note: Torrent data are only deleted in node applications.
If `callback` is provided, it will be called when the torrent is fully destroyed, i.e.
all open sockets are closed, and the storage is closed.

## `torrent.addPeer(peer)`

@@ -378,18 +378,20 @@ WebTorrent.prototype.seed = function (input, opts, onseed) {
* @param {string|Buffer|Torrent} torrentId
* @param {function} cb
*/
WebTorrent.prototype.remove = function (torrentId, cb) {
WebTorrent.prototype.remove = function (torrentId, opts, cb) {
this._debug('remove')
if (typeof opts === 'function') return this.remove(torrentId, null, opts)
var torrent = this.get(torrentId)
if (!torrent) throw new Error('No torrent with id ' + torrentId)
this._remove(torrentId, cb)
this._remove(torrentId, opts, cb)
}

WebTorrent.prototype._remove = function (torrentId, cb) {
WebTorrent.prototype._remove = function (torrentId, opts, cb) {
if (typeof opts === 'function') return this._remove(torrentId, null, opts)
var torrent = this.get(torrentId)
if (!torrent) return
this.torrents.splice(this.torrents.indexOf(torrent), 1)
torrent.delete(cb)
torrent.destroy(opts, cb)
}

WebTorrent.prototype.address = function () {
@@ -25,7 +25,6 @@ var path = require('path')
var Piece = require('torrent-piece')
var pump = require('pump')
var randomIterate = require('random-iterate')
var rimraf = require('rimraf')
var sha1 = require('simple-sha1')
var speedometer = require('speedometer')
var uniq = require('uniq')
@@ -72,7 +71,6 @@ function Torrent (torrentId, client, opts) {

this.announce = opts.announce
this.urlList = opts.urlList
this._fromLocalFile = opts.path
this.path = opts.path
this._store = opts.store || FSChunkStore
this._getAnnounceOpts = opts.getAnnounceOpts
@@ -638,39 +636,21 @@ Torrent.prototype._onStore = function () {
self._updateSelections()
}

Torrent.prototype.delete = function (cb) {
Torrent.prototype.destroy = function (opts, cb) {
var self = this
self._delete(cb)
if (typeof opts === 'function') return self.destroy(null, opts)
self._destroy(null, opts, cb)
}

Torrent.prototype._delete = function (cb) {
var self = this
self.destroy(function (err) {
if (err) return cb(err)
// We won't delete torrent created from local file
// We also can't delete file created on a browser
if (typeof window === 'undefined' && !self._fromLocalFile && self.path) {
rimraf(self.path, function (err) {
if (!cb) return
cb(err)
})
} else {
cb()
}
})
}

Torrent.prototype.destroy = function (cb) {
var self = this
self._destroy(null, cb)
}

Torrent.prototype._destroy = function (err, cb) {
Torrent.prototype._destroy = function (err, opts, cb) {
var self = this
if (typeof opts === 'function') return self._destroy(err, null, opts)
if (self.destroyed) return
self.destroyed = true
self._debug('destroy')

opts = opts ? extend(opts) : {}

self.client._remove(self)

clearInterval(self._rechokeIntervalId)
@@ -705,7 +685,11 @@ Torrent.prototype._destroy = function (err, cb) {

if (self.store) {
tasks.push(function (cb) {
self.store.close(cb)
if (self._store === FSChunkStore && opts.remove) {
self.store.destroy(cb)
} else {
self.store.close(cb)
}
})
}

@@ -49,7 +49,6 @@
"range-parser": "^1.2.0",
"readable-stream": "^2.1.4",
"render-media": "^2.8.0",
"rimraf": "^2.6.1",
"run-parallel": "^1.1.6",
"run-parallel-limit": "^1.0.3",
"safe-buffer": "^5.0.1",
@@ -1,8 +1,10 @@
var fs = require('fs')
var path = require('path')
var fixtures = require('webtorrent-fixtures')
var test = require('tape')
var WebTorrent = require('../')

test('torrent.destroy: destroy and remove torrent', function (t) {
test('torrent.destroy: destroy torrent', function (t) {
t.plan(5)

var client = new WebTorrent({ dht: false, tracker: false })
@@ -22,3 +24,34 @@ test('torrent.destroy: destroy and remove torrent', function (t) {
client.destroy(function (err) { t.error(err, 'client destroyed') })
})
})

test('torrent.destroy: seed torrent and remove it', function (t) {
t.plan(7)

var client = new WebTorrent({ dht: false, tracker: false })

client.on('error', function (err) { t.fail(err) })
client.on('warning', function (err) { t.fail(err) })

client.seed(fixtures.leaves.content, {
name: 'Leaves of Grass by Walt Whitman.epub',
announce: []
}, function (torrent) {
t.equal(client.torrents.length, 1)
t.equal(torrent.infoHash, fixtures.leaves.parsedTorrent.infoHash)
t.equal(torrent.magnetURI, fixtures.leaves.magnetURI)

var completeFileName = path.join(torrent.path, torrent.files[0].name)

client.remove(torrent, {'remove': true}, function (err) {
t.error(err, 'torrent removed')
fs.stat(completeFileName, function (err) {

This comment has been minimized.

Copy link
@Rowern

Rowern Apr 14, 2017

Author

I know this might not work well with browser API, I might add a check on the type of store used.

if (err && err.code === 'ENOENT') return t.pass('File deleted')
t.fail('File not deleted')
})
})
t.equal(client.torrents.length, 0)

client.destroy(function (err) { t.error(err, 'client destroyed') })
})
})
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.