Skip to content

Commit

Permalink
Added ability to install IITC core script with overwriting the standa…
Browse files Browse the repository at this point in the history
…rd script, similar to the usual plugins
  • Loading branch information
modos189 committed Sep 13, 2023
1 parent 8da14eb commit 7b39424
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 46 deletions.
134 changes: 89 additions & 45 deletions src/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,24 @@ export class Manager extends Worker {
async inject() {
const storage = await this.storage.get([
this.channel + '_iitc_core',
this.channel + '_iitc_core_user',
this.channel + '_plugins_flat',
this.channel + '_plugins_local',
this.channel + '_plugins_user',
]);

const iitc_core = storage[this.channel + '_iitc_core'];
const plugins_local = storage[this.channel + '_plugins_local'];
const plugins_user = storage[this.channel + '_plugins_user'];

if (iitc_core !== undefined && iitc_core['code'] !== undefined) {
let iitc_script = await this.getIITCCore(storage);
if (iitc_script !== null) {
const plugins_to_inject = [];

// IITC is injected first, then plugins. This is the correct order, because the initialization of IITC takes some time.
// During this time, plugins have time to be added to `window.bootPlugins` and are not started immediately.
// In addition, thanks to the injecting of plugins after IITC,
// plugins do not throw errors when attempting to access IITC, leaflet, etc. during the execution of the wrapper.
plugins_to_inject.push(iitc_core);
plugins_to_inject.push(iitc_script);
const plugins_flat = storage[this.channel + '_plugins_flat'];
for (const uid of Object.keys(plugins_flat)) {
if (plugins_flat[uid]['status'] === 'on') {
Expand Down Expand Up @@ -189,23 +190,29 @@ export class Manager extends Worker {
});
}
if (action === 'delete') {
if (plugins_flat[uid]['override']) {
if (plugins_local[uid] !== undefined) {
plugins_flat[uid] = { ...plugins_local[uid] };
}
plugins_flat[uid]['user'] = false;
plugins_flat[uid]['override'] = false;
plugins_flat[uid]['status'] = 'off';
if (uid === this.iitc_main_script_uid) {
await this._save({
iitc_core_user: {},
});
} else {
delete plugins_flat[uid];
}
delete plugins_user[uid];
if (plugins_flat[uid]['override']) {
if (plugins_local[uid] !== undefined) {
plugins_flat[uid] = { ...plugins_local[uid] };
}
plugins_flat[uid]['user'] = false;
plugins_flat[uid]['override'] = false;
plugins_flat[uid]['status'] = 'off';
} else {
delete plugins_flat[uid];
}
delete plugins_user[uid];

await this._save({
plugins_flat: plugins_flat,
plugins_local: plugins_local,
plugins_user: plugins_user,
});
await this._save({
plugins_flat: plugins_flat,
plugins_local: plugins_local,
plugins_user: plugins_user,
});
}
}
}

Expand All @@ -221,12 +228,14 @@ export class Manager extends Worker {
*/
async addUserScripts(scripts) {
let local = await this.storage.get([
this.channel + '_iitc_core_user',
this.channel + '_categories',
this.channel + '_plugins_flat',
this.channel + '_plugins_local',
this.channel + '_plugins_user',
]);

let iitc_core_user = local[this.channel + '_iitc_core_user'];
let categories = local[this.channel + '_categories'];
let plugins_flat = local[this.channel + '_plugins_flat'];
let plugins_local = local[this.channel + '_plugins_local'];
Expand All @@ -245,40 +254,49 @@ export class Manager extends Worker {

if (plugin_uid === null) throw new Error('The plugin has an incorrect ==UserScript== header');

const is_user_plugins = plugins_user[plugin_uid] !== undefined;
plugins_user[plugin_uid] = Object.assign(meta, {
uid: plugin_uid,
status: 'on',
code: code,
});
if (plugin_uid === this.iitc_main_script_uid) {
iitc_core_user = Object.assign(meta, {
uid: plugin_uid,
code: code,
});
installed_scripts[plugin_uid] = iitc_core_user;
} else {
const is_user_plugins = plugins_user[plugin_uid] !== undefined;
plugins_user[plugin_uid] = Object.assign(meta, {
uid: plugin_uid,
status: 'on',
code: code,
});

if (plugin_uid in plugins_flat && !is_user_plugins) {
if (plugin_uid in plugins_local && plugins_flat[plugin_uid]['status'] !== 'off') {
plugins_local[plugin_uid]['status'] = 'off';
}
if (plugin_uid in plugins_flat && !is_user_plugins) {
if (plugin_uid in plugins_local && plugins_flat[plugin_uid]['status'] !== 'off') {
plugins_local[plugin_uid]['status'] = 'off';
}

plugins_flat[plugin_uid]['status'] = 'on';
plugins_flat[plugin_uid]['code'] = code;
plugins_flat[plugin_uid]['override'] = true;
} else {
let category = plugins_user[plugin_uid]['category'];
if (category === undefined) {
category = 'Misc';
plugins_user[plugin_uid]['category'] = category;
}
if (!(category in categories)) {
categories[category] = {
name: category,
description: '',
};
plugins_flat[plugin_uid]['status'] = 'on';
plugins_flat[plugin_uid]['code'] = code;
plugins_flat[plugin_uid]['override'] = true;
} else {
let category = plugins_user[plugin_uid]['category'];
if (category === undefined) {
category = 'Misc';
plugins_user[plugin_uid]['category'] = category;
}
if (!(category in categories)) {
categories[category] = {
name: category,
description: '',
};
}
plugins_flat[plugin_uid] = { ...plugins_user[plugin_uid] };
}
plugins_flat[plugin_uid] = { ...plugins_user[plugin_uid] };
plugins_flat[plugin_uid]['user'] = true;
installed_scripts[plugin_uid] = plugins_flat[plugin_uid];
}
plugins_flat[plugin_uid]['user'] = true;
installed_scripts[plugin_uid] = plugins_flat[plugin_uid];
});

await this._save({
iitc_core_user: iitc_core_user,
categories: categories,
plugins_flat: plugins_flat,
plugins_local: plugins_local,
Expand All @@ -300,6 +318,32 @@ export class Manager extends Worker {
return all_plugins[uid];
}

/**
* Returns IITC core script.
*
* @async
* @param {Object|undefined} [storage=undefined] - Storage object with keys `channel_iitc_core` and `channel_iitc_core_user`.
* If not specified, the data is queried from the storage.
* @return {Promise<plugin|null>}
*/
async getIITCCore(storage) {
if (storage === undefined || !isSet(storage[this.channel + '_iitc_core'])) {
storage = await this.storage.get([this.channel + '_iitc_core', this.channel + '_iitc_core_user']);
}

const iitc_core = storage[this.channel + '_iitc_core'];
const iitc_core_user = storage[this.channel + '_iitc_core_user'];

let iitc_script = null;
if (isSet(iitc_core_user) && isSet(iitc_core_user['code'])) {
iitc_script = iitc_core_user;
iitc_script['override'] = true;
} else if (isSet(iitc_core) && isSet(iitc_core['code'])) {
iitc_script = iitc_core;
}
return iitc_script;
}

/**
* Asynchronously retrieves backup data based on the specified parameters.
*
Expand Down
6 changes: 5 additions & 1 deletion src/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ export class Worker {
this.progress_interval_id = null;
this.update_timeout_id = null;
this.external_update_timeout_id = null;
this.iitc_main_script_uid = 'IITC: Ingress intel map total conversion+https://github.com/IITC-CE/ingress-intel-total-conversion';

this.storage = typeof this.config.storage !== 'undefined' ? this.config.storage : console.error("config key 'storage' is not set");
this.message = this.config.message;
Expand Down Expand Up @@ -235,7 +236,10 @@ export class Worker {
async _save(options) {
const data = {};
Object.keys(options).forEach((key) => {
if (['iitc_version', 'last_modified', 'iitc_core', 'categories', 'plugins_flat', 'plugins_local', 'plugins_user'].indexOf(key) !== -1) {
if (
['iitc_version', 'last_modified', 'iitc_core', 'iitc_core_user', 'categories', 'plugins_flat', 'plugins_local', 'plugins_user'].indexOf(key) !==
-1
) {
data[this.channel + '_' + key] = options[key];
} else {
data[key] = options[key];
Expand Down
51 changes: 51 additions & 0 deletions test/manager.2.external.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -461,4 +461,55 @@ describe('manage.js external plugins integration tests', function () {
expect(db_data['release_plugins_flat'][external_3_uid]['override'], "release_plugins_flat['override']: " + external_3_uid).to.be.false;
});
});

describe('Adding and removing custom IITC core script', function () {
const iitc_custom_uid = 'IITC: Ingress intel map total conversion+https://github.com/IITC-CE/ingress-intel-total-conversion';
const iitc_custom = {
meta: {
author: 'jonatkins',
name: 'IITC: Ingress intel map total conversion',
version: '0.99.0',
description: 'Total conversion for the ingress intel map.',
id: 'total-conversion-build',
namespace: 'https://github.com/IITC-CE/ingress-intel-total-conversion',
},
code: external_code,
};
it('Add custom IITC core script', async function () {
const run = await manager.addUserScripts([iitc_custom]);
expect(run).to.have.all.keys(iitc_custom_uid);

const db_data = await storage.get(['release_iitc_core_user']);
expect(db_data['release_iitc_core_user']['code'], "iitc_core_user['code']").to.equal(external_code);
});
it('Check getIITCCore() for custom IITC', async function () {
const script = await manager.getIITCCore();
expect(script, 'getIITCCore()').to.have.all.keys('author', 'code', 'description', 'id', 'name', 'namespace', 'override', 'uid', 'version');
expect(script['override'], "getIITCCore() object must have the 'override' parameter set to true").to.be.true;
});
it('Remove custom IITC core script', async function () {
const run = await manager.managePlugin(iitc_custom_uid, 'delete');
expect(run).to.be.undefined;

const db_data = await storage.get(['release_iitc_core_user']);
expect(db_data['release_iitc_core_user'], 'iitc_core_user must be empty object').to.deep.equal({});
});
it('Check getIITCCore() for standard IITC', async function () {
const script = await manager.getIITCCore();
expect(script, 'getIITCCore()').to.have.all.keys(
'author',
'code',
'description',
'downloadURL',
'grant',
'id',
'match',
'name',
'namespace',
'runAt',
'updateURL',
'version'
);
});
});
});

0 comments on commit 7b39424

Please sign in to comment.