Skip to content

Commit

Permalink
Improve download progess UI and add metadata progress bar (#59)
Browse files Browse the repository at this point in the history
* improve proress and add metadata progress bar

* standard
  • Loading branch information
joehand authored Jan 3, 2017
1 parent c3a4ebe commit 74b1865
Showing 1 changed file with 33 additions and 62 deletions.
95 changes: 33 additions & 62 deletions lib/download.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
],
Expand Down Expand Up @@ -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}`
Expand All @@ -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] = ['']
Expand All @@ -126,40 +95,42 @@ 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 () {
output[1] = ui.network(network.connected, stats.network)
}

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!
Expand Down

0 comments on commit 74b1865

Please sign in to comment.