forked from espruino/BangleApps
-
Notifications
You must be signed in to change notification settings - Fork 0
/
backup.js
125 lines (121 loc) · 4.41 KB
/
backup.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* Code to handle Backup/Restore functionality */
const BACKUP_STORAGEFILE_DIR = "storage-files";
function bangleDownload() {
var zip = new JSZip();
Progress.show({title:"Scanning...",sticky:true});
var normalFiles, storageFiles;
console.log("Listing normal files...");
Comms.reset()
.then(() => Comms.showMessage("Backing up..."))
.then(() => Comms.listFiles({sf:false}))
.then(f => {
normalFiles = f;
console.log(" - "+f.join(","));
console.log("Listing StorageFiles...");
return Comms.listFiles({sf:true});
}).then(f => {
storageFiles = f;
console.log(" - "+f.join(","));
var fileCount = normalFiles.length + storageFiles.length;
var promise = Promise.resolve();
// Normal files
normalFiles.forEach((filename,n) => {
if (filename==".firmware") {
console.log("Ignoring .firmware file");
return;
}
promise = promise.then(() => {
Progress.hide({sticky: true});
var percent = n/fileCount;
Progress.show({title:`Download ${filename}`,sticky:true,min:percent,max:percent+(1/fileCount),percent:0});
return Comms.readFile(filename).then(data => zip.file(filename,data));
});
});
// Storage files
if (storageFiles.length) {
var zipStorageFiles = zip.folder(BACKUP_STORAGEFILE_DIR);
storageFiles.forEach((filename,n) => {
promise = promise.then(() => {
Progress.hide({sticky: true});
var percent = (normalFiles.length+n)/fileCount;
Progress.show({title:`Download ${filename}`,sticky:true,min:percent,max:percent+(1/fileCount),percent:0});
return Comms.readStorageFile(filename).then(data => zipStorageFiles.file(filename,data));
});
});
}
return promise;
}).then(() => {
return Comms.showMessage(Const.MESSAGE_RELOAD);
}).then(() => {
return zip.generateAsync({type:"binarystring"});
}).then(content => {
Progress.hide({ sticky: true });
showToast('Backup complete!', 'success');
Espruino.Core.Utils.fileSaveDialog(content, "Banglejs backup.zip");
}).catch(err => {
Progress.hide({ sticky: true });
showToast('Backup failed, ' + err, 'error');
});
}
function bangleUpload() {
Espruino.Core.Utils.fileOpenDialog({
id:"backup",
type:"arraybuffer",
mimeType:".zip,application/zip"}, function(data) {
if (data===undefined) return;
var promise = Promise.resolve();
var zip = new JSZip();
var cmds = "";
zip.loadAsync(data).then(function(zip) {
return showPrompt("Restore from ZIP","Are you sure? This will remove all existing apps");
}).then(()=>{
Progress.show({title:`Reading ZIP`});
zip.forEach(function (path, file){
console.log("path");
promise = promise
.then(() => file.async("string"))
.then(data => {
console.log("decoded", path);
if (data.length==0) { // https://github.com/espruino/BangleApps/issues/1593
console.log("Can't restore files of length 0, ignoring "+path);
} else if (path.startsWith(BACKUP_STORAGEFILE_DIR)) {
path = path.substr(BACKUP_STORAGEFILE_DIR.length+1);
cmds += AppInfo.getStorageFileUploadCommands(path, data)+"\n";
} else if (!path.includes("/")) {
cmds += AppInfo.getFileUploadCommands(path, data)+"\n";
} else console.log("Ignoring "+path);
});
});
return promise;
})
.then(() => {
Progress.hide({sticky:true});
Progress.show({title:`Erasing...`});
return Comms.removeAllApps(); })
.then(() => {
Progress.hide({sticky:true});
Progress.show({title:`Restoring...`, sticky:true});
return Comms.showMessage(`Restoring...`); })
.then(() => Comms.write("\x10"+Comms.getProgressCmd()+"\n"))
.then(() => Comms.uploadCommandList(cmds, 0, cmds.length))
.then(() => getInstalledApps(true))
.then(() => Comms.showMessage(Const.MESSAGE_RELOAD))
.then(() => {
Progress.hide({sticky:true});
showToast('Restore complete!', 'success');
})
.catch(err => {
Progress.hide({sticky:true});
showToast('Restore failed, ' + err, 'error');
});
return promise;
});
}
window.addEventListener('load', (event) => {
document.getElementById("downloadallapps").addEventListener("click",event=>{
bangleDownload();
});
document.getElementById("uploadallapps").addEventListener("click",event=>{
bangleUpload();
});
});