From 95745e519351adc3189e7e285a553bc6c1e5100a Mon Sep 17 00:00:00 2001 From: Jan Sprinz Date: Wed, 6 Jan 2021 16:27:29 +0100 Subject: [PATCH] Add AsteroidOS plugin --- package-lock.json | 4 +- package.json | 2 +- src/core/plugins/asteroid_os/api.js | 74 +++++++++++++++++++++ src/core/plugins/asteroid_os/api.spec.js | 7 ++ src/core/plugins/asteroid_os/plugin.js | 63 ++++++++++++++++++ src/core/plugins/asteroid_os/plugin.spec.js | 4 ++ src/core/plugins/index.js | 5 +- 7 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 src/core/plugins/asteroid_os/api.js create mode 100644 src/core/plugins/asteroid_os/api.spec.js create mode 100644 src/core/plugins/asteroid_os/plugin.js create mode 100644 src/core/plugins/asteroid_os/plugin.spec.js diff --git a/package-lock.json b/package-lock.json index 1f088610..ae519744 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "ubports-installer", - "version": "0.8.3-beta", + "version": "0.8.4-beta", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "0.8.3-beta", + "version": "0.8.4-beta", "license": "GPL-3.0", "dependencies": { "7zip-min": "^1.2.0", diff --git a/package.json b/package.json index 39d181cd..b5553583 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ubports-installer", - "version": "0.8.3-beta", + "version": "0.8.4-beta", "description": "The easy way to install Ubuntu Touch on UBports devices. A friendly cross-platform Installer for Ubuntu Touch. Just connect a supported device to your PC, follow the on-screen instructions and watch this awesome tool do all the rest.", "keywords": [ "Ubuntu", diff --git a/src/core/plugins/asteroid_os/api.js b/src/core/plugins/asteroid_os/api.js new file mode 100644 index 00000000..3cf8aabb --- /dev/null +++ b/src/core/plugins/asteroid_os/api.js @@ -0,0 +1,74 @@ +"use strict"; + +/* + * Copyright (C) 2020-2021 UBports Foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +const axios = require("axios"); + +/** @module asteroid_os */ + +const baseURL = "https://release.asteroidos.org/"; + +const api = axios.create({ baseURL, timeout: 15000 }); + +/** + * get images from api + * @param {String} channel channel + * @param {String} device device codename + * @returns {Promise>} images array + * @throws {Error} message "no network" if request failed + */ +const getImages = (channel, device) => + api + .get(`${channel}/${device}/MD5SUMS`) + .then(({ data }) => + data + .trim() + .split("\n") + .map(line => ({ + url: `${baseURL}${channel}/${device}/${line.split(/[ ,]+/)[1]}`, + checksum: { + sum: line.split(/[ ,]+/)[0], + algorithm: "md5" + } + })) + ) + .catch(error => { + if (error.response.status === 404) throw new Error("404"); + else if (error.response) throw new Error("no network"); + else throw error; + }); + +/** + * get channels from api + * @param {String} device device codename + * @returns {Promise>} channels + * @throws {Error} message "unsupported" if 404 not found + */ +const getChannels = device => + Promise.all( + ["1.0", "nightlies", "1.0-alpha"].map(channel => + getImages(channel, device) + .then(() => channel) + .catch(error => { + if (error.message === "404") return null; + else throw error; + }) + ) + ).then(channels => channels.filter(c => c)); + +module.exports = { getImages, getChannels }; diff --git a/src/core/plugins/asteroid_os/api.spec.js b/src/core/plugins/asteroid_os/api.spec.js new file mode 100644 index 00000000..1fcfb86f --- /dev/null +++ b/src/core/plugins/asteroid_os/api.spec.js @@ -0,0 +1,7 @@ +process.argv = [null, null, "-vv"]; +const { ipcMain } = require("electron"); +jest.mock("electron"); + +const api = require("./api.js"); + +it("should construct", () => expect(require("./api.js")).toBeDefined()); diff --git a/src/core/plugins/asteroid_os/plugin.js b/src/core/plugins/asteroid_os/plugin.js new file mode 100644 index 00000000..e5cbc037 --- /dev/null +++ b/src/core/plugins/asteroid_os/plugin.js @@ -0,0 +1,63 @@ +"use strict"; + +/* + * Copyright (C) 2020-2021 UBports Foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +const Plugin = require("../plugin.js"); +const api = require("./api.js"); + +/** + * Asteroid OS plugin + * @extends Plugin + */ +class AsteroidOsPlugin extends Plugin { + /** + * action download + * @returns {Promise>} + */ + action__download() { + return api + .getImages(this.props.settings.channel, this.props.config.codename) + .then(files => [ + { + actions: [ + { + "core:download": { + group: "AsteroidOS", + files + } + } + ] + } + ]); + } + + /** + * channels remote_values + * @returns {Promise>} + */ + remote_values__channels() { + return api.getChannels(this.props.config.codename).then(channels => + channels.map(channel => ({ + value: channel, + label: channel + })) + ); + } +} + +module.exports = AsteroidOsPlugin; diff --git a/src/core/plugins/asteroid_os/plugin.spec.js b/src/core/plugins/asteroid_os/plugin.spec.js new file mode 100644 index 00000000..e6f553c1 --- /dev/null +++ b/src/core/plugins/asteroid_os/plugin.spec.js @@ -0,0 +1,4 @@ +const systemimage = require("./plugin.js"); + +it("should be a singleton", () => + expect(systemimage).toEqual(require("./plugin.js"))); diff --git a/src/core/plugins/index.js b/src/core/plugins/index.js index 60a808c4..4bb7139e 100644 --- a/src/core/plugins/index.js +++ b/src/core/plugins/index.js @@ -1,7 +1,7 @@ "use strict"; /* - * Copyright (C) 2020 UBports Foundation + * Copyright (C) 2020-2021 UBports Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ */ const AdbPlugin = require("./adb/plugin.js"); +const AsteroidOsPlugin = require("./asteroid_os/plugin.js"); const CorePlugin = require("./core/plugin.js"); const FastbootPlugin = require("./fastboot/plugin.js"); const HeimdallPlugin = require("./heimdall/plugin.js"); @@ -28,6 +29,7 @@ const SystemimagePlugin = require("./systemimage/plugin.js"); * @property {Props} props props reference * @property {Object} plugins plugins namespace * @property {AdbPlugin} plugins.adb adb plugin + * @property {AsteroidOsPlugin} plugins.asteroid_os AteroidOS plugin * @property {CorePlugin} plugins.core core plugin * @property {FastbootPlugin} plugins.fastboot fastboot plugin * @property {HeimdallPlugin} plugins.heimdall heimdall plugin @@ -40,6 +42,7 @@ class PluginIndex { const pluginArgs = [props, cachePath, mainEvent, log]; this.plugins = { adb: new AdbPlugin(...pluginArgs), + asteroid_os: new AsteroidOsPlugin(...pluginArgs), core: new CorePlugin(...pluginArgs), fastboot: new FastbootPlugin(...pluginArgs), heimdall: new HeimdallPlugin(...pluginArgs),