Added logic for configuration remote backup/restore

This commit is contained in:
Fabio Manganiello 2020-06-30 11:58:26 +02:00
parent 7feb972715
commit 8eb5e80821
2 changed files with 131 additions and 7 deletions

View file

@ -4,17 +4,41 @@
<h2>Extension Configuration</h2>
<form class="loader" ref="loader" @submit.prevent="loadURL">
<div class="loader-head">
Load configuration
<input type="radio" id="_file" value="file" v-model="extConfigType" />
<label for="_file">From file</label>
<input type="radio" id="_url" value="url" v-model="extConfigType" />
<label for="_url">From URL</label>
<div class="left">
Load configuration
<input type="radio" id="_file" value="file" v-model="extConfigType" />
<label for="_file">From file</label>
<input type="radio" id="_url" value="url" v-model="extConfigType" />
<label for="_url">From URL</label>
<input type="radio" id="_host" value="host" v-model="extConfigType" />
<label for="_host">From device</label>
</div>
<div class="right" v-if="Object.keys(hosts).length">
<select id="host-selector" v-model="selectedHost">
<option disabled :selected="!selectedHost" value="">Backup configuration to a device</option>
<option v-for="(host, name) in hosts" :selected="selectedHost === name" :key="name" :value="name">{{ name }}</option>
</select>
<button type="button" :disabled="loading || !selectedHost || savedConfig !== config" @click.stop="backupConfig(selectedHost)">
<i class="fas fa-upload" /> &nbsp; Upload
</button>
</div>
</div>
<div class="loader-body">
<input type="file" name="file" placeholder="Configuration file" accept="application/json, text/x-json, text/plain" @change="uploadFile" v-if="extConfigType === 'file'" />
<input type="text" name="url" placeholder="Configuration URL" v-model="extURL" v-if="extConfigType === 'url'" />
<input type="submit" value="Load" v-if="extConfigType === 'url'" />
<select id="host-selector" v-model="selectedHost" v-if="extConfigType === 'host'">
<option disabled :selected="!selectedHost" value="">Select a device</option>
<option v-for="(host, name) in hosts" :selected="selectedHost === name" :key="name" :value="name">{{ name }}</option>
</select>
<button type="button" :disabled="loading || !selectedHost" @click.stop="restoreConfig(selectedHost)" v-if="extConfigType === 'host'">
<i class="fas fa-download" /> &nbsp; Restore
</button>
</div>
</form>
</div>
@ -22,7 +46,6 @@
<form class="content" ref="content" @submit.prevent="save">
<div class="textarea">
<PrismEditor name="text" v-model="config" :code="loading ? 'Loading...' : config" language="js" :emitEvents="true" />
<!-- <textarea name="text" ref="text" v-model="config" v-text="loading ? 'Loading...' : config" @focus="onFocus" :disabled="loading" /> -->
</div>
<div class="buttons">
@ -52,6 +75,8 @@ export default {
savedConfig: null,
extConfigType: 'file',
extURL: null,
selectedHost: null,
hosts: [],
};
},
@ -65,6 +90,7 @@ export default {
async reload() {
const config = await this.loadConfig();
this.hosts = config.hosts || [];
this.config = JSON.stringify(config, null, ' ');
this.savedConfig = this.config;
},
@ -121,6 +147,10 @@ export default {
this.loading = false;
}
},
async restoreConfig(host) {
this.config = JSON.stringify(await this.getConfig(host), null, ' ');
},
},
created() {
@ -176,7 +206,18 @@ $buttons-height: 5em;
margin-bottom: 1em;
.loader-head {
display: flex;
flex-direction: row;
margin-bottom: 1em;
.left {
width: 50%;
}
.right {
width: 50%;
text-align: right;
}
}
.loader-body {
@ -197,6 +238,10 @@ $buttons-height: 5em;
right: 0;
}
}
select {
margin-right: 0.5em;
}
</style>
<!-- vim:sw=2:ts=2:et: -->

View file

@ -71,11 +71,18 @@ export default {
if (Array.isArray(action.args)) {
args = action.args
.filter(arg => arg.value && arg.value.length)
.filter(arg => arg.value != null && arg.value.length)
.reduce((obj, arg) => {
obj[arg.name] = arg.value;
return obj;
}, {});
} else {
args = Object.entries(args)
.filter(([name, value]) => value != null && value.length)
.reduce((obj, [name, value]) => {
obj[name] = value;
return obj;
}, {});
}
Object.keys(args).forEach(name => {
@ -282,6 +289,78 @@ export default {
}
},
async backupConfig(host) {
if (typeof host === 'string') {
const hosts = await this.getHosts();
if (!(host in hosts)) {
this.notify(host, 'No such Platypush host');
return;
}
host = hosts[host];
}
this.loading = true;
const config = JSON.stringify(await this.loadConfig());
const basedir = `\${Config.get("workdir")}/webext`;
const filename = `${basedir}/config.json`;
try {
await this.run(
{
name: 'file.mkdir',
args: { directory: basedir },
},
host
);
await this.run(
{
name: 'file.write',
args: {
file: filename,
content: config,
},
},
host
);
this.notify(`Configugration successfully backed up to ${host.name}`, 'Backup successful');
} finally {
this.loading = false;
}
},
async getConfig(host) {
if (typeof host === 'string') {
const hosts = await this.getHosts();
if (!(host in hosts)) {
this.notify(host, 'No such Platypush host');
return;
}
host = hosts[host];
}
this.loading = true;
const basedir = `\${Config.get("workdir")}/webext`;
const filename = `${basedir}/config.json`;
try {
const config = await this.run(
{
name: 'file.read',
args: { file: filename },
},
host
);
return config;
} finally {
this.loading = false;
}
},
formToHost(form) {
return {
name: form.name.value,