-
Notifications
You must be signed in to change notification settings - Fork 33
/
Shortcuts Restore.js
180 lines (154 loc) · 5.08 KB
/
Shortcuts Restore.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: cyan; icon-glyph: magic;
/*
Name : Shortcuts Restore
Author : @supermamon
Version : 2.0.0
Changes :
v2.0.0 | 2018-10-30
- Removed the Tier-ring. Shortcuts restores
the shortcut names in Run Shortcut ones the
called shortcut is restored
- Grant access to the Shortcuts folder using
the document picker. Moving the backup
folder manually is no longer needed
v1.0.0 | 2018-09-29
- Initial release
Requires:
Backup & Restore Shortcut
- https://routinehub.co/shortcut/613
Parameters
* restore_dir : the folder inside the Shortcuts
folder where the backups are stored
* info_file : filename of the backup information
(.json) file
Configure
* DEBUG = false : full import.
* DEBUG = true : limited import
: append "(restore)" to names
*/
const DEBUG = true;
const DEBUG_TEST_IMPORT_QTY = 2;
const FM = FileManager.iCloud();
const params = URLScheme.allParameters();
// simulate parameters
// params['restore_dir']='Restore'
// params['info_file'] ='BackupInfo.json'
// let not run this without the required params
console.log('* Validating parameters')
if (isParamMissing('restore_dir')) {
console.log('* Aborted.')
return
}
if (isParamMissing('info_file')) {
console.log('Aborted.')
return
}
// how?
// 1. Navigate to the iCloud Drive root folder
// 2. Tap Select
// 3. Choose the Shortcuts folder
// 4. Tap Open
console.log('* Acquiring Shortcuts folder access')
let prompt = 'Please navigate to the iCloud ' +
'Drive and open the Shortcuts folder.'
const shortcutsDirs = await promptForFolders(prompt);
const shortcutsDir = shortcutsDirs[0];
// append the restore path to the Shortcuts path
console.log('* Acquiring restore path')
const restore_dir = FM.joinPath(
shortcutsDir,
params['restore_dir']
);
console.log(' --> ' + restore_dir)
// load the .json file
console.log('* Getting backup information')
let info_file = params['info_file'];
info_file = 'BackupInfo.json';
const backup_info = loadBackupInfo(
restore_dir,
info_file
)
console.log(' --> ' + backup_info.name)
// prepare the number of items and the list
console.log('* Getting the list of shortcuts')
const restore_list = backup_info.list_order;
const max_items = DEBUG?DEBUG_TEST_IMPORT_QTY:restore_list.length
console.log('* Ready to restore')
prompt = (DEBUG ? 'DEBUG MODE\n' : '' ) +
`This will restore ${max_items} ` +
'shortcuts! Focus will switch between ' +
'Shortcuts and Scriptable until the ' +
'restoration is completed.'
if ( await confirm('Restore', prompt) == -1 ) {
console.log('* Restore aborted by user.');
return
}
console.log('* Restoring');
for (var i=0; i<max_items; i++) {
// get the shortcut path
let shortcut = restore_list[i] + '.shortcut'
let sc_path = FM.joinPath(restore_dir,shortcut)
// import it
await importShortcut(sc_path)
}
// import done. show alert
console.log('* Restore completed.')
const alert = new Alert();
alert.title = 'Completed';
alert.message = 'Restore completed';
alert.addAction("OK");
await alert.presentAlert();
// go back to Shortcuts
Safari.open('shortcuts://')
// -----------------------------------------------
function isParamMissing(name) {
let paramMissing = !params[name]
if (paramMissing) {
console.log('* Missing parameter - '+name)
}
return paramMissing
}
async function promptForFolders(msg) {
const alert = new Alert();
alert.title = 'Select Folder';
alert.message = msg;
alert.addAction("OK");
await alert.presentAlert();
let dirs = await DocumentPicker.open(["public.folder"]);
return dirs;
}
async function confirm(title, msg) {
const alert = new Alert();
alert.title = title;
alert.message = msg;
alert.addDestructiveAction("Continue");
alert.addCancelAction('Cancel')
return await alert.presentAlert();
}
function loadBackupInfo(dir,filename) {
const bi_path = FM.joinPath(dir, filename)
const contents = Data.fromFile(bi_path)
return JSON.parse(contents.toRawString())
}
async function importShortcut(shortcutPath) {
// expects an absolute path
if (!FM.fileExists(shortcutPath)) return;
const scName = FM.fileName(shortcutPath,false);
console.log(`importing > ${scName}`)
// read the file and convert it into an
// encoded URL
let d = Data.fromFile(shortcutPath);
let file = d.toBase64String();
let durl = "data:text/shortcut;base64,"+file;
let encodedUri = encodeURI(durl);
console.log(` > ${scName} loaded`)
// callback to import it to the Shortcuts app
const baseURL = "shortcuts://import-shortcut";
const url = new CallbackURL(baseURL);
url.addParameter("name",scName+(DEBUG?' (restored)':''));
url.addParameter("url",encodedUri);
await url.open();
console.log(` > ${scName} sent for import`)
}