From fc373e0fee64e7b12c196b748445920a152f28c6 Mon Sep 17 00:00:00 2001 From: Willian Galvani Date: Mon, 25 Mar 2024 15:10:20 -0300 Subject: [PATCH 1/2] core: frontend: wizard: allow downloading scripts in wizard --- .../src/components/wizard/ScriptLoader.vue | 150 ++++++++++++++++++ .../frontend/src/components/wizard/Wizard.vue | 47 ++++++ core/frontend/src/libs/filebrowser.ts | 36 +++++ 3 files changed, 233 insertions(+) create mode 100644 core/frontend/src/components/wizard/ScriptLoader.vue diff --git a/core/frontend/src/components/wizard/ScriptLoader.vue b/core/frontend/src/components/wizard/ScriptLoader.vue new file mode 100644 index 000000000..0aa71edca --- /dev/null +++ b/core/frontend/src/components/wizard/ScriptLoader.vue @@ -0,0 +1,150 @@ + + + diff --git a/core/frontend/src/components/wizard/Wizard.vue b/core/frontend/src/components/wizard/Wizard.vue index e214d993c..fbcda7baf 100644 --- a/core/frontend/src/components/wizard/Wizard.vue +++ b/core/frontend/src/components/wizard/Wizard.vue @@ -129,6 +129,10 @@ + = import.meta.glob('/src/assets/vehicles/models/**', { eager: true }) function get_model(vehicle_name: string, frame_name: string): undefined | string { @@ -314,10 +322,12 @@ export default Vue.extend({ components: { DefaultParamLoader, RequireInternet, + ScriptLoader, }, data() { return { boat_model: get_model('boat', 'UNDEFINED'), + scripts: [] as string[], configuration_failed: false, error_message: 'The operation failed!', apply_status: ApplyStatus.Waiting, @@ -487,6 +497,15 @@ export default Vue.extend({ skip: false, started: false, }, + { + title: 'Install scripts', + summary: 'Download and install selected scripts', + promise: () => this.installScripts(), + message: undefined, + done: false, + skip: false, + started: false, + }, { title: 'Disable Wi-Fi hotspot', summary: 'Wi-Fi hotspot need to be disable to not interfere with onboard radio', @@ -648,6 +667,34 @@ export default Vue.extend({ }) .catch((error) => `Failed to fetch available firmware: ${error.message ?? error.response?.data}.`) }, + async installScripts(): Promise { + const scripts_folder = 'configs/ardupilot-manager/firmware/scripts/' + try { + // Use allSettled to allow promises to fail in parallel + await Promise.allSettled( + this.scripts.map( + async (script) => filebrowser.createFile(scripts_folder + script.split('/').last(), true), + ), + ) + await Promise.allSettled( + this.scripts.map(async (script) => { + await filebrowser.writeToFile( + scripts_folder + script.split('/').last(), + await this.fetchScript(script), + ) + }), + ) + return undefined + } catch (e) { + const error = `Failed to install scripts ${e}` + console.error(error) + return error + } + }, + async fetchScript(script: string): Promise { + const response = await fetch(`${REPOSITORY_ROOT}/scripts/ardupilot/${script}`) + return response.text() + }, validateParams(): boolean { return this.$refs.param_loader?.validateParams() }, diff --git a/core/frontend/src/libs/filebrowser.ts b/core/frontend/src/libs/filebrowser.ts index 958421df7..23fdd4580 100644 --- a/core/frontend/src/libs/filebrowser.ts +++ b/core/frontend/src/libs/filebrowser.ts @@ -66,6 +66,42 @@ class Filebrowser { }) } + async createFolder(folder_path: string): Promise { + if (!folder_path.endsWith('/')) { + folder_path += '/' + } + this.createFile(folder_path) + } + + async createFile(folder_path: string, override: Boolean = false): Promise { + back_axios({ + method: 'post', + url: `${filebrowser_url}/resources${folder_path}?override=${override}`, + timeout: 10000, + headers: { 'X-Auth': await this.filebrowserToken() }, + }) + .catch((error) => { + const message = `Could not create folder ${folder_path}: ${error.message}` + notifier.pushError('FOLDER_CREATE_FAIL', message) + throw new Error(message) + }) + } + + async writeToFile(file: string, content: string): Promise { + back_axios({ + method: 'put', + url: `/file-browser/api/resources${file}`, + timeout: 10000, + headers: { 'X-Auth': await this.filebrowserToken() }, + data: content, + }) + .catch((error) => { + const message = `Could not write to file ${file}: ${error.message}` + notifier.pushError('FILE_WRITE_FAIL', message) + throw new Error(message) + }) + } + /* Delete a single file. */ /* Register a notification and throws if delete fails. */ /** From 4f03706cdd9f7c18a3d459092b2e1b66bc52aec4 Mon Sep 17 00:00:00 2001 From: Willian Galvani Date: Tue, 26 Mar 2024 12:08:23 -0300 Subject: [PATCH 2/2] core: frontend: tweak wizard style --- core/frontend/src/components/wizard/DefaultParamLoader.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/frontend/src/components/wizard/DefaultParamLoader.vue b/core/frontend/src/components/wizard/DefaultParamLoader.vue index e2c906a44..400ffc497 100755 --- a/core/frontend/src/components/wizard/DefaultParamLoader.vue +++ b/core/frontend/src/components/wizard/DefaultParamLoader.vue @@ -9,7 +9,7 @@ :label="`Parameter Sets (${board} - ${vehicle} - ${version})`" :loading="is_loading" :disabled="is_loading_paramsets" - style="min-width: 60%;" + style="min-width: 330px;" :rules="[isNotEmpty]" @change="setParamSet(filtered_param_sets[selected_param_set_name])" />