1 // Copyright 2022 Stan Grishin <stangri@melmac.ca>
2 // This code wouldn't have been possible without help from [@vsviridov](https://github.com/vsviridov)
10 get Name() { return 'simple-adblock'; },
11 get URL() { return 'https://docs.openwrt.melmac.net/' + pkg
.Name
+ '/'; },
14 var getInitList
= rpc
.declare({
15 object
: "luci." + pkg
.Name
,
16 method
: "getInitList",
20 var getInitStatus
= rpc
.declare({
21 object
: "luci." + pkg
.Name
,
22 method
: "getInitStatus",
26 var getPlatformSupport
= rpc
.declare({
27 object
: "luci." + pkg
.Name
,
28 method
: "getPlatformSupport",
32 var _setInitAction
= rpc
.declare({
33 object
: "luci." + pkg
.Name
,
34 method
: "setInitAction",
35 params
: ["name", "action"],
36 expect
: { result
: false },
41 on
: function on(event
, callback
) {
42 var pair
= { event
: event
, callback
: callback
}
43 this.listeners
.push(pair
);
44 return function unsubscribe() {
45 this.listeners
= this.listeners
.filter(function (listener
) {
46 return listener
!== pair
;
50 emit
: function emit(event
, data
) {
51 this.listeners
.forEach(function (listener
) {
52 if (listener
.event
=== event
) {
53 listener
.callback(data
);
57 getInitList
: function getInitList(name
) {
58 getInitList(name
).then(function (result
) {
59 this.emit('getInitList', result
);
62 getInitStatus
: function getInitStatus(name
) {
63 getInitStatus(name
).then(function (result
) {
64 this.emit('getInitStatus', result
);
67 getPlatformSupport
: function getPlatformSupport(name
) {
68 getPlatformSupport(name
).then(function (result
) {
69 this.emit('getPlatformSupport', result
);
72 setInitAction
: function setInitAction(name
, action
) {
73 _setInitAction(name
, action
).then(function (result
) {
74 this.emit('setInitAction', result
);
79 var status
= baseclass
.extend({
82 L
.resolveDefault(getInitStatus(), {}),
83 ]).then(function (data
) {
84 var replyStatus
= data
[0];
86 var status
= replyStatus
[pkg
.Name
];
87 var outputFile
= status
.outputFile
;
88 var outputCache
= status
.outputCache
;
90 statusNoInstall
: _("%s is not installed or not found").format(pkg
.Name
),
91 statusStopped
: _("Stopped"),
92 statusStarting
: _("Starting"),
93 statusRestarting
: _("Restarting"),
94 statusForceReloading
: _("Force Reloading"),
95 statusDownloading
: _("Downloading"),
96 statusError
: _("Error"),
97 statusWarning
: _("Warning"),
98 statusFail
: _("Fail"),
99 statusSuccess
: _("Active")
102 var header
= E('h2', {}, _("Simple AdBlock - Status"))
103 var statusTitle
= E('label', { class: 'cbi-value-title' }, _("Service Status"));
104 if (status
.version
) {
105 text
+= _("Version: %s").format(status
.version
) + " - ";
106 switch (status
.status
) {
107 case 'statusSuccess':
108 text
+= statusTable
[status
.status
] + ".";
109 text
+= "<br />" + _("Blocking %s domains (with %s).").format(status
.entries
, status
.dns
);
110 if (status
.outputGzipExists
) {
111 text
+= "<br />" + _("Compressed cache file created.");
113 if (status
.force_dns_active
) {
114 text
+= "<br />" + _("Force DNS ports:");
115 status
.force_dns_ports
.forEach(element
=> {
116 text
+= " " + element
;
121 case 'statusStopped':
122 if (status
.enabled
) {
123 text
+= statusTable
[status
.status
] + ".";
126 text
+= statusTable
[status
.status
] + _("disabled") + "."
128 if (status
.outputCacheExists
) {
129 text
+= "<br />" + _("Cache file found.");
131 else if (status
.outputGzipExists
) {
132 text
+= "<br />" + _("Compressed cache file found.");
135 case 'statusRestarting':
136 case 'statusForceReloading':
137 case 'statusDownloading':
138 text
+= statusTable
[status
.status
] + "...";
141 text
+= statusTable
[status
.status
] + ".";
146 text
= _("Not installed or not found");
148 var statusText
= E('div', {}, text
);
149 var statusField
= E('div', { class: 'cbi-value-field' }, statusText
);
150 var statusDiv
= E('div', { class: 'cbi-value' }, [statusTitle
, statusField
]);
152 var warningsDiv
= [];
153 if (status
.warnings
) {
154 var warningsTitle
= E('label', { class: 'cbi-value-title' }, _("Service Warnings"));
155 var warningsText
= E('div', {}, status
.warnings
);
156 var warningsField
= E('div', { class: 'cbi-value-field' }, warningsText
);
157 warningsDiv
= E('div', { class: 'cbi-value' }, [warningsTitle
, warningsField
]);
161 if ((status
.errors
).length
) {
163 errorOutputFileCreate
: _("failed to create '%s' file").format(outputFile
),
164 errorFailDNSReload
: _("failed to restart/reload DNS resolver"),
165 errorSharedMemory
: _("failed to access shared memory"),
166 errorSorting
: _("failed to sort data file"),
167 errorOptimization
: _("failed to optimize data file"),
168 errorAllowListProcessing
: _("failed to process allow-list"),
169 errorDataFileFormatting
: _("failed to format data file"),
170 errorMovingDataFile
: _("failed to move temporary data file to '%s'").format(outputFile
),
171 errorCreatingCompressedCache
: _("failed to create compressed cache"),
172 errorRemovingTempFiles
: _("failed to remove temporary files"),
173 errorRestoreCompressedCache
: _("failed to unpack compressed cache"),
174 errorRestoreCache
: _("failed to move '%s' to '%s'").format(outputCache
, outputFile
),
175 errorOhSnap
: _("failed to create block-list or restart DNS resolver"),
176 errorStopping
: _("failed to stop %s").format(pkg
.Name
),
177 errorDNSReload
: _("failed to reload/restart DNS resolver"),
178 errorDownloadingConfigUpdate
: _("failed to download Config Update file"),
179 errorDownloadingList
: _("failed to download"),
180 errorParsingConfigUpdate
: _("failed to parse Config Update file"),
181 errorParsingList
: _("failed to parse"),
182 errorNoSSLSupport
: _("no HTTPS/SSL support on device"),
183 errorCreatingDirectory
: _("failed to create output/cache/gzip file directory")
185 var errorsTitle
= E('label', { class: 'cbi-value-title' }, _("Service Errors"));
187 (status
.errors
).forEach(element
=> {
188 text
+= errorTable
[element
] + ".<br />";
190 var errorsText
= E('div', {}, text
);
191 var errorsField
= E('div', { class: 'cbi-value-field' }, errorsText
);
192 errorsDiv
= E('div', { class: 'cbi-value' }, [errorsTitle
, errorsField
]);
195 var btn_gap
= E('span', {}, '  ');
196 var btn_gap_long
= E('span', {}, '        ');
198 var btn_start
= E('button', {
199 'class': 'btn cbi-button cbi-button-apply',
201 click: function (ev
) {
203 E('p', { 'class': 'spinning' }, _('Starting %s service').format(pkg
.Name
))
205 return RPC
.setInitAction(pkg
.Name
, 'start');
209 var btn_action
= E('button', {
210 'class': 'btn cbi-button cbi-button-apply',
212 click: function (ev
) {
214 E('p', { 'class': 'spinning' }, _('Force re-downloading %s block lists').format(pkg
.Name
))
216 return RPC
.setInitAction(pkg
.Name
, 'dl');
218 }, _('Force Re-Download'));
220 var btn_stop
= E('button', {
221 'class': 'btn cbi-button cbi-button-reset',
223 click: function (ev
) {
225 E('p', { 'class': 'spinning' }, _('Stopping %s service').format(pkg
.Name
))
227 return RPC
.setInitAction(pkg
.Name
, 'stop');
231 var btn_enable
= E('button', {
232 'class': 'btn cbi-button cbi-button-apply',
234 click: function (ev
) {
236 E('p', { 'class': 'spinning' }, _('Enabling %s service').format(pkg
.Name
))
238 return RPC
.setInitAction(pkg
.Name
, 'enable');
242 var btn_disable
= E('button', {
243 'class': 'btn cbi-button cbi-button-reset',
245 click: function (ev
) {
247 E('p', { 'class': 'spinning' }, _('Disabling %s service').format(pkg
.Name
))
249 return RPC
.setInitAction(pkg
.Name
, 'disable');
253 if (status
.enabled
) {
254 btn_enable
.disabled
= true;
255 btn_disable
.disabled
= false;
256 switch (status
.status
) {
257 case 'statusSuccess':
258 btn_start
.disabled
= true;
259 btn_action
.disabled
= false;
260 btn_stop
.disabled
= false;
262 case 'statusStopped':
263 btn_start
.disabled
= false;
264 btn_action
.disabled
= true;
265 btn_stop
.disabled
= true;
268 btn_start
.disabled
= true;
269 btn_action
.disabled
= true;
270 btn_stop
.disabled
= true;
271 btn_enable
.disabled
= true;
272 btn_disable
.disabled
= true;
277 btn_start
.disabled
= true;
278 btn_action
.disabled
= true;
279 btn_stop
.disabled
= true;
280 btn_enable
.disabled
= false;
281 btn_disable
.disabled
= true;
285 var buttonsTitle
= E('label', { class: 'cbi-value-title' }, _("Service Control"))
286 var buttonsText
= E('div', {}, [btn_start
, btn_gap
, btn_action
, btn_gap
, btn_stop
, btn_gap_long
, btn_enable
, btn_gap
, btn_disable
]);
287 var buttonsField
= E('div', { class: 'cbi-value-field' }, buttonsText
);
288 if (status
.version
) {
289 buttonsDiv
= E('div', { class: 'cbi-value' }, [buttonsTitle
, buttonsField
]);
292 return E('div', {}, [header
, statusDiv
, warningsDiv
, errorsDiv
, buttonsDiv
]);
297 RPC
.on('setInitAction', function (reply
) {
302 return L
.Class
.extend({
304 getPlatformSupport
: getPlatformSupport