Compare commits

...
Sign in to create a new pull request.

17 commits

Author SHA1 Message Date
buzz-lightsnack-2007
ff19ca4ec1 Run the checker if the extension is ready. 2024-06-08 23:39:59 +08:00
buzz-lightsnack-2007
7a6c6deba9 set ready state of the extension 2024-06-08 23:39:44 +08:00
buzz-lightsnack-2007
1654538159 Cancel the verbose logging 2024-06-08 23:39:22 +08:00
buzz-lightsnack-2007
ec72d1bc01 Get all data and set a blank value if it doesn't exist yet. 2024-06-08 22:29:30 +08:00
buzz-lightsnack-2007
7cc22f8b11 pass options to verification in secretariat.js 2024-06-08 22:27:48 +08:00
buzz-lightsnack-2007
9c2759c41e forcing downloading to be synchronous to ensure successful writing 2024-06-08 22:26:57 +08:00
buzz-lightsnack-2007
f38d690b57 Asynchronously wait for the writing to complete 2024-06-08 17:59:52 +08:00
buzz-lightsnack-2007
ed47e40bd1 change method of writing filter content to disk
Overwrite instead of merging
2024-06-08 17:48:21 +08:00
buzz-lightsnack-2007
fffef232c0 Failure to write is a failure to update 2024-06-08 17:45:07 +08:00
buzz-lightsnack-2007
c6f1249c44 Loop through each provided entry 2024-06-08 17:36:41 +08:00
buzz-lightsnack-2007
aca048f3d6 reduce lines on template.configure() 2024-06-08 09:35:53 +08:00
buzz-lightsnack-2007
d73ddbdd7e Change the comment to reduce lines 2024-06-08 09:35:41 +08:00
buzz-lightsnack-2007
ab38de0c33 Test the URL using standardized methods when updating all filters 2024-06-08 09:35:20 +08:00
buzz-lightsnack-2007
296c9af172 Add support for bundling filters locally 2024-06-08 09:34:48 +08:00
buzz-lightsnack-2007
a2cb524edd Fix reading global data for duration 2024-06-08 09:33:41 +08:00
buzz-lightsnack-2007
46a7182cfc Merge commit '6be5039163' into development-storage 2024-06-08 09:18:46 +08:00
buzz-lightsnack-2007
7fa035ad2a grant access to all extension-bundled filters 2024-06-08 09:07:35 +08:00
5 changed files with 203 additions and 134 deletions

View file

@ -21,7 +21,7 @@
"web_accessible_resources": [
{
"matches": ["http://*/*", "https://*/*"],
"resources": ["scripts/*.js", "scripts/platform/*.js"]
"resources": ["scripts/*.js", "scripts/platform/*.js", "config/filters/*.filter"]
}
],

View file

@ -10,10 +10,25 @@ import {background, global} from "/scripts/secretariat.js";
export default class BackgroundCheck {
update = {};
status = {};
constructor () {
this.manager = new EntryManager();
this.updater();
const main = () => {
global.read([`ready`]).then((STATE) => {
if (STATE && !this.status[`ready`]) {
this.manager = new EntryManager();
this.updater();
this.status[`ready`] = true;
};
if (this.status[`ready`]) {
(this.status.wait) ? this.status.wait.cancel() : false;
};
});
};
this.status.wait = new background(() => {main();})
};
updater() {
@ -26,94 +41,96 @@ export default class BackgroundCheck {
if (!(typeof DURATION_PREFERENCES).includes(`obj`) || !DURATION_PREFERENCES || Array.isArray(DURATION_PREFERENCES)) {
DURATION_PREFERENCES = {};
DURATION_PREFERENCES[`duration`] = 24;
// Write it.
return(await global.write([`settings`, `sync`], DURATION_PREFERENCES, -1, {"silent": true}));
} else {return (true)};
return(global.write([`settings`, `sync`, `duration`], DURATION_PREFERENCES[`duration`], -1, {"silent": true}));
} else {return(true)};
};
// Set the filter management.
let filter = new FilterManager();
/*
Run the update.
@return {Promise} the last update status.
*/
const updater_run = async () => {
filter.update();
// Update the last update time.
return(await global.write([`settings`,`sync`,`last`], Date.now(), -1, {"silent": true}));
};
/*
Check if it's time to update the filters through comparing the difference of the current time and the last updated time to the expected duration.
*/
async function updater_check() {
let TIME = {};
TIME[`now`] = Date.now();
TIME[`last`] = await global.read([`settings`,`sync`,`last`], -1);
// Run if the last time is not set or if the difference is greater than the expected duration.
return (TIME[`last`] ? ((TIME[`now`] - TIME[`last`]) > DURATION_PREFERENCES[`duration`]) : true);
};
// Set the interval.
let updater_set = () => {
this.update[`checker`] = setInterval(async () => {
// Update the filters.
updater_run();
}, DURATION_PREFERENCES[`duration`]);
};
setDefaults().then((result) => {
if (result) {
/*
Check if it's time to update the filters through comparing the difference of the current time and the last updated time to the expected duration.
*/
async function updater_check() {
let TIME = {};
TIME[`now`] = Date.now();
TIME[`last`] = await global.read([`settings`,`sync`,`last`], -1);
/*
Reset the interval.
*/
const updater_reset = () => {
// Cancel the interval.
(this.update[`checker`]) ? clearInterval(this.update[`checker`]) : false;
// Run if the last time is not set or if the difference is greater than the expected duration.
return (TIME[`last`] ? ((TIME[`now`] - TIME[`last`]) > DURATION_PREFERENCES[`duration`]) : true);
// Run the updater, if necessary.
(updater_check())
? updater_run()
: false;
// Start the new interval.
updater_set();
}
const updater_background = () => {
this.update[`background`] = async () => {
if ((await global.read([`settings`, `sync`, `duration`])) ? (await global.read([`settings`, `sync`, `duration`] * (60 ** 2) * 1000 != DURATION_PREFERENCES[`duration`])) : false) {
if (await global.global.read([`settings`, `sync`, `duration`])) {
// Get the new time.
DURATION_PREFERENCES[`duration`] = await global.read([`settings`, `sync`, `duration`]) * (60 ** 2) * 1000;
// Reset the updater.
updater_reset();
}
};
};
/*
Run the update.
// Set the background checker.
new background(() => {return(this.update.background())});
}
if (!(DURATION_PREFERENCES)) {
DURATION_PREFERENCES = {};
};
@return {Promise} the promise that, once resolved, contains the last update status.
*/
const updater_run = async () => {
filter.update();
// Convert DURATION_PREFERENCES[`duration`]) from hrs to milliseconds.
if (DURATION_PREFERENCES[`duration`]) {
DURATION_PREFERENCES[`duration`] = DURATION_PREFERENCES[`duration`] * (60 ** 2) * 1000;
};
// Update the last time.
return(await global.write([`settings`,`sync`,`last`], Date.now(), -1));
};
// When the browser is started, run the updater immediately only when the filters are not updated yet.
(updater_check() || !DURATION_PREFERENCES)
? updater_run()
: false;
// Set the interval.
let updater_set = () => {
this.update[`checker`] = setInterval(async () => {
// Update the filters.
updater_run();
}, DURATION_PREFERENCES[`duration`]);
};
/*
Reset the interval.
*/
const updater_reset = () => {
// Cancel the interval.
(this.update[`checker`]) ? clearInterval(this.update[`checker`]) : false;
// Run the updater, if necessary.
(updater_check())
? updater_run()
: false;
// Start the new interval.
updater_set();
}
const updater_background = () => {
this.update[`background`] = async () => {
if ((await global.read([`settings`, `sync`, `duration`])) ? (await global.read([`settings`, `sync`, `duration`] * (60 ** 2) * 1000 != DURATION_PREFERENCES[`duration`])) : false) {
if (await global.global.read([`settings`, `sync`, `duration`])) {
// Get the new time.
DURATION_PREFERENCES[`duration`] = await global.global.read([`settings`, `sync`, `duration`]) * (60 ** 2) * 1000;
// Reset the updater.
updater_reset();
}
};
};
// Set the background checker.
new background(() => {return(this.update.background())});
}
// Convert DURATION_PREFERENCES[`duration`]) from hrs to milliseconds.
DURATION_PREFERENCES[`duration`] = DURATION_PREFERENCES[`duration`] * (60 ** 2) * 1000;
// Set the filter management.
let filter = new FilterManager();
// When the browser is started, run the updater immediately only when the filters are not updated yet.
(updater_check())
? updater_run()
: false;
// Run the background.
updater_background();
}
});
// Run the background.
updater_background();
})
}
};

View file

@ -6,6 +6,8 @@ This script provides installation run scripts.
// File importation
import {template, global} from "../secretariat.js";
import pointer from "../data/pointer.js";
import {URLs} from "../utils/URLs.js";
import net from "../utils/net.js";
// The URL for the configuration file
const config = chrome.runtime.getURL("config/config.json");
@ -41,21 +43,58 @@ export default class BackgroundImporter {
.then(async (jsonData) => {
let configuration = jsonData;
// Run the storage initialization.
delete configuration[`OOBE`];
template.set(configuration);
if ((configuration) ? Object.keys(configuration).length : false) {
// Run the storage initialization.
delete configuration[`OOBE`];
// Replace local URLs of filters to corresponding chrome extension pages.
const checkURL = async () => {
if (((typeof configuration[`settings`][`filters`]).includes(`obj`) && configuration[`settings`][`filters`]) ? Object.keys(configuration[`settings`][`filters`]).length : false) {
let FILTERS = {};
FILTERS[`current`] = configuration[`settings`][`filters`];
FILTERS[`updated`] = {};
for (let FILTER_NUMBER = 0; FILTER_NUMBER < Object.keys(FILTERS[`current`]).length; FILTER_NUMBER++) {
let SOURCE = Object.keys(FILTERS[`current`])[FILTER_NUMBER];
// Check if the URL is invalid.
if (!(URLs.test(SOURCE))) {
// Set the URL.
let ORIGIN = {"raw": SOURCE};
// If it is, it's most likely located within the extension.
ORIGIN[`local`] = chrome.runtime.getURL(`config/filters/`.concat(ORIGIN[`raw`]));
// Attempt to verify the existence of the file.
if (await net.download(ORIGIN[`local`], `json`, true)) {
FILTERS[`updated`][ORIGIN[`local`]] = FILTERS[`current`][ORIGIN[`raw`]];
};
} else {
FILTERS[`updated`][SOURCE] = FILTERS[`current`][SOURCE];
};
};
configuration[`settings`][`filters`] = FILTERS[`updated`];
return(FILTERS[`updated`]);
};
};
await checkURL();
// Set the template.
template.set(configuration);
await global.write([`ready`], true, -1);
};
})
.catch((error) => {
console.error(error);
});
}
};
trigger() {
chrome.runtime.onInstalled.addListener((details) => {
(details.reason == chrome.runtime.OnInstalledReason.INSTALL) ? this.hello() : null;
this.setup();
});
}
};
// main function
constructor () {

View file

@ -71,43 +71,47 @@ export default class FilterManager {
if (((typeof (FILTERS_ALL)).includes(`obj`) && !Array.isArray(FILTERS_ALL) && FILTERS_ALL) ? Object.keys(FILTERS_ALL).length > 0 : false) {
for (let FILTER_URL_INDEX = 0; FILTER_URL_INDEX < Object.keys(FILTERS_ALL).length; FILTER_URL_INDEX++) {
let FILTER_URL = (Object.keys(FILTERS_ALL, 1))[FILTER_URL_INDEX];
if (FILTER_URL.includes(`://`)) {
// Test the URL.
if (URLs.test(FILTER_URL)) {
filters.enqueue(FILTER_URL);
}
}
}
}
};
if (!filters.isEmpty()) {
// Inform the user of download state.
new logging (texts.localized(`settings_filters_update_status`));
while (!filters.isEmpty()) {
let filter_URL = filters.dequeue();
// Inform the user of download state.
new logging (texts.localized(`settings_filters_update_status`), filter_URL);
try {
let DOWNLOAD = await net.download(filter_URL, `JSON`, false, true);
// Only work when the filter is valid.
if (DOWNLOAD) {
// Write the filter to storage.
if (!(await global.write(["filters", filter_URL], DOWNLOAD, -1, {"silent": true, "strict": true}))) {
throw ReferenceError;
};
// Create promise of downloading.
let filter_download = net.download(filter_URL, `JSON`, false, true);
filter_download
.then(async function (result) {
// Only work when the filter is valid.
if (result) {
// Write the filter to storage.
await global.write(["filters", filter_URL], result, -1, {"silent": true});
// Add the filter to the sync list.
if ((await global.read(["settings", `filters`])) ? !((Object.keys(await global.read(["settings", `filters`]))).includes(filter_URL)) : true) {
global.write(["settings", `filters`, filter_URL], true, 1, {"silent": true});
};
// Notify that the update is completed.
new logging(texts.localized(`settings_filters_update_status_complete`),filter_URL);
}
})
.catch((error) => {
// Inform the user of the download failure.
logging.error(error.name, texts.localized(`settings_filters_update_status_failure`, null, [error.name, filter_URL]), error.stack);
});
}
// Add the filter to the sync list.
if (((await global.read(["settings", `filters`])) ? !((Object.keys(await global.read(["settings", `filters`]))).includes(filter_URL)) : true)
? (!(await global.write(["settings", `filters`, filter_URL], true, 1, {"silent": true})))
: false) {
throw ReferenceError;
};
};
} catch (error) {
// Inform the user of the download failure.
logging.error(error.name, texts.localized(`settings_filters_update_status_failure`, null, [error.name, filter_URL]), error.stack);
};
};
// Notify that the update is completed.
new logging(texts.localized(`settings_filters_update_status_complete`));
} else {
// Inform the user of the download being unnecessary.
logging.warn(texts.localized(`settings_filters_update_stop`));

View file

@ -94,7 +94,7 @@ class global {
static async write(path, data, CLOUD = -1, OPTIONS = {}) {
let DATA_INJECTED = {};
async function verify (NAME, DATA) {
async function verify (NAME, DATA, OPTIONS) {
let DATA_CHECK = {};
// Verify the presence of the data.
@ -117,11 +117,24 @@ class global {
};
// Get all data and set a blank value if it doesn't exist yet.
DATA_ALL = await global.read(null, CLOUD);
DATA_ALL = ((DATA_ALL != null && DATA_ALL != undefined && (typeof DATA_ALL).includes(`obj`)) ? Object.keys(DATA_ALL).length <= 0 : true)
if (CLOUD == 0 || CLOUD == null) {
const ORIGINS = {};
ORIGINS[-1] = `local`;
ORIGINS[1] = `global`;
for (let SOURCE = -1; SOURCE != 0 && SOURCE < 2; SOURCE = SOURCE + 2) {
DATA_ALL[ORIGINS[SOURCE]] = await global.read(null, CLOUD);
};
CLOUD = (DATA_ALL[`local`] != null) ? -1 : 1;
} else {
DATA_ALL = await global.read(null, CLOUD);
};
DATA_ALL = ((!(typeof DATA_ALL).includes(`undef`)) ? ((DATA_ALL != null && (typeof DATA_ALL).includes(`obj`)) ? Object.keys(DATA_ALL).length <= 0 : true) : false)
? {}
: DATA_ALL;
// Set the data name.
let DATA_NAME = (!(Array.isArray(path)) && path && path != undefined)
? String(path).trim().split(",")
@ -130,15 +143,14 @@ class global {
// Merge!
DATA_INJECTED = nested.dictionary.set(DATA_ALL, (DATA_NAME != null) ? [...DATA_NAME] : DATA_NAME, data, OPTIONS);
// If cloud is not selected, get where the data is already existent.
(CLOUD == 0 || CLOUD == null)
? (CLOUD = (DATA_ALL[`local`] != null) ? -1 : 1)
: false;
// Write!
chrome.storage[(CLOUD > 0) ? `sync` : `local`].set(DATA_INJECTED);
GUI_INFO[`log`] ? GUI_INFO[`log`].clear() : false;
return ((OPTIONS[`verify`] != null ? (OPTIONS[`verify`]) : true) ? verify(DATA_NAME, data) : true);
return(chrome.storage[(CLOUD > 0) ? `sync` : `local`].set(DATA_INJECTED).then(async () => {
GUI_INFO[`log`] ? GUI_INFO[`log`].clear() : false;
return (((OPTIONS[`verify`] != null ? (OPTIONS[`verify`]) : true) ? await verify(DATA_NAME, data, OPTIONS) : true));
}).catch((err) => {
logging.error((new texts(`error_msg_save_failed`)).localized, DATA_NAME.join(``), JSON.stringify(data))
return (false);
}));
}
/*
@ -257,7 +269,6 @@ export async function compare(PATH, DATA) {
return (RESULT);
}
let COMPARISON = {};
COMPARISON[`test`] = (PATH) ? DATA : DATA[1];
COMPARISON[`against`] = (PATH) ? (await global.read((Array.isArray(PATH)) ? [...PATH] : PATH)) : DATA[0];
@ -285,8 +296,7 @@ class template {
})
});
// Merge the data.
// Managed > Synchronized > Imported > Local
// Merge the data, such that Managed > Synchronized > Imported > Local.
// Set managed preferences.
managed.reinforce();
@ -310,16 +320,15 @@ class template {
? global.write(PREFERENCE[`name`], PREFERENCES[`all`][`build`][PREFERENCE[`name`]], -1)
: false;
});
}
};
};
/*
Use our preferences when handling the data.
*/
static configure() {
chrome.storage.session.setAccessLevel(
{accessLevel: 'TRUSTED_AND_UNTRUSTED_CONTEXTS'}
);
chrome.storage.session.setAccessLevel({accessLevel: 'TRUSTED_AND_UNTRUSTED_CONTEXTS'});
}
}