luci-app-adblock: major update 1080/head
authorDirk Brenken <dev@brenken.org>
Sat, 25 Mar 2017 20:58:51 +0000 (21:58 +0100)
committerDirk Brenken <dev@brenken.org>
Sun, 26 Mar 2017 06:49:02 +0000 (08:49 +0200)
* multi-tab navigation
  Overview/View Logfile/Advanced
  Advanced: Edit Blacklist/Whitelist/Configuration
  Query domains
* all adblock options are now configurable via LuCI

Signed-off-by: Dirk Brenken <dev@brenken.org>
applications/luci-app-adblock/Makefile
applications/luci-app-adblock/luasrc/controller/adblock.lua
applications/luci-app-adblock/luasrc/model/cbi/adblock.lua [deleted file]
applications/luci-app-adblock/luasrc/model/cbi/adblock/blacklist_tab.lua [new file with mode: 0644]
applications/luci-app-adblock/luasrc/model/cbi/adblock/configuration_tab.lua [new file with mode: 0644]
applications/luci-app-adblock/luasrc/model/cbi/adblock/overview_tab.lua [new file with mode: 0644]
applications/luci-app-adblock/luasrc/model/cbi/adblock/whitelist_tab.lua [new file with mode: 0644]
applications/luci-app-adblock/luasrc/view/adblock/config_css.htm [new file with mode: 0644]
applications/luci-app-adblock/luasrc/view/adblock/logread.htm [new file with mode: 0644]
applications/luci-app-adblock/luasrc/view/adblock/query.htm [new file with mode: 0644]
applications/luci-app-adblock/luasrc/view/adblock/runtime.htm [new file with mode: 0644]

index 8efe2d604855d82e26e4c2d171433988b125f0f6..5657cfc90adf8ab27db06aedf0215885deb14a36 100644 (file)
@@ -1,7 +1,6 @@
-# Copyright (C) 2016 Openwrt.org
-#
-# This is free software, licensed under the Apache License, Version 2.0 .
-#
+# Copyright 2016 Hannu Nyman
+# Copyright 2017 Dirk Brenken (dev@brenken.org)
+# This is free software, licensed under the Apache License, Version 2.0
 
 include $(TOPDIR)/rules.mk
 
@@ -10,5 +9,3 @@ LUCI_DEPENDS:=+adblock
 LUCI_PKGARCH:=all
 
 include ../../luci.mk
-
-# call BuildPackage - OpenWrt buildroot signature
index d8b471814f89438b395e79b29052bf7fc2574bd6..bcb297603385e0a428e2627fb637f0286b2219a3 100644 (file)
@@ -1,12 +1,53 @@
--- Copyright 2016 Openwrt.org
--- Licensed to the public under the Apache License 2.0.
+-- Copyright 2016 Hannu Nyman
+-- Copyright 2017 Dirk Brenken (dev@brenken.org)
+-- This is free software, licensed under the Apache License, Version 2.0
 
 module("luci.controller.adblock", package.seeall)
 
+local fs = require("nixio.fs")
+local util = require("luci.util")
+local template = require("luci.template")
+local i18n = require("luci.i18n")
+
 function index()
        if not nixio.fs.access("/etc/config/adblock") then
                return
        end
+       entry({"admin", "services", "adblock"}, firstchild(), _("Adblock"), 30).dependent = false
+       entry({"admin", "services", "adblock", "tab_from_cbi"}, cbi("adblock/overview_tab"), _("Overview"), 10).leaf = true
+       entry({"admin", "services", "adblock", "logfile"}, call("logread"), _("View Logfile"), 20).leaf = true
+       entry({"admin", "services", "adblock", "advanced"}, firstchild(), _("Advanced"), 100)
+       entry({"admin", "services", "adblock", "advanced", "blacklist"}, cbi("adblock/blacklist_tab"), _("Edit Blacklist"), 110).leaf = true
+       entry({"admin", "services", "adblock", "advanced", "whitelist"}, cbi("adblock/whitelist_tab"), _("Edit Whitelist"), 120).leaf = true
+       entry({"admin", "services", "adblock", "advanced", "configuration"}, cbi("adblock/configuration_tab"), _("Edit Configuration"), 130).leaf = true
+       entry({"admin", "services", "adblock", "advanced", "query"}, call("query"), _("Query domains"), 140).leaf = true
+       entry({"admin", "services", "adblock", "advanced", "result"}, call("queryData"), nil, 150).leaf = true
+end
+
+function logread()
+       local logfile = util.trim(util.exec("logread -e 'adblock'"))
+       template.render("adblock/logread", {title = i18n.translate("Adblock Logfile"), content = logfile})
+end
 
-       entry({"admin", "services", "adblock"}, cbi("adblock"), _("Adblock"), 40)
+function query()
+       template.render("adblock/query", {title = i18n.translate("Adblock Domain Query")})
+end
+
+function queryData(domain)
+       if domain and domain:match("^[a-zA-Z0-9%-%._]+$") then
+               luci.http.prepare_content("text/plain")
+               local cmd = "/etc/init.d/adblock query %q 2>&1"
+               local util = io.popen(cmd % domain)
+               if util then
+                       while true do
+                               local line = util:read("*l")
+                               if not line then
+                                       break
+                               end
+                               luci.http.write(line)
+                               luci.http.write("\n")
+                       end
+                       util:close()
+               end
+       end
 end
diff --git a/applications/luci-app-adblock/luasrc/model/cbi/adblock.lua b/applications/luci-app-adblock/luasrc/model/cbi/adblock.lua
deleted file mode 100644 (file)
index 0a4a4cd..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
--- Copyright 2016 Hannu Nyman
--- Licensed to the public under the Apache License 2.0.
-
-m = Map("adblock", translate("Adblock"),
-       translate("Configuration of the adblock package to block ad/abuse domains by using DNS."))
-
--- General options
-
-s = m:section(NamedSection, "global", "adblock", translate("Global options"))
-
-o1 = s:option(Flag, "adb_enabled", translate("Enable adblock"))
-o1.rmempty = false
-o1.default = 0
-
-o3 = s:option(Value, "adb_whitelist", translate("Whitelist file"),
-     translate("File with whitelisted hosts/domains that are allowed despite being on a blocklist."))
-o3.rmempty = false
-o3.datatype = "file"
-
--- Blocklist options
-
-bl = m:section(TypedSection, "source", translate("Blocklist sources"),
-       translate("Available blocklist sources (")
-       .. [[<a href="https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md" target="_blank">]]
-       .. translate("see list details")
-       .. [[</a>]]
-       .. translate("). Note that list URLs and Shallalist category selections are not configurable via Luci."))
-bl.template = "cbi/tblsection"
-
-name = bl:option(Flag, "enabled", translate("Enabled"))
-name.rmempty  = false
-
-des = bl:option(DummyValue, "adb_src_desc", translate("Description"))
-
--- Additional options
-
-s2 = m:section(NamedSection, "global", "adblock", translate("Backup options"))
-
-o4 = s2:option(Flag, "adb_backup", translate("Enable blocklist backup"))
-o4.rmempty = false
-o4.default = 0
-
-o5 = s2:option(Value, "adb_backupdir", translate("Backup directory"))
-o5.rmempty = false
-o5.datatype = "directory"
-
--- Extra options
-
-e = m:section(NamedSection, "global", "adblock", translate("Extra options"),
-       translate("Options for further tweaking in case the defaults are not suitable for you."))
-
-a = e:option(Flag, "adb_debug", translate("Enable verbose debug logging"))
-a.default = a.disabled
-a.rmempty = false
-
-a = e:option(Value, "adb_iface", translate("Restrict reload trigger to certain interface(s)"),
-       translate("Space separated list of wan interfaces that trigger reload action. " ..
-               "To disable reload trigger set it to 'false'. Default: empty"))
-a.datatype = "network"
-a.rmempty = true
-
-return m
-
diff --git a/applications/luci-app-adblock/luasrc/model/cbi/adblock/blacklist_tab.lua b/applications/luci-app-adblock/luasrc/model/cbi/adblock/blacklist_tab.lua
new file mode 100644 (file)
index 0000000..de24d77
--- /dev/null
@@ -0,0 +1,39 @@
+-- Copyright 2016 Hannu Nyman
+-- Copyright 2017 Dirk Brenken (dev@brenken.org)
+-- This is free software, licensed under the Apache License, Version 2.0
+
+local fs = require("nixio.fs")
+local util = require("luci.util")
+local uci = require("uci")
+local adbinput = uci.get("adblock", "blacklist", "adb_src")
+
+if not nixio.fs.access(adbinput) then
+       m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
+       return m
+end
+
+m = SimpleForm("input", nil)
+       m:append(Template("adblock/config_css"))
+
+s = m:section(SimpleSection, nil,
+       translate("This form allows you to modify the content of the adblock blacklist (" .. adbinput .. ").<br />")
+       .. translate("Please add only one domain per line. Comments introduced with '#' are allowed - ip addresses, wildcards & regex are not."))
+
+f = s:option(TextValue, "data")
+       f.rmempty = true
+       f.datatype = "string"
+       f.rows = 20
+
+       function f.cfgvalue()
+               return nixio.fs.readfile(adbinput) or ""
+       end
+
+       function f.write(self, section, data)
+               return nixio.fs.writefile(adbinput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
+       end
+
+       function s.handle(self, state, data)
+               return true
+       end
+
+return m
diff --git a/applications/luci-app-adblock/luasrc/model/cbi/adblock/configuration_tab.lua b/applications/luci-app-adblock/luasrc/model/cbi/adblock/configuration_tab.lua
new file mode 100644 (file)
index 0000000..035b99e
--- /dev/null
@@ -0,0 +1,36 @@
+-- Copyright 2016 Hannu Nyman
+-- Copyright 2017 Dirk Brenken (dev@brenken.org)
+-- This is free software, licensed under the Apache License, Version 2.0
+
+local fs = require("nixio.fs")
+local util = require("luci.util")
+local adbinput = "/etc/config/adblock"
+
+if not nixio.fs.access(adbinput) then
+       m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
+       return m
+end
+
+m = SimpleForm("input", nil)
+       m:append(Template("adblock/config_css"))
+
+s = m:section(SimpleSection, nil,
+translate("This form allows you to modify the content of the main adblock configuration file (/etc/config/adblock)."))
+
+f = s:option(TextValue, "data")
+       f.rmempty = true
+       f.rows = 20
+
+       function f.cfgvalue()
+               return nixio.fs.readfile(adbinput) or ""
+       end
+
+       function f.write(self, section, data)
+               return nixio.fs.writefile(adbinput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
+       end
+
+       function s.handle(self, state, data)
+               return true
+       end
+
+return m
diff --git a/applications/luci-app-adblock/luasrc/model/cbi/adblock/overview_tab.lua b/applications/luci-app-adblock/luasrc/model/cbi/adblock/overview_tab.lua
new file mode 100644 (file)
index 0000000..5103923
--- /dev/null
@@ -0,0 +1,119 @@
+-- Copyright 2016 Hannu Nyman
+-- Copyright 2017 Dirk Brenken (dev@brenken.org)
+-- This is free software, licensed under the Apache License, Version 2.0
+
+local sys = require("luci.sys")
+local util = require("luci.util")
+local data = util.ubus("service", "get_data", "name", "adblock") or { }
+local dnsFile1 = sys.exec("find '/tmp/dnsmasq.d' -maxdepth 1 -type f -name 'adb_list*' -print")
+local dnsFile2 = sys.exec("find '/var/lib/unbound' -maxdepth 1 -type f -name 'adb_list*' -print")
+
+m = Map("adblock", translate("Adblock"),
+       translate("Configuration of the adblock package to block ad/abuse domains by using DNS. ")
+       .. translate("For further information ")
+       .. [[<a href="https://github.com/openwrt/packages/blob/master/net/adblock/files/README.md" target="_blank">]]
+       .. translate("see online documentation")
+       .. [[</a>]]
+       .. translate("."))
+
+-- Main adblock options
+
+s = m:section(NamedSection, "global", "adblock")
+
+o1 = s:option(Flag, "adb_enabled", translate("Enable adblock"))
+o1.rmempty = false
+o1.default = 0
+
+if data.adblock ~= nil and (dnsFile1 ~= "" or dnsFile2 ~= "") then
+btn = s:option( Button, "_btn", translate("Suspend adblock"))
+       btn.inputstyle = "reset"
+       function btn.write()
+               luci.sys.call("/etc/init.d/adblock suspend")
+       end
+else
+       btn = s:option( Button, "_btn", translate("Resume adblock"))
+       btn.inputstyle = "apply"
+       function btn.write()
+               luci.sys.call("/etc/init.d/adblock resume")
+       end
+end
+
+o2 = s:option(Flag, "adb_debug", translate("Enable verbose debug logging"))
+o2.default = o2.disabled
+o2.rmempty = false
+
+o3 = s:option(Value, "adb_iface", translate("Restrict interface reload trigger to certain interface(s)"),
+       translate("Space separated list of interfaces that trigger a reload action. "..
+       "To disable reload trigger at all set it to 'false'."))
+o3.rmempty =false
+
+-- Runtime information
+
+       ds = s:option(DummyValue, "_dummy", translate("Runtime information"))
+       ds.template = "cbi/nullsection"
+
+       dv1 = s:option(DummyValue, "adblock_version", translate("Adblock version"))
+       if data.adblock ~= nil then
+               dv1.value = data.adblock.adblock.adblock_version or "?"
+       else
+               dv1.value = "?"
+       end
+       dv1.template = "adblock/runtime"
+
+       dv2 = s:option(DummyValue, "status", translate("Status"))
+       if dnsFile1 ~= "" or dnsFile2 ~= "" then
+               dv2.value = "active"
+       else
+               dv2.value = "suspended"
+       end
+       dv2.template = "adblock/runtime"
+
+       dv3 = s:option(DummyValue, "dns_backend", translate("DNS backend"))
+       if data.adblock ~= nil then
+               dv3.value = data.adblock.adblock.dns_backend or "?"
+       else
+               dv3.value = "?"
+       end
+       dv3.template = "adblock/runtime"
+
+       dv4 = s:option(DummyValue, "blocked_domains", translate("Blocked domains (overall)"))
+       if data.adblock ~= nil then
+               dv4.value = data.adblock.adblock.blocked_domains or "?"
+       else
+               dv4.value = "?"
+       end
+       dv4.template = "adblock/runtime"
+
+       dv5 = s:option(DummyValue, "last_rundate", translate("Last rundate"))
+       if data.adblock ~= nil then
+               dv5.value = data.adblock.adblock.last_rundate or "?"
+       else
+               dv5.value = "?"
+       end
+       dv5.template = "adblock/runtime"
+
+-- Blocklist options
+
+bl = m:section(TypedSection, "source", translate("Blocklist sources"),
+       translate("Available blocklist sources. ")
+       .. translate("Note that list URLs and Shallalist category selections are configurable in the 'Advanced' section."))
+bl.template = "cbi/tblsection"
+
+name = bl:option(Flag, "enabled", translate("Enabled"))
+name.rmempty  = false
+
+des = bl:option(DummyValue, "adb_src_desc", translate("Description"))
+
+-- Backup options
+
+s = m:section(NamedSection, "global", "adblock", translate("Backup options"))
+
+o4 = s:option(Flag, "adb_backup", translate("Enable blocklist backup"))
+o4.rmempty = false
+o4.default = 0
+
+o5 = s:option(Value, "adb_backupdir", translate("Backup directory"))
+o5.rmempty = false
+o5.datatype = "directory"
+
+return m
diff --git a/applications/luci-app-adblock/luasrc/model/cbi/adblock/whitelist_tab.lua b/applications/luci-app-adblock/luasrc/model/cbi/adblock/whitelist_tab.lua
new file mode 100644 (file)
index 0000000..52db9a6
--- /dev/null
@@ -0,0 +1,39 @@
+-- Copyright 2016 Hannu Nyman
+-- Copyright 2017 Dirk Brenken (dev@brenken.org)
+-- This is free software, licensed under the Apache License, Version 2.0
+
+local fs = require("nixio.fs")
+local util = require("luci.util")
+local uci = require("uci")
+local adbinput = uci.get("adblock", "global", "adb_whitelist") or " "
+
+if not nixio.fs.access(adbinput) then
+       m = SimpleForm("error", nil, translate("Input file not found, please check your configuration."))
+       return m
+end
+
+m = SimpleForm("input", nil)
+       m:append(Template("adblock/config_css"))
+
+s = m:section(SimpleSection, nil,
+       translate("This form allows you to modify the content of the adblock whitelist (" .. adbinput .. ").<br />")
+       .. translate("Please add only one domain per line. Comments introduced with '#' are allowed - ip addresses, wildcards & regex are not."))
+
+f = s:option(TextValue, "data")
+       f.rmempty = true
+       f.datatype = "string"
+       f.rows = 20
+
+       function f.cfgvalue()
+               return nixio.fs.readfile(adbinput) or ""
+       end
+
+       function f.write(self, section, data)
+               return nixio.fs.writefile(adbinput, "\n" .. util.trim(data:gsub("\r\n", "\n")) .. "\n")
+       end
+
+       function s.handle(self, state, data)
+               return true
+       end
+
+return m
diff --git a/applications/luci-app-adblock/luasrc/view/adblock/config_css.htm b/applications/luci-app-adblock/luasrc/view/adblock/config_css.htm
new file mode 100644 (file)
index 0000000..53493a1
--- /dev/null
@@ -0,0 +1,10 @@
+<style type="text/css">
+       textarea
+       {
+               border: 1px solid #cccccc;
+               padding: 5px;
+               font-size: 12px;
+               font-family: monospace;
+               resize: none;
+       }
+</style>
diff --git a/applications/luci-app-adblock/luasrc/view/adblock/logread.htm b/applications/luci-app-adblock/luasrc/view/adblock/logread.htm
new file mode 100644 (file)
index 0000000..4a5585f
--- /dev/null
@@ -0,0 +1,15 @@
+<%#
+Copyright 2016 Hannu Nyman
+Copyright 2017 Dirk Brenken (dev@brenken.org)
+This is free software, licensed under the Apache License, Version 2.0
+-%>
+
+<%+header%>
+
+<div class="cbi-map">
+       <fieldset class="cbi-section">
+               <div class="cbi-section-descr">This form shows the syslog output, pre-filtered for adblock related messages only.</div>
+               <textarea id="logread_id" style="width: 100%; height: 450px; border: 1px solid #cccccc; padding: 5px; font-size: 12px; font-family: monospace; resize: none;" readonly="readonly" wrap="off" rows="<%=content:cmatch("\n")+2%>"><%=content:pcdata()%></textarea>
+       </fieldset>
+</div>
+<%+footer%>
diff --git a/applications/luci-app-adblock/luasrc/view/adblock/query.htm b/applications/luci-app-adblock/luasrc/view/adblock/query.htm
new file mode 100644 (file)
index 0000000..841a16b
--- /dev/null
@@ -0,0 +1,66 @@
+<%#
+Copyright 2016 Hannu Nyman
+Copyright 2017 Dirk Brenken (dev@brenken.org)
+This is free software, licensed under the Apache License, Version 2.0
+-%>
+
+<%+header%>
+
+<script type="text/javascript" src="<%=resource%>/cbi.js"></script>
+<script type="text/javascript">
+//<![CDATA[
+       var stxhr = new XHR();
+
+       function update_status(data)
+       {
+               var domain = data.value;
+               var input = document.getElementById('query_input');
+               var output = document.getElementById('query_output');
+
+               if (input && output)
+               {
+                       output.innerHTML =
+                               '<img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /> ' +
+                               '<%:Waiting for command to complete...%>'
+                       ;
+                       input.parentNode.style.display = 'block';
+                       input.style.display = 'inline';
+                       stxhr.post('<%=url('admin/services/adblock/advanced/result/')%>' + domain, { token: '<%=token%>' },
+                               function(x)
+                               {
+                                       if (x.responseText)
+                                       {
+                                               input.style.display = 'none';
+                                               output.innerHTML = String.format('<pre>%h</pre>', x.responseText);
+                                       }
+                                       else
+                                       {
+                                               input.style.display = 'none';
+                                               output.innerHTML = '<span class="error"><%:Invalid domain specified!%></span>';
+                                       }
+                               }
+                       );
+               }
+       }
+//]]>
+</script>
+
+<form method="post" action="<%=REQUEST_URI%>">
+       <div class="cbi-map">
+               <fieldset class="cbi-section">
+                       <div class="cbi-section-descr">This form allows you to query active block lists for certain domains, e.g. for whitelisting.</div>
+                       <div style="width:33%; float:left;">
+                               <input style="margin: 5px 0" type="text" value="www.lede-project.org" name="input" />
+                               <input type="button" value="<%:Query%>" class="cbi-button cbi-button-apply" onclick="update_status(this.form.input)" />
+                       </div>
+                       <br style="clear:both" />
+                       <br />
+               </fieldset>
+       </div>
+       <fieldset class="cbi-section" style="display:none">
+               <legend id="query_input"><%:Collecting data...%></legend>
+               <span id="query_output"></span>
+       </fieldset>
+</form>
+
+<%+footer%>
diff --git a/applications/luci-app-adblock/luasrc/view/adblock/runtime.htm b/applications/luci-app-adblock/luasrc/view/adblock/runtime.htm
new file mode 100644 (file)
index 0000000..bb55d23
--- /dev/null
@@ -0,0 +1,11 @@
+<%#
+Copyright 2016 Hannu Nyman
+Copyright 2017 Dirk Brenken (dev@brenken.org)
+This is free software, licensed under the Apache License, Version 2.0
+-%>
+
+<%+cbi/valueheader%>
+
+<input name="runtime" id="runtime" type="text" class="cbi-input-text" style="border: none; box-shadow: none; background-color: #ffffff; color: #0069d6;" value="<%=self:cfgvalue(section)%>" disabled />
+
+<%+cbi/valuefooter%>