Skip to content

Commit

Permalink
Add methods for exporting and importing backups
Browse files Browse the repository at this point in the history
In the 'Manager' class, the 'getBackupData' and 'setBackupData' methods have been added to handle the export and import of backups, respectively. These methods allow the user to retrieve backup data based on specified parameters and set backup data using the provided backup object.
  • Loading branch information
modos189 committed Jul 28, 2023
1 parent 994fd87 commit 0060a0a
Show file tree
Hide file tree
Showing 5 changed files with 447 additions and 3 deletions.
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@
"homepage": "https://github.com/IITC-CE/lib-iitc-manager#readme",
"devDependencies": {
"chai": "^4.3.6",
"http-server": "^14.1.0",
"mocha": "^9.2.2",
"node-fetch": "^3.2.3",
"eslint": "^8.20.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"http-server": "^14.1.0",
"mocha": "^9.2.2",
"node-fetch": "^3.2.3",
"prettier": "^2.7.1"
},
"dependencies": {
"@bundled-es-modules/deepmerge": "^4.3.1",
"xhr2": "^0.2.1"
}
}
212 changes: 212 additions & 0 deletions src/backup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
// @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3

import { parseMeta } from './helpers.js';
import deepmerge from '@bundled-es-modules/deepmerge';

/**
* Processes the input parameters for backup data retrieval.
*
* This function takes an input object containing parameters for backup data retrieval
* and returns a new object with processed parameters. If the input parameters are not
* an object, an empty object is used as the default value. The function combines the
* input parameters with default parameters to ensure all required properties are present.
*
* @param {BackupParams} params - The parameters for setting the backup data.
* @returns {Object} The processed parameters object.
*/
export function paramsProcessing(params) {
if (typeof params !== 'object') params = {};

// Default parameters
const default_params = {
settings: false,
data: false,
external: false,
};

// Combine the default parameters with the input parameters using spread syntax
return { ...default_params, ...params };
}

/**
* Exports specific IITC settings from the provided storage object.
*
* This function takes a storage object and extracts specific IITC settings based on
* predefined keys. It creates a new object containing only the specified IITC settings
* and returns it.
*
* @param {Object} all_storage - The storage object containing all data.
* @returns {Object} An object containing specific IITC settings.
*/
export const exportIitcSettings = (all_storage) => {
const iitc_settings = {};

// An array of predefined keys for IITC settings
const storage_keys = ['channel', 'network_host', 'release_update_check_interval', 'beta_update_check_interval', 'custom_update_check_interval'];

// Loop through all_storage and check if the keys are present in storage_keys
// If present, add them to the iitc_settings object
for (const key in all_storage) {
if (storage_keys.includes(key)) {
iitc_settings[key] = all_storage[key];
}
}
return iitc_settings;
};

/**
* Exports specific plugin settings from the provided storage object.
*
* This function takes a storage object and extracts plugin settings that have keys starting
* with the prefix 'VMin'. It creates a new object containing only the plugin settings
* and returns it.
*
* @param {Object} all_storage - The storage object containing all data.
* @returns {Object} An object containing specific plugin settings.
*/
export const exportPluginsSettings = (all_storage) => {
const plugins_storage = {};

// Loop through all_storage and check if the keys start with the prefix 'VMin'
// If so, add them to the plugins_storage object
for (const key in all_storage) {
if (key.startsWith('VMin')) {
plugins_storage[key] = all_storage[key];
}
}
return plugins_storage;
};

/**
* Exports external plugins from the provided storage object.
*
* This function takes a storage object and extracts external plugins based on predefined keys.
* It creates a new object containing the external plugins organized by their channels and filenames,
* and returns it.
*
* @param {Object} all_storage - The storage object containing all data.
* @returns {Object} An object containing external plugins organized by channels and filenames.
*/
export const exportExternalPlugins = (all_storage) => {
const external_plugins = {};

// An array of predefined keys for external plugins
const storage_keys = ['release_plugins_user', 'beta_plugins_user', 'custom_plugins_user'];

// Loop through all_storage and check if the keys are present in storage_keys
// If present, process and add the external plugins to the external_plugins object
for (const key in all_storage) {
if (storage_keys.includes(key)) {
// Extract the channel name from the key by splitting at '_'
const channel = key.split('_')[0];
external_plugins[channel] = {};

// Loop through each plugin UID in the current key's storage data
for (const plugin_uid in all_storage[key]) {
// Get the plugin's filename and code from the storage data and add to the external_plugins object
const plugin_filename = all_storage[key][plugin_uid]['filename'];
external_plugins[channel][plugin_filename] = all_storage[key][plugin_uid]['code'];
}
}
}

return external_plugins;
};

/**
* Imports IITC settings from the provided backup object.
*
* @async
* @param {Object} self - IITC manager object.
* @param {Object} backup - The backup object containing IITC settings to import.
* @returns {Promise<void>} A promise that resolves when the import is complete.
*/
export const importIitcSettings = async (self, backup) => {
const backup_obj = Object.assign({}, backup);
const default_channel = self.channel;

// Set the IITC settings from the backup object into the storage
await self.storage.set(backup_obj);

// Check if the channel in the backup object is different from the original channel
const set_channel = backup_obj.channel;
if (set_channel !== default_channel) {
await self.setChannel(set_channel);
}
};

/**
* Imports plugin settings from the provided backup object.
*
* The function first retrieves all data from the storage object
* using `self.storage.get(null)` and filters out the records with keys starting with 'VMin'
* to create a new object `vMinRecords` containing only plugin-related data. The function then
* merges the `vMinRecords` object with the provided backup object using the `deepmerge` library,
* resulting in a new storage object `new_storage` that contains updated plugin settings. Finally,
* the updated storage object is set into the 'self' object using `self.storage.set()`.
*
* @async
* @param {Object} self - IITC manager object.
* @param {Object} backup - The backup object containing plugin settings to import.
* @returns {Promise<void>} A promise that resolves when the import is complete.
*/
export const importPluginsSettings = async (self, backup) => {
const all_storage = await self.storage.get(null);

// Create a new object containing only plugin-related data (keys starting with 'VMin')
const vMinRecords = {};
Object.keys(all_storage).forEach((key) => {
if (key.startsWith('VMin')) {
vMinRecords[key] = all_storage[key];
}
});

// Merge the 'vMinRecords' object with the provided backup object and set into storage
const new_storage = deepmerge(vMinRecords, backup);
await self.storage.set(new_storage);
};

/**
* Imports external plugins from the provided backup object.
*
* The function iterates through each channel in the backup object,
* sets the current channel using `self.setChannel()`, and then extracts the plugin information
* (metadata and code) for each plugin in the channel. The plugin information is added to the 'scripts'
* array, which is then passed to `self.addUserScripts()` to add the external plugins. After processing
* all channels, the function sets the default channel using `self.setChannel()` if it was changed during
* the import process.
*
* @async
* @param {Object} self - IITC manager object.
* @param {Object} backup - The backup object containing external plugins to import.
* @returns {Promise<void>} A promise that resolves when the import is complete.
*/
export const importExternalPlugins = async (self, backup) => {
const default_channel = self.channel;

// Iterate through each channel in the backup object
for (const channel of Object.keys(backup)) {
// Initialize an empty array to store the plugin information (metadata and code)
const scripts = [];
await self.setChannel(channel);

// Iterate through each plugin in the current channel and extract plugin information
for (const [filename, code] of Object.entries(backup[channel])) {
// Parse the metadata from the plugin code using the 'parseMeta()' function
const meta = parseMeta(code);
meta['filename'] = filename;

// Push the plugin information (metadata and code) to the 'scripts' array
scripts.push({ meta: meta, code: code });
}

// Add the external plugins using the 'self.addUserScripts()' method
await self.addUserScripts(scripts);
}

// If the current channel is different from the default channel,
// set the default channel using the 'self.setChannel()' method
if (self.channel !== default_channel) {
await self.setChannel(default_channel);
}
};
56 changes: 56 additions & 0 deletions src/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { Worker } from './worker.js';
import * as migrations from './migrations.js';
import { getUID, isSet } from './helpers.js';
import * as backup from './backup.js';

/**
* @classdesc This class contains methods for managing IITC and plugins.
Expand Down Expand Up @@ -298,4 +299,59 @@ export class Manager extends Worker {
if (all_plugins === undefined) return null;
return all_plugins[uid];
}

/**
* Asynchronously retrieves backup data based on the specified parameters.
*
* @async
* @param {BackupParams} params - The parameters for the backup data retrieval.
* @return {Promise<object>} A promise that resolves to the backup data.
*/
async getBackupData(params) {
// Process the input parameters using the 'paramsProcessing' function from the 'backup' module.
params = backup.paramsProcessing(params);

// Initialize the backup_data object with its properties.
const backup_data = {
external_plugins: {},
data: {
iitc_settings: {},
plugins_data: {},
app: 'IITC Button',
},
};

// Retrieve all_storage using the 'get' method of 'storage' module.
const all_storage = await this.storage.get(null);

if (params.settings) backup_data.data.iitc_settings = backup.exportIitcSettings(all_storage);
if (params.data) backup_data.data.plugins_data = backup.exportPluginsSettings(all_storage);
if (params.external) backup_data.external_plugins = backup.exportExternalPlugins(all_storage);

// Return the backup_data object.
return backup_data;
}

/**
* Asynchronously sets backup data based on the specified parameters.
*
* This function takes the provided parameters and backup data object and sets the data
* accordingly. The input parameters are processed using the 'paramsProcessing' function
* from the 'backup' module. Depending on the parameters, the function imports IITC settings,
* plugin data, and external plugins into the 'this' object using appropriate functions from
* the 'backup' module.
*
* @async
* @param {BackupParams} params - The parameters for setting the backup data.
* @param {object} backup_data - The backup data object containing the data to be set.
* @return {Promise<void>} A promise that resolves when the backup data is set.
*/
async setBackupData(params, backup_data) {
// Process the input parameters using the 'paramsProcessing' function from the 'backup' module.
params = backup.paramsProcessing(params);

if (params.settings) await backup.importIitcSettings(this, backup_data.data.iitc_settings);
if (params.data) await backup.importPluginsSettings(this, backup_data.data.plugins_data);
if (params.external) await backup.importExternalPlugins(this, backup_data.external_plugins);
}
}
9 changes: 9 additions & 0 deletions src/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,15 @@ import { ajaxGet, clearWait, getUID, isSet, parseMeta, wait } from './helpers.js
* @property {string[]} grant
*/

/**
* Parameters for retrieving backup data.
*
* @typedef {Object} BackupParams
* @property {boolean} settings - Whether to import/export IITC settings.
* @property {boolean} data - Whether to import/export plugins' data.
* @property {boolean} external - Whether to import/export external plugins.
*/

/**
* @classdesc This class contains methods for managing IITC and plugins.
*/
Expand Down
Loading

0 comments on commit 0060a0a

Please sign in to comment.