Skip to content

Instantly share code, notes, and snippets.

@TheJaredWilcurt
Created October 15, 2015 19:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheJaredWilcurt/deb276067f38bae4e873 to your computer and use it in GitHub Desktop.
Save TheJaredWilcurt/deb276067f38bae4e873 to your computer and use it in GitHub Desktop.
'use strict';
var Q = require('q');
var fs = require('fs');
var path = require('path');
var mkdirp = require('mkdirp');
var spawn = require('child_process').spawn;
var ncp = require('ncp').ncp;
var rimraf = require('rimraf');
var http = require('http');
var EventEmitter = require('events').EventEmitter;
var fstream = require('fstream');
var utils = require('./utils');
var URL_FORMAT = 'http://dl.nwjs.io/v{version}/nwjs-v{version}-{platform}-{arch}.{ext}';
var downloader = module.exports = new EventEmitter();
downloader.download = function (dist, version, cb) {
var data = {};
version = version.replace(/^v/i, '');
try {
data.platform = downloader.detectPlatform(version);
} catch (e) {
return cb(e);
}
data.url = downloader.getFileUrl(version, data.platform.type, data.platform.arch);
downloader.emit('log', {
level: 'info',
message: 'File: ' + data.url
});
var clean = function (err) {
if (data.tmp) {
downloader.emit('log', {
level: 'verbose',
message: 'Remove tmp folder.'
});
downloader.clean(data.tmp)
.then(function () {
cb(err);
}, cb);
} else {
cb(err);
}
};
Q.nfcall(mkdirp, dist)
.then(function () {
downloader.emit('log', {
level: 'verbose',
message: 'Check if node-webkit v' + version + ' exists.'
});
return downloader.doesExist(dist, version)
})
.then(function (args) {
if (args[0]) {
throw new Error('node-webkit v' + version + ' is already install.');
}
data.dist = args[1];
})
.then(function () {
downloader.emit('log', {
level: 'verbose',
message: 'Create tmp folder.'
});
return downloader.createTmpFolder(dist);
})
.then(function (tmp) {
var temp = path.join(dist, 'tmp');
data.tmp = temp;
})
.then(function () {
downloader.emit('log', {
level: 'info',
message: 'Start downloading.'
});
data.tmpFile = path.join(data.tmp, 'node-webkit');
return downloader.downloadFile(data.url, data.tmpFile);
})
.then(function () {
downloader.emit('log', {
level: 'info',
message: 'Extract file.'
});
data.tmpExtract = path.join(data.tmp, version);
return downloader.uncompress(data.platform.type, data.tmpFile, data.tmpExtract);
})
.then(function () {
downloader.emit('log', {
level: 'info',
message: 'Copy files.'
});
return downloader.copyTmpFolder(data.tmpExtract, data.dist);
})
.then(function () {
clean();
}, function (err) {
clean(err);
})
};
downloader.detectPlatform = function () {
var platform = {
darwin: 'mac',
win32: 'windows',
win64: 'windows',
linux: 'linux'
};
if (!platform.hasOwnProperty(process.platform)) {
throw new Error(process.platform + ' is not supported');
}
var type = platform[process.platform];
var arch = 'ia32';
if (type === 'linux') {
arch = process.arch;
}
return {
type: type,
arch: arch
};
};
downloader.getFileUrl = function (version, platform, arch) {
var ext = {
linux: 'tar.gz',
windows: 'zip',
mac: 'zip'
};
var platformShorname = {
linux: 'linux',
windows: 'win',
mac: 'osx'
};
var url = utils.format(URL_FORMAT, {
version: version,
platform: platformShorname[platform],
arch: arch,
ext: ext[platform]
});
return url;
};
downloader.generateDistFolderName = function (dist, version) {
return path.join(dist, version);
};
downloader.doesExist = function (dist, version) {
var dist = downloader.generateDistFolderName(dist, version);
var promise = Q.nfcall(function (cb) {
fs.exists(dist, function (exists) {
cb(null, exists, dist);
});
});
return promise;
};
downloader.createTmpFolder = function (dist) {
var folder = path.join(dist, 'tmp');
return Q.nfcall(mkdirp, folder);
};
downloader.downloadFile = function (url, file) {
var deferred = Q.defer();
http.get(url, function (res) {
var stream = fs.createWriteStream(file);
var progress = {};
var done = false;
progress.total = res.headers['content-length'];
progress.count = 0;
downloader.emit('startDownloading', res);
res.pipe(stream);
res.on('error', function (err) {
if (!done) {
done = true;
downloader.emit('downloadFinished');
deferred.reject(err);
}
});
res.on('data', function (chunk) {
progress.count += chunk.length;
downloader.emit('downloadProgress', {
total: progress.total,
progress: progress.count
});
});
stream.on('finish', function () {
if (!done) {
done = true;
downloader.emit('downloadFinished');
deferred.resolve(file);
}
});
});
return deferred.promise;
};
downloader.uncompress = function (platform, file, dist) {
if (platform === 'linux') {
return downloader.untar.apply(null, arguments);
} else {
return downloader.unzip.apply(null, arguments);
}
};
downloader.unzip = function (platform, file, dist) {
var deferred = Q.defer();
var unzip = platform === 'windows' ? path.join(__dirname, '../bin/unzip.exe') : 'unzip';
var cmd = spawn(unzip, [file, '-d', dist]);
var errmsg = [];
cmd.stderr.on('data', function (data) {
errmsg.push(data);
});
cmd.on('close', function (code) {
if (code === 1) {
deferred.reject(new Error(errmsg.join('\n')));
} else {
deferred.resolve();
}
});
return deferred.promise;
};
downloader.untar = function (platform, file, dist) {
var deferred = Q.defer();
var dir = path.dirname(dist);
mkdirp(dist, function (err) {
if (err) {
return deferred.reject(err);
}
var cmd = spawn('tar', ['-xf', file, '-C', dist, '--strip-components', 1]);
var errmsg = [];
cmd.stderr.on('data', function (data) {
errmsg.push(data);
});
cmd.on('close', function (code) {
if (code === 1) {
deferred.reject(new Error(errmsg.join('\n')));
} else {
deferred.resolve();
}
});
});
return deferred.promise;
};
downloader.copyTmpFolder = function (tmp, dist) {
return Q.nfcall(ncp, tmp, dist);
};
downloader.clean = function (tmp) {
return Q.nfcall(rimraf, tmp);
};
downloader.getExecutableFilePath = function (version, basedir) {
version = version.replace(/^v/i, '');
var platform = downloader.detectPlatform();
var filename = [basedir, version];
switch (platform.type) {
case 'windows':
filename.push('nw.exe');
break;
case 'linux':
filename.push('nw');
break;
case 'mac':
filename.push('node-webkit.app/Contents/MacOS/node-webkit');
break;
}
return path.join.apply(path, filename);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment