diff --git a/package.json b/package.json
index a5aa696b..4877a4c9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ubports-installer",
- "version": "0.1.0-beta2",
+ "version": "0.1.2-beta",
"description": "Ubports installer",
"main": "src/main.js",
"bin": "./src/main.js",
@@ -32,14 +32,15 @@
"bootstrap": "^3.3.7",
"checksum": "^0.1.1",
"commander": "^2.9.0",
- "decompress-tarxz": "^2.1.0",
"electron-open-link-in-browser": "^1.0.2",
"electron-sudo": "^3.0.13",
"executable": "^4.1.0",
"forward-emitter": "^0.1.1",
"fs-extra": "^2.0.0",
+ "getos": "^3.0.1",
"ini": "^1.3.4",
"jquery": "^3.1.1",
+ "jquery-i18next": "^1.2.0",
"mkdirp": "^0.5.1",
"openurl": "^1.1.1",
"request": "^2.79.0",
diff --git a/src/adb.js b/src/adb.js
index 926b5465..717c546e 100644
--- a/src/adb.js
+++ b/src/adb.js
@@ -85,6 +85,7 @@ var push = (file, dest, pushEvent) => {
}
var pushMany = (files, pushManyEvent) => {
+ var totalLenght = files.length;
if (files.length <= 0){
pushManyEvent.emit("adbpush:error", "No files provided");
return false;
@@ -97,7 +98,7 @@ var pushMany = (files, pushManyEvent) => {
pushManyEvent.emit("adbpush:done");
return;
}
- pushManyEvent.emit("adbpush:next", files.length)
+ pushManyEvent.emit("adbpush:next", files.length, totalLenght)
push(files[0].src, files[0].dest, pushManyEvent);
})
return pushManyEvent
diff --git a/src/devices.js b/src/devices.js
index 928d94c2..144c7878 100644
--- a/src/devices.js
+++ b/src/devices.js
@@ -231,7 +231,7 @@ var setEvents = (downloadEvent) => {
downloadEvent.emit("user:write:next", "Downloading", i, t);
});
downloadEvent.on("download:next", (i, t) => {
- utils.log.info(`Downloading next file, ${i} left`);
+ utils.log.info(`Downloading next file, ${i} left, ${t} total`);
downloadEvent.emit("user:write:next", "Downloading", i, t);
});
downloadEvent.on("download:progress", (i) => {
@@ -252,9 +252,9 @@ var setEvents = (downloadEvent) => {
utils.log.info("Adb push, "+r+"% left");
downloadEvent.emit("user:write:progress", r);
});
- downloadEvent.on("adbpush:next", (r) => {
+ downloadEvent.on("adbpush:next", (r, t) => {
utils.log.info("Start pusing next file, " + r + " files left")
- downloadEvent.emit("user:write:next", "Pushing", r);
+ downloadEvent.emit("user:write:next", "Pushing", r, t);
});
downloadEvent.on("adbpush:start", (r) => {
utils.log.info("Start pusing "+r+" files")
@@ -377,6 +377,13 @@ module.exports = {
getDeviceSelects: (callback) => {
getDevices((devices) => {
var devicesAppend = [];
+ devices.sort(function(a, b){
+ var y = a.name.toLowerCase();
+ var x = b.name.toLowerCase();
+ if (x < y) {return -1;}
+ if (x > y) {return 1;}
+ return 0;
+ });
devices.forEach((device) => {
devicesAppend.push("");
})
diff --git a/src/fastboot.js b/src/fastboot.js
index 29534f16..48516968 100644
--- a/src/fastboot.js
+++ b/src/fastboot.js
@@ -10,7 +10,13 @@ const path = require("path");
const utils = require("./utils.js")
const fastboot = utils.getPlatformTools().fastboot;
+/*
+
+args; string, function
+
+*/
var waitForDevice = (password, callback) => {
+ utils.log.debug("fastboot: wait for device");
var cmd = "";
if (utils.needRoot())
cmd += "echo " + password + " | sudo -S "
@@ -52,7 +58,22 @@ var waitForDevice = (password, callback) => {
// Due to limitations with sudo we combind the sudo.exec to one call to prevent
// seperate password prompts
+/*
+
+args; array(object), string, function
+
+image object format
+[
+ {
+ path: string, | path of file
+ url: string, | url to extract filename
+ type: string | partition to flash
+ }
+]
+
+*/
var flash = (images, callback, password) => {
+ utils.log.debug("fastboot: flash; " + images);
var cmd = "";
images.forEach((image, l) => {
if (utils.needRoot())
@@ -77,6 +98,19 @@ var flash = (images, callback, password) => {
});
}
+/*
+
+args; array(object), string, function
+
+image object format
+[
+ {
+ path: string, | path of file
+ url: string | url to extract filename
+ }
+]
+
+*/
var boot = (image, password, callback) => {
var cmd="";
if (utils.needRoot())
@@ -97,9 +131,39 @@ var boot = (image, password, callback) => {
})
});
}
+/*
+
+args; array, string, function
+
+*/
+var format = (partitions, password, callback) => {
+ var cmd="";
+ partitions.forEach((partition, l) => {
+ if (utils.needRoot())
+ cmd += "echo " + password + " | sudo -S "
+ cmd += fastboot + " format " + partition;
+ if (l !== partitions.length - 1)
+ cmd += " && "
+ });
+ utils.asarExec(fastboot, (asarExec) => {
+ asarExec.exec(cmd, (c, r, e) => {
+ if (c) {
+ if (c.message.includes("incorrect password"))
+ callback({
+ password: true
+ });
+ else callback(true, "Fastboot: Unknown error: " + r.replace(password, "***") + " " + e.replace(password, "***"));
+ } else {
+ callback(c, r, e)
+ }
+ asarExec.done();
+ })
+ });
+}
module.exports = {
flash: flash,
waitForDevice: waitForDevice,
- boot: boot
+ boot: boot,
+ format: format
}
diff --git a/src/html/index.html b/src/html/index.html
index c6e60ee2..faa60fe2 100644
--- a/src/html/index.html
+++ b/src/html/index.html
@@ -34,9 +34,9 @@
Please connect your device
-
+
@@ -211,131 +211,157 @@
Password needed to continue
var openurl = require("openurl");
var devices = require('../devices.js');
var systemImage = require("../system-image.js");
+ var utils = require("../utils.js")
$("#main-wait-for-device").show();
+ var onErr = (err) => {
+ $("#error-body").text(err);
+ $("#errorModal").modal("show");
+ }
+ $("#btn-bugreport").click(() => {
+ var title = $("#error-body").text();
+ utils.createBugReport(title, (body) => {
+ openurl.open("https://github.com/ubports/ubports-installer/issues/new?title="+title+"&body="+body);
+ });
+ })
+
devices.getDeviceSelects((out) => {
$("#device-select").append(out);
});
- var waitEvent = devices.waitForDevice((output, device, channels) => {
- $("#main-wait-for-device").hide();
- $("#waitForDevice").hide();
- $("#device").show();
- if(!output) {
- $("#device-name").text("Device not supported");
- $("#device-under-text").text("The device " + device + " is not supported");
- $("[id=your-device]").text(device)
- $("#main-not-supported").show();
- $("#btn-inst").hide();
- }else {
- $("#device-channels").append(channels);
- $("#btn-inst").show();
- $("#device-name").text(output.device.name);
- $("#your-ubp-device").text(output.device.name+" ("+output.device.device+")")
- $("#your-ubp-device").click(() => {
- openurl.open("https://devices.ubports.com/#/"+output.device.device);
- })
- var notWorking = devices.getFormatedNotWorking(output.device.whatIsWorking);
- if (notWorking)
- $("#not-working").text(notWorking);
- else
- $("#not-working-block").hide();
- $("#main-install").show();
- $("#btn-inst").click(() => {
- $('#installModal').modal('show')
- })
- $("#btn-installModal").click(() => {
- $("#main-install").hide();
- $("#main-installing").show();
- $("#progress").show();
- const installEvent= devices.install(output.device.device,
- $("#device-channels").find(":selected").val())
-
- installEvent.on("bootstrap:flashing", () => {
- $("#main-installing").show();
- $("#main-reboot-up").hide();
- $("#main-reboot-down").hide();
- $("#device-under-text").text("Flashing recovery and boot images")
+ if (!utils.debugScreen()) {
+ var waitEvent = devices.waitForDevice((output, device, channels) => {
+ $("#main-wait-for-device").hide();
+ $("#waitForDevice").hide();
+ $("#device").show();
+ if(!output) {
+ $("#device-name").text("Device not supported");
+ $("#device-under-text").text("The device " + device + " is not supported");
+ $("[id=your-device]").text(device)
+ $("#main-not-supported").show();
+ $("#btn-inst").hide();
+ }else {
+ $("#device-channels").append(channels);
+ $("#btn-inst").show();
+ $("#device-name").text(output.device.name);
+ $("#your-ubp-device").text(output.device.name+" ("+output.device.device+")")
+ $("#your-ubp-device").click(() => {
+ openurl.open("https://devices.ubports.com/#/"+output.device.device);
})
-
- installEvent.on("system-image:start", () => {
- $("#main-installing").show();
- $("#main-reboot-up").hide();
- $("#main-reboot-down").hide();
+ var notWorking = devices.getFormatedNotWorking(output.device.whatIsWorking);
+ if (notWorking)
+ $("#not-working").text(notWorking);
+ else
+ $("#not-working-block").hide();
+ $("#main-install").show();
+ $("#btn-inst").click(() => {
+ $('#installModal').modal('show')
})
+ $("#btn-installModal").click(() => {
+ $("#main-install").hide();
+ $("#main-installing").show();
+ $("#progress").show();
+ const installEvent= devices.install(output.device.device,
+ $("#device-channels").find(":selected").val())
- installEvent.on("install:done", () => {
- $("#main-done").show();
- $("#main-installing").hide();
- $("#main-reboot-up").hide();
- $("#main-reboot-down").hide();
- });
+ installEvent.on("user:error", onErr);
- installEvent.on("user:password", () => {
- $('#password').modal('show');
- $("#password-input").val("");
- $("#password-input").keypress((event) => {
- if (event.which == '13') {
- event.preventDefault();
+ installEvent.on("bootstrap:flashing", () => {
+ $("#main-installing").show();
+ $("#main-reboot-up").hide();
+ $("#main-reboot-down").hide();
+ $("#device-under-text").text("Flashing recovery and boot images")
+ })
+
+ installEvent.on("system-image:start", () => {
+ $("#main-installing").show();
+ $("#main-reboot-up").hide();
+ $("#main-reboot-down").hide();
+ })
+
+ installEvent.on("install:done", () => {
+ $("#main-done").show();
+ $("#main-installing").hide();
+ $("#main-reboot-up").hide();
+ $("#main-reboot-down").hide();
+ });
+
+ installEvent.on("user:password", () => {
+ $('#password').modal('show');
+ $("#password-input").val("");
+ $("#password-input").keypress((event) => {
+ if (event.which == '13') {
+ event.preventDefault();
+ installEvent.emit("password", $("#password-input").val());
+ $('#password').modal('hide');
+ $('#password-wrong').hide();
+ }
+ });
+ $("#btn-password").click(() => {
installEvent.emit("password", $("#password-input").val());
- $('#password').modal('hide');
$('#password-wrong').hide();
- }
});
- $("#btn-password").click(() => {
- installEvent.emit("password", $("#password-input").val());
- $('#password-wrong').hide();
- });
- });
+ });
- installEvent.on("user:error", (err) => {
- $("#errorModal").modal("show");
- })
+ installEvent.on("user:password:wrong", () => {
+ installEvent.emit("user:password");
+ $('#password-wrong').show();
+ })
- $("#btn-bugreport").click(() => {
- openurl.open("https://github.com/ubports/ubports-installer/issues/new?title=error&body=")
- })
+ installEvent.on("user:reboot", (i) => {
+ $("#main-installing").hide();
+ $("#main-reboot-"+i.button).show();
+ $("[id=reboot-to-state]").text(i.state);
+ $("#device-name").text("Please reboot to "+i.state);
+ $("#device-under-text").text("")
+ })
+ installEvent.on("user:write:next", (text,length, total) => {
+ $("#device-under-text").text(text+" file "+(total-(length-1))+" of "+total)
+ $("#progress").width("0%");
+ })
+ installEvent.on("user:write:start", (text, length) => {
+ $("#device-under-text").text(text+" file 1 of "+length)
+ $("#progress").width("0%");
+ })
+ installEvent.on("user:write:progress", (length) => {
+ if(length >= 100) {
+ length=100;
+ }
+ $("#progress").width(length.toString()+"%");
+ })
+ installEvent.on("user:write:done", () => {
+ $("#device-under-text").text("")
+ $("#progress").width("0%");
+ })
+ installEvent.on("user:write:status", (status) => {
+ $("#device-name").text(status).append(".");
+ })
- installEvent.on("user:password:wrong", () => {
- installEvent.emit("user:password");
- $('#password-wrong').show();
+ utils.debugTrigger(installEvent, 2);
})
+ }
+ });
- installEvent.on("user:reboot", (i) => {
- $("#main-installing").hide();
- $("#main-reboot-"+i.button).show();
- $("[id=reboot-to-state]").text(i.state);
- $("#device-name").text("Please reboot to "+i.state);
- $("#device-under-text").text("")
- })
- installEvent.on("user:write:next", (text,length, total) => {
- $("#device-under-text").text(text+" file "+(total-(length-1))+" of "+total)
- $("#progress").width("0%");
- })
- installEvent.on("user:write:start", (text, length) => {
- $("#device-under-text").text(text+" file 1 of "+length)
- $("#progress").width("0%");
- })
- installEvent.on("user:write:progress", (length) => {
- if(length >= 100) {
- length=100;
- }
- $("#progress").width(length.toString()+"%");
- })
- installEvent.on("user:write:done", () => {
- $("#device-under-text").text("")
- })
- installEvent.on("user:write:status", (status) => {
- $("#device-name").text(status).append(".");
- })
- })
+ $("#btn-device-select").click(() => {
+ var device = $("#device-select").find(":selected").attr("name");
+ waitEvent.emit("device:select", device);
+ })
+ }else {
+ if (utils.debugScreen().startsWith("modal:")){
+ var modal=utils.debugScreen().split(":")[1]
+ setTimeout(function () {
+ $("#"+modal).modal("show");
+ }, 10);
+ } else {
+ $("#main-wait-for-device").hide();
+ $("#waitForDevice").hide();
+ $("#"+utils.debugScreen()).show()
}
- });
+ }
- $("#btn-device-select").click(() => {
- var device = $("#device-select").find(":selected").attr("name");
- waitEvent.emit("device:select", device);
- })
+ waitEvent.on("user:error", onErr);
+
+ utils.debugTrigger(waitEvent, 1);
require('bootstrap')
diff --git a/src/main.js b/src/main.js
index cc5cacfc..c72f16f9 100755
--- a/src/main.js
+++ b/src/main.js
@@ -18,7 +18,10 @@ const url = require('url')
let mainWindow
function createWindow () {
- mainWindow = new BrowserWindow({width: 800, height: 600})
+ if (process.env.DEBUG)
+ mainWindow = new BrowserWindow({width: 1600, height: 600})
+ else
+ mainWindow = new BrowserWindow({width: 800, height: 600})
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, 'html/index.html'),
diff --git a/src/utils.js b/src/utils.js
index 370950a3..e23a536a 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -6,6 +6,8 @@ Author: Marius Gripsgard
*/
+const version = "0.1.2-beta"
+
const http = require("request");
const progress = require("request-progress");
const os = require("os");
@@ -17,6 +19,7 @@ const tmp = require('tmp');
const exec = require('child_process').exec;
const sudo = require('electron-sudo');
const winston = require('winston');
+const getos = require('getos')
//const decompress = require('decompress');
//const decompressTarxz = require('decompress-tarxz');
@@ -26,6 +29,21 @@ const platforms = {
"win32": "win"
}
+var debugScreen = () => {
+ return process.env.DEBUG ? process.env.SCREEN : null
+}
+
+var debugTrigger = (event, stage) => {
+ if (!process.env.DEBUG || !process.env.TRIGGER)
+ return
+ var args = process.env.TRIGGER.split(",");
+ if (stage ==! args[1])
+ return
+ setTimeout(function () {
+ event.emit(args[1], args[2]);
+ }, 10);
+}
+
var log = {
error: (l) => {winston.log("error", l)},
warn: (l) => {winston.log("warn", l)},
@@ -33,6 +51,50 @@ var log = {
debug: (l) => {winston.log("debug", l)}
}
+var createBugReport = (title, callback) => {
+ var options = {
+ limit: 400,
+ start: 0,
+ order: 'desc'
+ };
+
+ winston.query(options, function (err, results) {
+ if (err) {
+ throw err;
+ }
+
+ var errorLog = ""
+ results.file.forEach((err) => {
+ errorLog+=err.level+" "
+ errorLog+=err.timestamp+" "
+ errorLog+=err.message+"\n"
+ })
+
+ http.post({
+ url: "http://paste.ubuntu.com",
+ form: {
+ poster: "Ubports installer bug",
+ syntax: "text",
+ content: "Title: "+title+
+ "\n"+errorLog
+ }
+ }, (err, res, bod) => {
+ if (!err && res.statusCode === 302)
+ getos((e,gOs) => {
+ callback("Automatically generated error report %0A\
+Version: "+version+" %0A\
+Host OS: "+gOs.os+" %0A\
+Host Dist: "+gOs.dist+" "+gOs.release+ "%0A\
+Host Arch: "+os.arch()+" %0A\
+Node: "+process.version+" %0A%0A\
+Error log: "+res.headers.location+" %0A")
+ })
+ else callback(false);
+ })
+});
+
+}
+
var getUbportDir = () => {
return path.join(process.env.APPDATA || (process.platform == 'darwin' ? process.env.HOME + '/Library/Application Support' : process.env.HOME + '/.cache'), "ubports/")
}
@@ -256,6 +318,9 @@ module.exports = {
getPlatformTools: getPlatformTools,
getUbportDir: getUbportDir,
needRoot: needRoot,
- checkPassword: checkPassword
+ checkPassword: checkPassword,
+ debugScreen: debugScreen,
+ debugTrigger: debugTrigger,
+ createBugReport: createBugReport
// decompressTarxzFileOnlyImages: decompressTarxzFileOnlyImages
}