function getArchive (key, cb) { // if ((typeof key) === 'string') key = encoding.decode(key) // if (Buffer.isBuffer(key)) key = key.toString('hex') console.log('createArchive', [key]) var archive = drive.createArchive(key, {live: true, sparse: true}) var sw = swarm(archive) sw.on('connection', function (peer) { // store.dispatch({ type: 'UPDATE_PEERS', peers: sw.connections }) // peer.on('close', function () { // store.dispatch({ type: 'UPDATE_PEERS', peers: sw.connections }) // }) }) archive.open(function () { if (archive.content) { archive.content.get(0, function (data) { // XXX: Hack to fetch a small bit of data so size properly updates }) } cb(archive) }) // archive.on('download', function () { // store.dispatch({type: 'UPDATE_ARCHIVE', archive: archive}) // }) // archive.on('upload', function () { // store.dispatch({type: 'UPDATE_ARCHIVE', archive: archive}) // }) }
archive.open(function (err) { if (err) return onerror(err) if (argv.resume && !archive.owner) return onerror('You cannot resume this link') logger.status('', 0) // reserve line for file progress logger.status('', 1) // reserve total progress and size logger.status('Creating Link...', 2) // reserve for dat link if ((archive.live || archive.owner) && archive.key) { logger.status(chalk.bold('[Sharing] ') + chalk.blue.underline(archive.key.toString('hex')), 2) var swarm = createSwarm(archive, argv) swarmLogger(swarm, logger) } logger.status(chalk.bold('[Status]'), 3) logger.status(chalk.blue(' Reading Files...'), 4) archive.on('upload', function (data) { stats.bytesTransferred += data.length stats.transferRate(data.length) logger.status(chalk.blue(' Uploading ' + prettyBytes(stats.transferRate()) + '/s'), 5) if (noDataTimeout) clearInterval(noDataTimeout) noDataTimeout = setInterval(function () { logger.status(chalk.blue(' Uploading ' + prettyBytes(stats.transferRate()) + '/s'), 5) }, 100) }) each(walker(dir), appendEntry, done) })
archive.finalize(() => { swarm(archive) downloadArchiveFile(archive, fileURL, () => { fileHashes[signature(fileURL)] = archive.key.toString('hex') hub.broadcast(channel, {type: 'hash', hashes: fileHashes}) }) })
archive.finalize(function (err) { if (err) return onerror(err) if (!archive.live) { logger.status(chalk.bold('[Sharing] ') + chalk.blue.underline(archive.key.toString('hex')), 2) logger.status(chalk.blue(' Static Dat Finalized'), 4) logger.status(chalk.blue(' Waiting for connections...'), -1) var swarm = createSwarm(archive, argv) swarmLogger(swarm, logger) return } var dirName = dir === '.' ? process.cwd() : dir logger.status(chalk.blue(' Watching ' + chalk.bold(dirName) + '...'), 4) logger.status(chalk.blue(' Waiting for connections...'), -1) yoloWatch(dir, function (name, st) { logger.status(' ' + name, 0) archive.append({type: st.isDirectory() ? 'directory' : 'file', name: name}, function () { logger.message(chalk.green.dim(' [Done] ') + chalk.dim(name)) logger.status('', 0) printTotalStats() }) }) })
archive.finalize(function (err) { if (err) return onerror(err) db.put('!dat!finalized', true) if (args.snapshot) { logger.status(printDatLink(archive.key), 1) swarm = createSwarm(archive, args) swarmLogger(swarm, logger, 'Sharing Snapshot ' + dir) return } var watcher = yoloWatch(dir) watcher.on('changed', function (name, stat) { // TODO: make yolowatch data consistent w/ folder-walker if (name === dir) return var data = { filepath: name, stat: stat, relname: path.relative(dir, name), basename: path.basename(name) } appendEntry(data, function () {}) }) watcher.on('added', function (file, stat) { appendEntry(stat, function () {}) }) })
function getArchive (key, cb) { var archive = drive.createArchive(key, {live: true}) var sw = swarm(archive) sw.on('connection', function (peer) { updatePeers(sw.connections) peer.on('close', function () { updatePeers(sw.connections) }) }) archive.open(function () { cb(archive) }) attachSpeedometer(archive) }
export function swarm (key) { var [keyBuf, keyStr] = bufAndStr(key) // fetch if (keyStr in swarms) return swarms[keyStr] // create log('[DAT] Swarming archive', keyStr) var archive = getArchive(key) var s = hyperdriveArchiveSwarm(archive) swarms[keyStr] = s s.on('peer', peer => log('[DAT] Peer', peer)) // TODO this is no longer giving us peer info return s }
archive.open(function (err) { if (err) return onerror(err) if (key && !archive.owner) { logger.message('External Dat already exists in directory.') logger.message('Run ' + chalk.bold('dat ' + key.toString('hex')) + ' to update.') logger.logNow() process.exit(0) } logger.message('Initializing Dat in ' + dir) logger.status('', 0) // reserve total progress and size if (key) logger.status(printDatLink(archive.key), 1) else logger.status('Creating Share Link...', 1) // reserve for dat link logger.status('The Share Link is secret and only those you share it with will be able to get the files', 2) if ((archive.live || archive.owner) && archive.key) { if (!key) db.put('!dat!key', archive.key.toString('hex')) logger.status(printDatLink(archive.key), 1) swarm = createSwarm(archive, args) swarmLogger(swarm, logger, 'Sharing ' + dir) } archive.on('upload', function (data) { stats.bytesTransferred += data.length stats.transferRate(data.length) var msg = 'Uploading ' + prettyBytes(stats.transferRate()) + '/s' msg += ', ' + prettyBytes(stats.bytesTransferred) + ' Total' logger.status(msg, -1) if (noDataTimeout) clearInterval(noDataTimeout) noDataTimeout = setInterval(function () { var msg = 'Uploading ' + prettyBytes(stats.transferRate()) + '/s' msg += ', ' + prettyBytes(stats.bytesTransferred) + ' Total' logger.status(msg, -1) }, 100) }) if (args.resume) { db.get('!dat!finalized', function (err, val) { if (err || val !== 'true') return walkFolder(true) else walkFolder(true) // TODO: check mtimes }) } else { walkFolder() } })
function main (key) { $hyperdrive.innerHTML = '' archive = drive.createArchive(key, {live: true}) swarm(archive) var help = document.querySelector('#help-text') if (key && !archive.owner) help.innerHTML = 'looking for peers...' else if (archive.owner) help.innerHTML = 'drag and drop files' window.location = '#' + archive.key.toString('hex') var widget = explorer(archive) $hyperdrive.appendChild(widget) var stream = archive.list({live: true}) stream.on('data', function (entry) { if (archive.owner) help.innerHTML = 'drag and drop files' else help.innerHTML = '' }) }
function download (fileURL) { if (fileHashes[signature(fileURL)]) { // if it's a known file in fileHashes, use peerdownload var archive = drive.createArchive(fileHashes[signature(fileURL)]) swarm(archive) downloadArchiveFile(archive, fileURL, () => { console.log('done') }) } else { var archive = drive.createArchive() var ws = archive.createFileWriteStream('data') http.get(fileURL, (res) => { res.pipe(ws).on('finish', () => { archive.finalize(() => { swarm(archive) downloadArchiveFile(archive, fileURL, () => { fileHashes[signature(fileURL)] = archive.key.toString('hex') hub.broadcast(channel, {type: 'hash', hashes: fileHashes}) }) }) }) }) } }
function downloadArchive () { var drive = hyperdrive(db) var archive = drive.createArchive(Buffer(key, 'hex'), { file: function (name) { return raf(path.join(dir, name)) } }) logger.message('Initializing Dat from ' + chalk.blue.underline(archive.key.toString('hex'))) logger.status('', 0) // total progress and size logger.status(printDatLink(archive.key), 1) logger.status('The Share Link is secret and only those you share it with will be able to get the files', 2) var swarm = createSwarm(archive, args) swarmLogger(swarm, logger, 'Downloading to ' + pathName) archive.on('download', function (data) { if (noDataTimeout) clearInterval(noDataTimeout) stats.bytesTransferred += data.length stats.transferRate(data.length) logger.status('Downloading ' + prettyBytes(stats.transferRate()) + '/s', -1) printTotalStats() noDataTimeout = setInterval(function () { logger.status(chalk.blue('Waiting for Data...'), -1) }, 1000) }) archive.open(function (err) { if (err) return onerror(err) db.put('!dat!key', archive.key.toString('hex')) logger.status('', 0) each(archive.list({live: archive.live}), function (data, next) { var startBytes = stats.bytesTransferred printTotalStats() archive.download(data, function (err) { if (err) return onerror(err) var msg = chalk.green.dim('[DONE] ') + chalk.dim(data.name) if (data.type === 'file') msg += chalk.dim(' (' + prettyBytes(data.length) + ')') logger.message(msg) stats.filesTransferred += 1 if (startBytes === stats.bytesTransferred) stats.bytesTransferred += data.length // file already exists printTotalStats() if (stats.filesTransferred === stats.filesTotal) done() else next() }) }, done) }) function done () { printTotalStats() if (args.exit) { if (archive.live) logger.status('Download Finished, Run Again to Update', 3) else logger.status('Download of Snapshot Finished', 3) logger.status('', -1) // remove peer count logger.logNow() process.exit(0) } logger.status('Download Finished, you may exit process', -1) if (archive.live) swarmLogger(swarm, logger, 'Syncing live updates') else swarmLogger(swarm, logger, 'Sharing data') } function printDatLink (key) { return chalk.bold('Share Link ') + chalk.blue.underline(key.toString('hex')) } function printTotalStats () { var msg = '' var totalPer = 0 var done = (stats.bytesTransferred === stats.bytesTotal) stats.filesTotal = archive.metadata.blocks - 1 // first block is header stats.bytesTotal = archive.content.bytes totalPer = Math.floor(100 * (stats.bytesTransferred / stats.bytesTotal)) if (done) msg += chalk.bold.green('[DONE] ') else msg += chalk.bold('[' + (' ' + totalPer).slice(-3) + '%] ') if (done) { msg += stats.filesTransferred + ' items' msg += chalk.dim(' (' + prettyBytes(stats.bytesTransferred) + ')') } else { msg += stats.filesTransferred + ' of ' + stats.filesTotal + ' items' msg += chalk.dim(' (' + prettyBytes(stats.bytesTransferred) + ' of ') msg += chalk.dim(prettyBytes(stats.bytesTotal) + ')') } logger.status(msg, 0) } }
var level = require('level-browserify') var drop = require('drag-drop') var fileReader = require('filereader-stream') var choppa = require('choppa') var swarm = require('hyperdrive-archive-swarm') var db = level('./hyperdrive6') var drive = hyperdrive(db) var explorer = require('./') var $display = document.querySelector('#display') var $hyperdrive = document.querySelector('#hyperdrive-ui') var url = window.location.toString() var key = url.split('#')[1] var archive = drive.createArchive(key, {live: true}) swarm(archive) var file if (key) file = key.split('/').splice(1).join('/') if (!file) main(key) else { archive.createFileReadStream(file).pipe(concat(function (data) { document.write(data) })) } var button = document.querySelector('#new') button.onclick = function () { main(null) } function main (key) { $hyperdrive.innerHTML = ''
function join () { swarm(archive || f) }
// RUN: // node bonus.js <dat-link> <filename> var memdb = require('memdb') var Hyperdrive = require('hyperdrive') var Swarm = require('hyperdrive-archive-swarm') var link = process.argv[2] // user enters link as second argument var file = process.argv[3] // test file as third argument if (!link || !file) { console.error('Link and File required.') process.exit(1) } var db = memdb() var drive = Hyperdrive(db) var archive = drive.createArchive(link) var swarm = Swarm(archive) var stream = archive.createFileReadStream(file) stream.on('end', function (err) { process.exit(0) }) stream.on('error', function (err) { console.error('File does not exist.') process.exit(1) }) stream.pipe(process.stdout)
module.exports = function (argv) { var key = argv._[0] var drive = hyperdrive(memdb()) var archive = drive.createArchive(Buffer(key, 'hex'), { file: function (name) { return raf(name) } }) var noDataTimeout = null var stats = { filesTotal: 0, bytesTotal: 0, filesTransferred: 0, bytesTransferred: 0, transferRate: speedometer() } var logger = statusLogger(argv) logger.message(chalk.gray('Starting Dat: ') + chalk.blue.underline(archive.key.toString('hex')) + '\n') logger.status(chalk.gray('Getting Information...'), 0) // reserve line for file progress logger.status(chalk.bold(''), 1) // TODO: total progress and size logger.status(chalk.bold('[Joining] ') + chalk.blue.underline(archive.key.toString('hex')), 2) logger.status(chalk.bold('[Status]'), 3) logger.status(chalk.blue(' Looking for Peers...'), -1) var swarm = createSwarm(archive, argv) swarmLogger(swarm, logger) archive.on('download', function (data) { if (noDataTimeout) clearInterval(noDataTimeout) stats.bytesTransferred += data.length stats.transferRate(data.length) logger.status(chalk.bold('[Downloading] ') + chalk.blue.underline(archive.key.toString('hex')), 2) logger.status(chalk.blue(' Downloading ' + prettyBytes(stats.transferRate()) + '/s'), 4) printTotalStats() noDataTimeout = setInterval(function () { logger.status(chalk.blue(' Waiting for Data...'), 4) }, 1000) }) each(archive.list({live: argv.live}), function (data, next) { printTotalStats() if (stats.bytesTransferred === 0) { logger.status(' Getting Metadata...', 0) // HACK } else { logger.status(' ' + data.name, 0) // TODO: actual progress % } archive.download(data, function (err) { if (err) return onerror(err) logger.message(chalk.green.dim(' [Done] ') + chalk.dim(data.name)) logger.status('', 0) // clear file progress msg stats.filesTransferred += 1 printTotalStats() next() }) }, function () { logger.status(chalk.bold('[Downloaded] ') + chalk.blue.underline(archive.key.toString('hex'))) logger.status('', -1) // remove peer count printTotalStats() logger.logNow() process.exit(0) }) function printTotalStats () { stats.filesTotal = archive.metadata.blocks - 1 // first block is header stats.bytesTotal = archive.content ? archive.content.bytes : 0 var totalPer = Math.floor(100 * (stats.bytesTransferred / stats.bytesTotal)) var msg = '' if (totalPer === 100) msg += chalk.bold.green('[Done] ') else if (totalPer >= 0) msg += chalk.bold('[' + (' ' + totalPer).slice(-3) + '%] ') else msg += ' ' msg += stats.filesTransferred + ' of ' + stats.filesTotal + ' files' msg += chalk.dim(' (' + prettyBytes(stats.bytesTransferred) + ' of ') msg += chalk.dim(prettyBytes(stats.bytesTotal) + ') ') logger.status(msg, 1) } function onerror (err) { console.error(err.stack || err) process.exit(1) } }