0
0
mirror of https://github.com/openwrt/luci.git synced 2025-02-07 12:49:53 +00:00
Stan Grishin 66c0c58bbc luci-app-adblock-fast: catch up to snapshots version
Signed-off-by: Stan Grishin <stangri@melmac.ca>
2024-12-06 03:20:55 +00:00

536 lines
15 KiB
JavaScript

// Copyright MOSSDeF, 2023 Stan Grishin <stangri@melmac.ca>
// This code wouldn't have been possible without help from:
// - [@vsviridov](https://github.com/vsviridov)
"require ui";
"require rpc";
"require form";
"require baseclass";
var pkg = {
get Name() {
return "adblock-fast";
},
get ReadmeCompat() {
return "";
},
get URL() {
return (
"https://docs.openwrt.melmac.net/" + pkg.Name + "/" + pkg.ReadmeCompat
);
},
humanFileSize: function (bytes, si = false, dp = 2) {
return `%${si ? 1000 : 1024}.${dp ?? 0}mB`.format(bytes);
},
isObjEmpty: function (obj) {
return Object.keys(obj).length === 0;
},
};
var getFileUrlFilesizes = rpc.declare({
object: "luci." + pkg.Name,
method: "getFileUrlFilesizes",
params: ["name", "url"],
});
var getInitList = rpc.declare({
object: "luci." + pkg.Name,
method: "getInitList",
params: ["name"],
});
var getInitStatus = rpc.declare({
object: "luci." + pkg.Name,
method: "getInitStatus",
params: ["name"],
});
var getPlatformSupport = rpc.declare({
object: "luci." + pkg.Name,
method: "getPlatformSupport",
params: ["name"],
});
var _setInitAction = rpc.declare({
object: "luci." + pkg.Name,
method: "setInitAction",
params: ["name", "action"],
expect: { result: false },
});
var RPC = {
listeners: [],
on: function (event, callback) {
var pair = { event: event, callback: callback };
this.listeners.push(pair);
return function unsubscribe() {
this.listeners = this.listeners.filter(function (listener) {
return listener !== pair;
});
}.bind(this);
},
emit: function (event, data) {
this.listeners.forEach(function (listener) {
if (listener.event === event) {
listener.callback(data);
}
});
},
setInitAction: function (name, action) {
_setInitAction(name, action).then(
function (result) {
this.emit("setInitAction", result);
}.bind(this)
);
},
};
var status = baseclass.extend({
render: function () {
return Promise.all([L.resolveDefault(getInitStatus(pkg.Name), {})]).then(
function (data) {
var reply = {
status: (data[0] && data[0][pkg.Name]) || {
enabled: false,
status: null,
running: null,
version: null,
errors: [],
warnings: [],
force_dns_active: null,
force_dns_ports: [],
entries: null,
dns: null,
outputFile: null,
outputCache: null,
outputGzip: null,
outputFileExists: null,
outputCacheExists: null,
outputGzipExists: null,
leds: [],
},
};
var text = "";
var outputFile = reply.status.outputFile;
var outputCache = reply.status.outputCache;
var statusTable = {
statusNoInstall: _("%s is not installed or not found").format(
pkg.Name
),
statusStopped: _("Stopped"),
statusStarting: _("Starting"),
statusProcessing: _("Processing lists"),
statusRestarting: _("Restarting"),
statusForceReloading: _("Force Reloading"),
statusDownloading: _("Downloading lists"),
statusFail: _("Failed to start"),
statusSuccess: _("Active"),
};
var header = E("h2", {}, _("AdBlock-Fast - Status"));
var statusTitle = E(
"label",
{ class: "cbi-value-title" },
_("Service Status")
);
if (reply.status.version) {
text += _("Version %s").format(reply.status.version) + " - ";
switch (reply.status.status) {
case "statusSuccess":
text += statusTable[reply.status.status] + ".";
text +=
"<br />" +
_("Blocking %s domains (with %s).").format(
reply.status.entries,
reply.status.dns
);
if (reply.status.outputGzipExists) {
text += "<br />" + _("Compressed cache file created.");
}
if (reply.status.force_dns_active) {
text += "<br />" + _("Force DNS ports:");
reply.status.force_dns_ports.forEach((element) => {
text += " " + element;
});
text += ".";
}
break;
case "statusStopped":
if (reply.status.enabled) {
text += statusTable[reply.status.status] + ".";
} else {
text +=
statusTable[reply.status.status] +
" (" +
_("Disabled") +
").";
}
if (reply.status.outputCacheExists) {
text += "<br />" + _("Cache file found.");
} else if (reply.status.outputGzipExists) {
text += "<br />" + _("Compressed cache file found.");
}
break;
case "statusRestarting":
case "statusForceReloading":
case "statusDownloading":
case "statusProcessing":
text += statusTable[reply.status.status] + "...";
break;
default:
text += statusTable[reply.status.status] + ".";
break;
}
} else {
text = _("Not installed or not found");
}
var statusText = E("div", {}, text);
var statusField = E("div", { class: "cbi-value-field" }, statusText);
var statusDiv = E("div", { class: "cbi-value" }, [
statusTitle,
statusField,
]);
var warningsDiv = [];
if (reply.status.warnings && reply.status.warnings.length) {
var warningTable = {
warningExternalDnsmasqConfig: _(
"Use of external dnsmasq config file detected, please set '%s' option to '%s'"
).format("dns", "dnsmasq.conf"),
warningMissingRecommendedPackages: _(
"Missing recommended package: '%s'"
),
warningOutdatedLuciPackage: _(
"The WebUI application (luci-app-adblock-fast) is outdated, please update it"
),
warningOutdatedPrincipalPackage: _(
"The principal package (adblock-fast) is outdated, please update it"
),
warningInvalidCompressedCacheDir: _(
"Invalid compressed cache directory '%s'"
),
warningFreeRamCheckFail: _("Can't detect free RAM"),
};
var warningsTitle = E(
"label",
{ class: "cbi-value-title" },
_("Service Warnings")
);
var text = "";
reply.status.warnings.forEach((element) => {
if (element.id && warningTable[element.id])
text +=
warningTable[element.id].format(element.extra || " ") +
"<br />";
else text += _("Unknown warning") + "<br />";
});
var warningsText = E("div", {}, text);
var warningsField = E(
"div",
{ class: "cbi-value-field" },
warningsText
);
warningsDiv = E("div", { class: "cbi-value" }, [
warningsTitle,
warningsField,
]);
}
var errorsDiv = [];
if (reply.status.errors && reply.status.errors.length) {
var errorTable = {
errorConfigValidationFail: _(
"Config (%s) validation failure!"
).format("/etc/config/" + pkg.Name),
errorServiceDisabled: _("%s is currently disabled").format(
pkg.Name
),
errorNoDnsmasqIpset: _(
"The dnsmasq ipset support is enabled, but dnsmasq is either not installed or installed dnsmasq does not support ipset"
),
errorNoIpset: _(
"The dnsmasq ipset support is enabled, but ipset is either not installed or installed ipset does not support '%s' type"
).format("hash:net"),
errorNoDnsmasqNftset: _(
"The dnsmasq nft set support is enabled, but dnsmasq is either not installed or installed dnsmasq does not support nft set"
),
errorNoNft: _(
"The dnsmasq nft sets support is enabled, but nft is not installed"
),
errorNoWanGateway: _(
"The %s failed to discover WAN gateway"
).format(pkg.Name),
errorOutputDirCreate: _("Failed to create directory for %s file"),
errorOutputFileCreate: _("Failed to create '%s' file"),
errorFailDNSReload: _("Failed to restart/reload DNS resolver"),
errorSharedMemory: _("Failed to access shared memory"),
errorSorting: _("Failed to sort data file"),
errorOptimization: _("Failed to optimize data file"),
errorAllowListProcessing: _("Failed to process allow-list"),
errorDataFileFormatting: _("Failed to format data file"),
errorMovingDataFile: _(
"Failed to move temporary data file to '%s'"
).format(outputFile),
errorCreatingCompressedCache: _(
"Failed to create compressed cache"
),
errorRemovingTempFiles: _("Failed to remove temporary files"),
errorRestoreCompressedCache: _("Failed to unpack compressed cache"),
errorRestoreCache: _("Failed to move '%s' to '%s'").format(
outputCache,
outputFile
),
errorOhSnap: _(
"Failed to create block-list or restart DNS resolver"
),
errorStopping: _("Failed to stop %s").format(pkg.Name),
errorDNSReload: _("Failed to reload/restart DNS resolver"),
errorDownloadingConfigUpdate: _(
"Failed to download Config Update file"
),
errorDownloadingList: _("Failed to download %s"),
errorParsingConfigUpdate: _("Failed to parse Config Update file"),
errorParsingList: _("Failed to parse %s"),
errorNoSSLSupport: _("No HTTPS/SSL support on device"),
errorCreatingDirectory: _(
"Failed to create output/cache/gzip file directory"
),
errorDetectingFileType: _("Failed to detect format %s"),
errorNothingToDo: _(
"No blocked list URLs nor blocked-domains enabled"
),
errorTooLittleRam: _(
"Free ram (%s) is not enough to process all enabled block-lists"
),
errorCreatingBackupFile: _("failed to create backup file %s"),
errorDeletingDataFile: _("failed to delete data file %s"),
errorRestoringBackupFile: _("failed to restore backup file %s"),
errorNoOutputFile: _("failed to create final block-list %s"),
};
var errorsTitle = E(
"label",
{ class: "cbi-value-title" },
_("Service Errors")
);
var text = "";
reply.status.errors.forEach((element) => {
if (element.id && errorTable[element.id])
text +=
errorTable[element.id].format(element.extra || " ") + "!<br />";
else text += _("Unknown error") + "<br />";
});
text += _("Errors encountered, please check the %sREADME%s").format(
'<a href="' + pkg.URL + '" target="_blank">',
"</a>!<br />"
);
var errorsText = E("div", {}, text);
var errorsField = E("div", { class: "cbi-value-field" }, errorsText);
errorsDiv = E("div", { class: "cbi-value" }, [
errorsTitle,
errorsField,
]);
}
var btn_gap = E("span", {}, "&#160;&#160;");
var btn_gap_long = E(
"span",
{},
"&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;"
);
var btn_start = E(
"button",
{
class: "btn cbi-button cbi-button-apply",
disabled: true,
click: function (ev) {
ui.showModal(null, [
E(
"p",
{ class: "spinning" },
_("Starting %s service").format(pkg.Name)
),
]);
return RPC.setInitAction(pkg.Name, "start");
},
},
_("Start")
);
var btn_action_dl = E(
"button",
{
class: "btn cbi-button cbi-button-apply",
disabled: true,
click: function (ev) {
ui.showModal(null, [
E(
"p",
{ class: "spinning" },
_("Force redownloading %s block lists").format(pkg.Name)
),
]);
return RPC.setInitAction(pkg.Name, "dl");
},
},
_("Redownload")
);
var btn_action_pause = E(
"button",
{
class: "btn cbi-button cbi-button-apply",
disabled: true,
click: function (ev) {
ui.showModal(null, [
E("p", { class: "spinning" }, _("Pausing %s").format(pkg.Name)),
]);
return RPC.setInitAction(pkg.Name, "pause");
},
},
_("Pause")
);
var btn_stop = E(
"button",
{
class: "btn cbi-button cbi-button-reset",
disabled: true,
click: function (ev) {
ui.showModal(null, [
E(
"p",
{ class: "spinning" },
_("Stopping %s service").format(pkg.Name)
),
]);
return RPC.setInitAction(pkg.Name, "stop");
},
},
_("Stop")
);
var btn_enable = E(
"button",
{
class: "btn cbi-button cbi-button-apply",
disabled: true,
click: function (ev) {
ui.showModal(null, [
E(
"p",
{ class: "spinning" },
_("Enabling %s service").format(pkg.Name)
),
]);
return RPC.setInitAction(pkg.Name, "enable");
},
},
_("Enable")
);
var btn_disable = E(
"button",
{
class: "btn cbi-button cbi-button-reset",
disabled: true,
click: function (ev) {
ui.showModal(null, [
E(
"p",
{ class: "spinning" },
_("Disabling %s service").format(pkg.Name)
),
]);
return RPC.setInitAction(pkg.Name, "disable");
},
},
_("Disable")
);
if (reply.status.enabled) {
btn_enable.disabled = true;
btn_disable.disabled = false;
switch (reply.status.status) {
case "statusSuccess":
btn_start.disabled = true;
btn_action_dl.disabled = false;
btn_action_pause.disabled = false;
btn_stop.disabled = false;
break;
case "statusStopped":
btn_start.disabled = false;
btn_action_dl.disabled = true;
btn_action_pause.disabled = true;
btn_stop.disabled = true;
break;
default:
btn_start.disabled = false;
btn_action_dl.disabled = true;
btn_action_pause.disabled = true;
btn_stop.disabled = false;
btn_enable.disabled = true;
btn_disable.disabled = true;
break;
}
} else {
btn_start.disabled = true;
btn_action_dl.disabled = true;
btn_action_pause.disabled = true;
btn_stop.disabled = true;
btn_enable.disabled = false;
btn_disable.disabled = true;
}
var buttonsDiv = [];
var buttonsTitle = E(
"label",
{ class: "cbi-value-title" },
_("Service Control")
);
var buttonsText = E("div", {}, [
btn_start,
btn_gap,
// btn_action_pause,
// btn_gap,
btn_action_dl,
btn_gap,
btn_stop,
btn_gap_long,
btn_enable,
btn_gap,
btn_disable,
]);
var buttonsField = E("div", { class: "cbi-value-field" }, buttonsText);
if (reply.status.version) {
buttonsDiv = E("div", { class: "cbi-value" }, [
buttonsTitle,
buttonsField,
]);
}
return E("div", {}, [
header,
statusDiv,
warningsDiv,
errorsDiv,
buttonsDiv,
]);
}
);
},
});
RPC.on("setInitAction", function (reply) {
ui.hideModal();
location.reload();
});
return L.Class.extend({
status: status,
pkg: pkg,
getInitStatus: getInitStatus,
getFileUrlFilesizes: getFileUrlFilesizes,
getPlatformSupport: getPlatformSupport,
});