diff --git a/lib/download.js b/lib/download.js index 5169283..926ecbb 100644 --- a/lib/download.js +++ b/lib/download.js @@ -18,16 +18,15 @@ module.exports = function (type, opts, dat) { var network = null var stats = null var archive = null - var connected = false - var metadataDownloaded = false - var contentPopulated = false + var onceConnected = false // Logging Init var output = [ [ 'Starting Dat...', // Shows Folder Name '', // Shows Link - '', // Shows Downloading Progress Bar + '', // Shows Metadata Progress Bar + '', // Shows Content Progress Bar '', // Shows Total Size Info '' // spacer before network info ], @@ -60,6 +59,13 @@ module.exports = function (type, opts, dat) { archive = dat.archive + archive.open(function () { + if (!archive.content) return removeExit() // Not an archive + archive.content.once('download-finished', checkDone) + }) + // TODO: could be optimized for frequent metadata updates + archive.metadata.on('update', updateDownload) + // General Archive Info var niceType = (type === 'clone') ? 'Cloning' : type.charAt(0).toUpperCase() + type.slice(1) + 'ing' progressOutput[0] = `${niceType} Dat Archive: ${dat.path}` @@ -74,48 +80,11 @@ module.exports = function (type, opts, dat) { network = dat.joinNetwork(opts) network.swarm.once('connection', function (peer) { debug('Network: first peer connected') - connected = true + onceConnected = true progressOutput[2] = 'Starting Download...' - - if (archive.metadata.blocksRemaining() === 0) { - metadataDownloaded = true - archive.metadata.on('update', onMetadataUpdate) - } }) progressOutput[2] = 'Looking for Dat Archive in Network' - // Metadata Download - archive.metadata.once('download-finished', function () { - metadataDownloaded = true - debug('Metadata downloaded') - - // Live metadata updates - // TODO: this can be buggy if there are lots of metadata updates - archive.metadata.on('update', onMetadataUpdate) - }) - - // Content is populated - // TODO: couldn't get one these to work for all situations - // if content.blocks = zero there is no downloads - archive.once('content', function () { - contentPopulated = true - }) - archive.open(function () { - if (!archive.content) return removeExit() - archive.content.once('download', function () { - contentPopulated = true - }) - }) - - function onMetadataUpdate () { - if (metadataDownloaded) { - metadataDownloaded = false - archive.metadata.once('download-finished', function () { - metadataDownloaded = true - }) - } - } - function removeExit () { output[0] = [''] output[1] = [''] @@ -126,23 +95,25 @@ module.exports = function (type, opts, dat) { } function updateDownload () { - var st = stats.get() - - // TODO: blocksTotal may be slow to populate for large metadata, need to handle that - // TODO: currently code is buggy for very frequent metadata updates - if (!metadataDownloaded || !contentPopulated) { + if (!archive.content) { progressOutput[2] = '... Fetching Metadata' - progressOutput[3] = '' return } - // TODO: think about how this could work for empty archives & slow metadata downloads - var progress = st.blocksTotal === 0 ? 100 : Math.round(st.blocksProgress * 100 / st.blocksTotal) - debug('Download Progress:', progress + '%') - if (progress === 100 && checkDone()) return - progressOutput[2] = bar(progress) - if (!connected) progressOutput[3] = 'Waiting for connections to update progress...' - else progressOutput[3] = `Total size: ${st.filesTotal} ${st.filesTotal === 1 ? 'file' : 'files'} (${prettyBytes(st.bytesTotal)})` + if (checkDone()) return + var st = stats.get() + + var metaBlocksProgress = archive.metadata.blocks - archive.metadata.blocksRemaining() + var metaProgress = Math.round(metaBlocksProgress * 100 / archive.metadata.blocks) + var contentProgress = st.blocksTotal === 0 ? 100 : Math.round(st.blocksProgress * 100 / st.blocksTotal) + progressOutput[2] = 'Metadata: ' + bar(metaProgress) + ' ' + metaProgress + '%' + progressOutput[3] = 'Content: ' + bar(contentProgress) + ' ' + contentProgress + '%' + + if (!onceConnected) progressOutput[4] = 'Waiting for connections to check for updates.' + else progressOutput[4] = `Total size: ${st.filesTotal} ${st.filesTotal === 1 ? 'file' : 'files'} (${prettyBytes(st.bytesTotal)})` + + if (metaProgress < 100) debug('Metadata Download Progress:', metaProgress + '%') + if (contentProgress < 100) debug('Download Progress:', contentProgress + '%') } function updateNetwork () { @@ -150,16 +121,16 @@ module.exports = function (type, opts, dat) { } function checkDone () { + if (!onceConnected || archive.metadata.blocksRemaining() !== 0) return false + if (!archive.content || archive.content.blocksRemaining() !== 0) return false + var st = stats.get() - if (!connected || !metadataDownloaded || !contentPopulated) return false - if (st.blocksTotal !== archive.content.blocks) return false // TODO: hyperdrive-stats bug? - if (archive.content.blocksRemaining() !== 0) return false - var sizeMsg = `Total size: ${st.filesTotal} ${st.filesTotal === 1 ? 'file' : 'files'} (${prettyBytes(st.bytesTotal)})` - progressOutput[2] = (type === 'sync') ? 'Files updated to latest!' : 'Download Finished!' - progressOutput[3] = sizeMsg - debug('Download finished', sizeMsg) + progressOutput[2] = '' + progressOutput[3] = (type === 'sync') ? 'Files updated to latest!' : 'Download Finished!' + progressOutput[4] = `Total size: ${st.filesTotal} ${st.filesTotal === 1 ? 'file' : 'files'} (${prettyBytes(st.bytesTotal)})` + debug('Download finished') if (!opts.exit) return true // Exit!