From d1d816ed030e1e8e214444fa23d1398d788fe502 Mon Sep 17 00:00:00 2001 From: Alexey Kasyanchuk Date: Wed, 27 Jun 2018 21:36:52 +0300 Subject: [PATCH] feat(downloading): removing after download ability --- src/app/torrent.js | 76 ++++++++++++++++++-- src/background/api.js | 123 ++++++++++++++++++++++++++------ src/background/torrentClient.js | 14 +++- 3 files changed, 182 insertions(+), 31 deletions(-) diff --git a/src/app/torrent.js b/src/app/torrent.js index 6cc0618..edbe73d 100644 --- a/src/app/torrent.js +++ b/src/app/torrent.js @@ -161,20 +161,26 @@ export default class Torrent extends Component { downloading: false, downloaded: false, startingDownloading: false, - downloadProgress: {} + downloadProgress: {}, + downloadRemoveOnDone: false } constructor(props) { super(props) - if(props.download) + + const download = props.download || props.torrent.download + if(download) { - const { progress, downloaded, downloadSpeed } = props.download + const { progress, downloaded, downloadSpeed, removeOnDone } = download this.state.downloadProgress = { progress, downloaded, downloadSpeed } - this.state.downloading = true + this.state.downloading = progress < 1 + this.state.downloaded = progress === 1 + this.state.downloadRemoveOnDone = removeOnDone } } + componentDidMount() { this.downloading = (hash) => { @@ -211,6 +217,16 @@ export default class Torrent extends Component { }) } window.torrentSocket.on('downloadProgress', this.downloadProgress); + + this.downloadUpdate = (hash, options) => { + if(this.props.torrent.hash != hash) + return; + + this.setState({ + downloadRemoveOnDone: options.removeOnDone + }) + } + window.torrentSocket.on('downloadUpdate', this.downloadUpdate); } componentWillUnmount() { @@ -220,6 +236,8 @@ export default class Torrent extends Component { window.torrentSocket.off('downloadDone', this.downloadDone); if(this.downloadProgress) window.torrentSocket.off('downloadProgress', this.downloadProgress); + if(this.downloadUpdate) + window.torrentSocket.off('downloadUpdate', this.downloadUpdate); } render() { @@ -231,6 +249,8 @@ export default class Torrent extends Component { if(torrent.good > 0 || torrent.bad > 0) torrentRating = Math.round(rating(torrent.good, torrent.bad) * 100); + const canDeleteDownloadAfterFinish = (this.state.downloading || this.state.startingDownloading) && !this.state.downloaded + return (
+
+ { + // mark delete after finish + canDeleteDownloadAfterFinish + && + + { + e.preventDefault(); + e.stopPropagation(); + window.torrentSocket.emit('downloadUpdate', torrent.hash, {removeOnDone: 'switch'}) + }} viewBox="0 0 512 512"> + + + + + + + + + } { !this.state.startingDownloading && !this.state.downloading && !this.state.downloaded ? @@ -373,7 +433,11 @@ export default class Torrent extends Component { : this.state.startingDownloading && !this.state.downloading ? -
+
{ + e.preventDefault(); + e.stopPropagation(); + window.torrentSocket.emit('downloadCancel', torrent.hash) + }}>
diff --git a/src/background/api.js b/src/background/api.js index 335d130..2baf840 100644 --- a/src/background/api.js +++ b/src/background/api.js @@ -29,6 +29,48 @@ module.exports = async ({ topCache = {}; }, 24 * 60 * 60 * 1000); + + const mergeTorrentsWithDownloads = (torrents) => { + if(!torrents) + return torrents + + const mergeTorrent = (torrent) => { + const id = torrentClientHashMap[torrent.hash] + if(id) + { + const download = torrentClient.get(id) + torrent.download = { + received: download.received, + downloaded: download.downloaded, + progress: download.progress, + downloadSpeed: download.downloadSpeed, + + removeOnDone: download.removeOnDone + } + } + } + + if(Array.isArray(torrents)) + { + for(const torrent of torrents) + { + mergeTorrent(torrent) + } + } + else + { + mergeTorrent(torrents) + } + + return torrents + } + + const mergeTorrentsWithDownloadsFn = (Fn) => (...args) => { + const callback = args[args.length - 1] + const rest = args.slice(0, -1) + Fn(...rest, (data) => callback(mergeTorrentsWithDownloads(data))) + } + recive('recentTorrents', function(callback) { if(typeof callback != 'function') @@ -128,15 +170,6 @@ module.exports = async ({ callback(baseRowData(torrent)) } - if(torrentClientHashMap[hash]) - { - const torrent = torrentClient.get(torrentClientHashMap[hash]) - if(torrent) - { - send('downloading', torrent.infoHash) - } - } - // get votes const {good, bad, selfVote} = await getVotes(hash) send('votes', { @@ -152,7 +185,7 @@ module.exports = async ({ }); } - recive('torrent', onTorrent); + recive('torrent', mergeTorrentsWithDownloadsFn(onTorrent)); p2p.on('torrent', ({hash, options} = {}, callback) => { if(!hash) return; @@ -287,7 +320,7 @@ module.exports = async ({ }); } - recive('searchTorrent', (text, navigation, callback) => { + recive('searchTorrent', mergeTorrentsWithDownloadsFn((text, navigation, callback) => { searchTorrentCall(text, navigation, callback) p2p.emit('searchTorrent', {text, navigation}, (remote, socketObject) => { console.log('remote search results', remote && remote.length) @@ -297,9 +330,9 @@ module.exports = async ({ const peer = { address: socket.remoteAddress, port: socket.remotePort } remote = remote.map(torrent => Object.assign(torrent, {peer})) } - send('remoteSearchTorrent', remote) + send('remoteSearchTorrent', mergeTorrentsWithDownloads(remote)) }) - }); + })); p2p.on('searchTorrent', ({text, navigation} = {}, callback) => { if(!text) @@ -410,7 +443,7 @@ module.exports = async ({ }); } - recive('searchFiles', (text, navigation, callback) => { + recive('searchFiles', mergeTorrentsWithDownloadsFn((text, navigation, callback) => { searchFilesCall(text, navigation, callback) p2p.emit('searchFiles', {text, navigation}, (remote, socketObject) => { console.log('remote search files results', remote && remote.length) @@ -420,9 +453,9 @@ module.exports = async ({ const peer = { address: socket.remoteAddress, port: socket.remotePort } remote = remote.map(torrent => Object.assign(torrent, {peer})) } - send('remoteSearchFiles', remote) + send('remoteSearchFiles', mergeTorrentsWithDownloads(remote)) }) - }); + })); p2p.on('searchFiles', ({text, navigation} = {}, callback) => { if(!text) @@ -485,7 +518,7 @@ module.exports = async ({ }); } - recive('topTorrents', (type, navigation, callback) => + recive('topTorrents', mergeTorrentsWithDownloadsFn((type, navigation, callback) => { topTorrentsCall(type, navigation, callback) p2p.emit('topTorrents', {type, navigation}, (remote, socketObject) => { @@ -498,7 +531,7 @@ module.exports = async ({ } send('remoteTopTorrents', {torrents: remote, type, time: navigation && navigation.time}) }) - }); + })); p2p.on('topTorrents', ({type, navigation} = {}, callback) => { topTorrentsCall(type, navigation, (data) => callback(data)) @@ -604,16 +637,33 @@ module.exports = async ({ torrent.on('ready', () => { console.log('start downloading', torrent.infoHash, 'to', torrent.path) send('downloading', torrent.infoHash) + progress(0) // immediately display progress }) torrent.on('done', () => { console.log('download done', torrent.infoHash) progress(0) // update progress - send('downloadDone', torrent.infoHash) + // remove torrent if marked + if(torrent.removeOnDone) + { + torrentClient.remove(magnet, (err) => { + if(err) + { + console.log('download removing error', err) + return + } + + delete torrentClientHashMap[torrent.infoHash] + send('downloadDone', torrent.infoHash) + }) + } + else + { + send('downloadDone', torrent.infoHash) + } }) let now = Date.now() - progress(0) // immediately display progress torrent.on('download', (bytes) => { if(Date.now() - now < 100) return @@ -624,10 +674,37 @@ module.exports = async ({ if(callback) callback(true) + + return torrent } recive('download', torrentClient._add); + recive('downloadUpdate', (hash, options) => + { + const id = torrentClientHashMap[hash] + if(!id) + { + console.log('cant find torrent for removing', hash) + return + } + + const torrent = torrentClient.get(id) + if(!torrent) { + console.log('no torrent for update founded') + return + } + + if(options.removeOnDone) + { + torrent.removeOnDone = options.removeOnDone == 'switch' ? !torrent.removeOnDone : options.removeOnDone + } + + send('downloadUpdate', torrent.infoHash, { + removeOnDone: torrent.removeOnDone + }) + }) + recive('downloadCancel', (hash, callback) => { const id = torrentClientHashMap[hash] @@ -663,7 +740,9 @@ module.exports = async ({ received: torrent.received, downloaded: torrent.downloaded, progress: torrent.progress, - downloadSpeed: torrent.downloadSpeed + downloadSpeed: torrent.downloadSpeed, + + removeOnDone: torrent.removeOnDone }))) }) @@ -788,7 +867,7 @@ module.exports = async ({ { callback(feed.feed) } - recive('feed', feedCall); + recive('feed', mergeTorrentsWithDownloadsFn(feedCall)); p2p.on('feed', ({}, callback) => { feedCall((data) => callback(data)) diff --git a/src/background/torrentClient.js b/src/background/torrentClient.js index 9cbf56a..7b78fda 100644 --- a/src/background/torrentClient.js +++ b/src/background/torrentClient.js @@ -7,7 +7,9 @@ torrentClient.saveSession = (sessionFile) => { torrents: torrentClient.torrents.map(torrent => ({ infoHash: torrent.infoHash, path: torrent.path, - torrent: torrent.torrentObject + torrent: torrent.torrentObject, + + removeOnDone: torrent.removeOnDone, })) }, null, 4), 'utf8'); } @@ -31,14 +33,20 @@ torrentClient.loadSession = (sessionFile) => { return } const {torrents} = obj - torrents.forEach(({torrent, infoHash, path}) => { + torrents.forEach(({torrent, infoHash, path, removeOnDone}) => { if(!torrent || !infoHash || !path) { console.log('no info for starting download this torrent') return } console.log('restore download session:', torrent.name) - torrentClient._add(torrent, path) + const download = torrentClient._add(torrent, path) + if(download) + { + console.log('restore options') + // restore options + download.removeOnDone = removeOnDone + } }) } module.exports = torrentClient \ No newline at end of file