mirror of
https://github.com/openwrt/packages.git
synced 2026-05-31 06:51:51 +08:00
f64dd10a41
* Switch Hagezi URL to a more compact higher-level only domains list as we prefer it anyways and there's less processing (thanks @dave14305) * When update_config_sizes is unset, save collected sizes to RAM to improve luci app performance (thanks @sshaikh) Signed-off-by: Stan Grishin <stangri@melmac.ca>
214 lines
4.6 KiB
Ucode
214 lines
4.6 KiB
Ucode
// UCI mock for adblock-fast tests.
|
|
// Based on mwan4's UCI mock, extended with set/save/commit/changes/delete.
|
|
|
|
let mocklib = global.mocklib; // ucode-lsp disable
|
|
|
|
let byte = (str, off) => { // ucode-lsp disable
|
|
let v = ord(str, off);
|
|
return type(v) == 'array' ? v[0] : v;
|
|
};
|
|
|
|
let hash = (s) => { // ucode-lsp disable
|
|
let h = 7;
|
|
|
|
for (let i = 0; i < length(s); i++)
|
|
h = h * 31 + byte(s, i);
|
|
|
|
return h;
|
|
};
|
|
|
|
let id = (config, t, n) => { // ucode-lsp disable
|
|
while (true) {
|
|
let id = sprintf('cfg%08x', hash(t + n));
|
|
|
|
if (!exists(config, id))
|
|
return id;
|
|
|
|
n++;
|
|
}
|
|
};
|
|
|
|
let fixup_config = (config) => { // ucode-lsp disable
|
|
let rv = {};
|
|
let n_section = 0;
|
|
|
|
for (let stype in config) {
|
|
switch (type(config[stype])) {
|
|
case 'object':
|
|
config[stype] = [ config[stype] ];
|
|
/* fall through */
|
|
|
|
case 'array':
|
|
for (let idx, sobj in config[stype]) {
|
|
let sid, anon;
|
|
|
|
if (exists(sobj, '.name') && !exists(rv, sobj['.name'])) {
|
|
sid = sobj['.name'];
|
|
anon = false;
|
|
}
|
|
else {
|
|
sid = id(rv, stype, idx);
|
|
anon = true;
|
|
}
|
|
|
|
rv[sid] = {
|
|
'.index': n_section++,
|
|
...sobj,
|
|
'.name': sid,
|
|
'.type': stype,
|
|
'.anonymous': anon
|
|
};
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (let n, sid in sort(keys(rv), (a, b) => rv[a]['.index'] - rv[b]['.index']))
|
|
rv[sid]['.index'] = n;
|
|
|
|
return rv;
|
|
};
|
|
|
|
return {
|
|
cursor: () => ({
|
|
_configs: {},
|
|
_dirty: {},
|
|
|
|
load: function(file) {
|
|
let basename = replace(file, /^.+\//, ''),
|
|
path = sprintf("uci/%s.json", basename),
|
|
mock = mocklib.read_json_file(path);
|
|
|
|
if (!mock || mock != mock) {
|
|
mocklib.I("No configuration fixture defined for uci package %s.", file);
|
|
mocklib.I("Provide a mock configuration through the following JSON file:\n%s\n", path);
|
|
|
|
return null;
|
|
}
|
|
|
|
this._configs[basename] = fixup_config(mock);
|
|
},
|
|
|
|
_get_section: function(config, section) {
|
|
if (!exists(this._configs, config)) {
|
|
this.load(config);
|
|
|
|
if (!exists(this._configs, config))
|
|
return null;
|
|
}
|
|
|
|
let cfg = this._configs[config],
|
|
extended = match('' + section, /^@([A-Za-z0-9_-]+)\[(-?[0-9]+)\]$/);
|
|
|
|
if (extended) {
|
|
let stype = extended[1],
|
|
sindex = +extended[2];
|
|
|
|
let sids = sort(
|
|
filter(keys(cfg), sid => cfg[sid]['.type'] == stype),
|
|
(a, b) => cfg[a]['.index'] - cfg[b]['.index']
|
|
);
|
|
|
|
if (sindex < 0)
|
|
sindex = length(sids) + sindex;
|
|
|
|
return cfg[sids[sindex]];
|
|
}
|
|
|
|
return cfg[section];
|
|
},
|
|
|
|
get: function(config, section, option) {
|
|
let sobj = this._get_section(config, section);
|
|
|
|
if (option && index(option, ".") == 0)
|
|
return null;
|
|
else if (sobj && option)
|
|
return sobj[option];
|
|
else if (sobj)
|
|
return sobj[".type"];
|
|
},
|
|
|
|
get_all: function(config, section) {
|
|
return section ? this._get_section(config, section) : this._configs[config];
|
|
},
|
|
|
|
foreach: function(config, stype, cb) {
|
|
let rv = false;
|
|
|
|
if (!exists(this._configs, config))
|
|
this.load(config);
|
|
|
|
if (exists(this._configs, config)) {
|
|
let cfg = this._configs[config],
|
|
sids = sort(keys(cfg), (a, b) => cfg[a]['.index'] - cfg[b]['.index']);
|
|
|
|
for (let i, sid in sids) {
|
|
if (stype == null || cfg[sid]['.type'] == stype) {
|
|
if (cb({ ...(cfg[sid]) }) === false)
|
|
break;
|
|
|
|
rv = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return rv;
|
|
},
|
|
|
|
// -- Extensions for adblock-fast --
|
|
|
|
set: function(config, section, option, value) {
|
|
let sobj = this._get_section(config, section);
|
|
if (sobj) {
|
|
sobj[option] = value;
|
|
this._dirty[config] = true;
|
|
}
|
|
},
|
|
|
|
save: function(config) {
|
|
return true;
|
|
},
|
|
|
|
commit: function(config) {
|
|
delete this._dirty[config];
|
|
return true;
|
|
},
|
|
|
|
changes: function(config) {
|
|
return this._dirty[config] ? [['set']] : [];
|
|
},
|
|
|
|
revert: function(config) {
|
|
delete this._dirty[config];
|
|
},
|
|
|
|
delete: function(config, section, option) {
|
|
if (option) {
|
|
let sobj = this._get_section(config, section);
|
|
if (sobj) delete sobj[option];
|
|
} else if (section) {
|
|
if (exists(this._configs, config))
|
|
delete this._configs[config][section];
|
|
}
|
|
},
|
|
|
|
list_add: function(config, section, option, value) {
|
|
let sobj = this._get_section(config, section);
|
|
if (!sobj) return;
|
|
if (type(sobj[option]) != 'array')
|
|
sobj[option] = sobj[option] ? [sobj[option]] : [];
|
|
push(sobj[option], value);
|
|
this._dirty[config] = true;
|
|
},
|
|
|
|
list_remove: function(config, section, option, value) {
|
|
let sobj = this._get_section(config, section);
|
|
if (!sobj || type(sobj[option]) != 'array') return;
|
|
sobj[option] = filter(sobj[option], v => v != value);
|
|
this._dirty[config] = true;
|
|
},
|
|
})
|
|
};
|