luci-app-simple-adblock: bugfix: get package version from opkg
[project/luci.git] / applications / luci-app-simple-adblock / luasrc / model / cbi / simple-adblock.lua
index 3ec4c4399fe763ff87fb50519cb3e80382466e47..1095d5edc26b7c9bf843bce76fa508e67cfe0503 100644 (file)
@@ -10,18 +10,24 @@ local util = require "luci.util"
 local sys = require "luci.sys"
 local jsonc = require "luci.jsonc"
 local fs = require "nixio.fs"
+local nutil = require "nixio.util"
 local http = require "luci.http"
 local dispatcher = require "luci.dispatcher"
 local enabledFlag = uci:get(packageName, "config", "enabled")
 local command, outputFile, outputCache, outputGzip
 local targetDNS = uci:get(packageName, "config", "dns")
+local checkDnsmasq = sys.call("which dnsmasq >/dev/null 2>&1") == 0 and true
+local checkUnbound = sys.call("which unbound >/dev/null 2>&1") == 0 and true
+local checkDnsmasqIpset = sys.call("dnsmasq -v 2>/dev/null | grep -q 'no-ipset' || ! dnsmasq -v 2>/dev/null | grep -q -w 'ipset'") ~= 0
+   and sys.call("ipset help hash:net >/dev/null 2>&1") and true
 
 if not targetDNS or targetDNS == "" then
        targetDNS = "dnsmasq.servers"
 end
 
 if targetDNS ~= "dnsmasq.addnhosts" and targetDNS ~= "dnsmasq.conf" and 
-        targetDNS ~= "dnsmasq.servers" and targetDNS ~= "unbound.adb_list" then
+        targetDNS ~= "dnsmasq.ipset" and targetDNS ~= "dnsmasq.servers" and 
+        targetDNS ~= "unbound.adb_list" then
        targetDNS = "dnsmasq.servers"
 end
 
@@ -43,18 +49,13 @@ elseif targetDNS == "unbound.adb_list" then
        outputGzip="/etc/" .. packageName .. ".unbound.gz"
 end
 
-m = Map("simple-adblock", translate("Simple AdBlock Settings"))
-m.apply_on_parse = true
-m.on_after_apply = function(self)
-       sys.call("/etc/init.d/simple-adblock restart")
-end
-
-local tmpfs
+local packageVersion = packageName .. " " .. tostring(util.trim(sys.exec("opkg list-installed " .. packageName .. " | awk '{print $3}'")))
+local tmpfs, tmpfsMessage, tmpfsError, tmpfsStats
+local tmpfsStatus = "statusStopped"
 if fs.access("/var/run/" .. packageName .. ".json") then
        tmpfs = jsonc.parse(util.trim(sys.exec("cat /var/run/" .. packageName .. ".json")))
 end
 
-local tmpfsVersion, tmpfsStatus, tmpfsMessage, tmpfsError, tmpfsStats = "", "Stopped"
 if tmpfs and tmpfs['data'] then
        if tmpfs['data']['status'] and tmpfs['data']['status'] ~= "" then
                tmpfsStatus = tmpfs['data']['status']
@@ -68,44 +69,80 @@ if tmpfs and tmpfs['data'] then
        if tmpfs['data']['stats'] and tmpfs['data']['stats'] ~= "" then
                tmpfsStats = tmpfs['data']['stats']
        end
-       if tmpfs['data']['version'] and tmpfs['data']['version'] ~= "" then
-               tmpfsVersion = " (" .. packageName .. " " .. tmpfs['data']['version'] .. ")"
-       end
 end
 
-h = m:section(NamedSection, "config", "simple-adblock", translate("Service Status") .. tmpfsVersion)
+local statusTable = {}
+local errorTable = {}
+statusTable["statusNoInstall"] = translatef("%s is not installed or not found", packageName)
+statusTable["statusStopped"] = translate("Stopped")
+statusTable["statusStarting"] = translate("Starting")
+statusTable["statusRestarting"] = translate("Restarting")
+statusTable["statusForceReloading"] = translate("Force Reloading")
+statusTable["statusDownloading"] = translate("Downloading")
+statusTable["statusError"] = translate("Error")
+statusTable["statusWarning"] = translate("Warning")
+statusTable["statusFail"] = translate("Fail")
+statusTable["statusSuccess"] = translate("Success")
+errorTable["errorOutputFileCreate"] = translatef("failed to create '%s' file", outputFile)
+errorTable["errorFailDNSReload"] = translate("failed to restart/reload DNS resolver")
+errorTable["errorSharedMemory"] = translate("failed to access shared memory")
+errorTable["errorSorting"] = translate("failed to sort data file")
+errorTable["errorOptimization"] = translate("failed to optimize data file")
+errorTable["errorWhitelistProcessing"] = translate("failed to process whitelist")
+errorTable["errorDataFileFormatting"] = translate("failed to format data file")
+errorTable["errorMovingDataFile"] = translatef("failed to move temporary data file to '%s'", outputFile)
+errorTable["errorCreatingCompressedCache"] = translate("failed to create compressed cache")
+errorTable["errorRemovingTempFiles"] = translate("failed to remove temporary files")
+errorTable["errorRestoreCompressedCache"] = translate("failed to unpack compressed cache")
+errorTable["errorRestoreCache"] = translatef("failed to move '%s' to '%s'", outputCache, outputFile)
+errorTable["errorOhSnap"] = translate("failed to create blocklist or restart DNS resolver")
+errorTable["errorStopping"] = translatef("failed to stop %s", packageName)
+errorTable["errorDNSReload"] = translate("failed to reload/restart DNS resolver")
+errorTable["errorDownloadingList"] = translate("failed to download")
+errorTable["errorParsingList"] = translate("failed to parse")
+
+m = Map("simple-adblock", translate("Simple AdBlock Settings"))
+m.apply_on_parse = true
+m.on_after_apply = function(self)
+       sys.call("/etc/init.d/simple-adblock restart")
+end
+
+h = m:section(NamedSection, "config", "simple-adblock", translatef("Service Status [%s]", packageVersion))
 
-if tmpfsStatus and tmpfsStatus:match("ing") then
+if tmpfsStatus == "statusStarting" or
+        tmpfsStatus == "statusRestarting" or
+        tmpfsStatus == "statusForceReloading" or
+        tmpfsStatus == "statusDownloading" then
        ss = h:option(DummyValue, "_dummy", translate("Service Status"))
        ss.template = "simple-adblock/status"
-       ss.value = tmpfsStatus .. '...'
+       ss.value = statusTable[tmpfsStatus] .. '...'
        if tmpfsMessage then
                sm = h:option(DummyValue, "_dummy", translate("Task"))
                sm.template = "simple-adblock/status"
                sm.value = tmpfsMessage
        end
 else
-       en = h:option(Button, "__toggle")
-       if enabledFlag ~= "1" or tmpfsStatus:match("Stopped") then
-               en.title      = translate("Service is disabled/stopped")
-               en.inputtitle = translate("Enable/Start")
-               en.inputstyle = "apply important"
+       if tmpfsStatus == "statusStopped" then
+               ss = h:option(DummyValue, "_dummy", translate("Service Status"))
+               ss.template = "simple-adblock/status"
+               ss.value = statusTable[tmpfsStatus]
                if fs.access(outputCache) then
                        sm = h:option(DummyValue, "_dummy", translate("Info"))
                        sm.template = "simple-adblock/status"
-                       sm.value = "Cache file containing " .. util.trim(sys.exec("wc -l < " .. outputCache)) .. " domains found."
+                       sm.value = translatef("Cache file containing %s domains found.", util.trim(sys.exec("wc -l < " .. outputCache)))
                elseif fs.access(outputGzip) then
                        sm = h:option(DummyValue, "_dummy", translate("Info"))
                        sm.template = "simple-adblock/status"
-                       sm.value = "Compressed cache file found."
+                       sm.value = translate("Compressed cache file found.")
                end
        else
-               en.title      = translate("Service is enabled/started")
-               en.inputtitle = translate("Stop/Disable")
-               en.inputstyle = "reset important"
                ss = h:option(DummyValue, "_dummy", translate("Service Status"))
                ss.template = "simple-adblock/status"
-               ss.value = tmpfsStatus
+               if tmpfsStatus == "statusSuccess" then
+                       ss.value = translatef("%s is blocking %s domains (with %s).", packageVersion, util.trim(sys.exec("wc -l < " .. outputFile)), targetDNS)
+               else
+                       ss.value = statusTable[tmpfsStatus]
+               end
                if tmpfsMessage then
                        ms = h:option(DummyValue, "_dummy", translate("Message"))
                        ms.template = "simple-adblock/status"
@@ -113,34 +150,22 @@ else
                end
                if tmpfsError then
                        es = h:option(DummyValue, "_dummy", translate("Collected Errors"))
-                       es.template = "simple-adblock/status"
-                       es.value = tmpfsError
-                       reload = h:option(Button, "__reload")
-                       reload.title      = translate("Service started with error")
-                       reload.inputtitle = translate("Reload")
-                       reload.inputstyle = "apply important"
-                       function reload.write()
-                               sys.exec("/etc/init.d/simple-adblock reload")
-                               http.redirect(dispatcher.build_url("admin/services/" .. packageName))
+                       es.template = "simple-adblock/error"
+                       es.value = ""
+                       local err, e, url
+                       for err in tmpfsError:gmatch("[%p%w]+") do
+                               if err:match("=") then
+                                       e,url = err:match("(.+)=(.+)")
+                                       es.value = translatef("%s Error: %s %s", es.value, errorTable[e], url) .. ".\n"
+                               else
+                                       es.value = translatef("%s Error: %s", es.value, errorTable[err]) .. ".\n"
+                               end
                        end
                end
        end
-       function en.write()
-               if tmpfsStatus and tmpfsStatus:match("Stopped") then
-                       enabledFlag = "1"
-               else
-                       enabledFlag = enabledFlag == "1" and "0" or "1"
-               end
-               uci:set(packageName, "config", "enabled", enabledFlag)
-               uci:save(packageName)
-               uci:commit(packageName)
-               if enabledFlag == "0" then
-                       luci.sys.init.stop(packageName)
-               else
-                       luci.sys.init.enable(packageName)
-                       luci.sys.init.start(packageName)
-               end
-               luci.http.redirect(luci.dispatcher.build_url("admin/services/" .. packageName))
+       if packageVersion ~= "" then
+               buttons = h:option(DummyValue, "_dummy")
+               buttons.template = packageName .. "/buttons"
        end
 end
 
@@ -148,7 +173,7 @@ s = m:section(NamedSection, "config", "simple-adblock", translate("Configuration
 -- General options
 s:tab("basic", translate("Basic Configuration"))
 
-o2 = s:taboption("basic", ListValue, "verbosity", translate("Output Verbosity Setting"),translate("Controls system log and console output verbosity."))
+o2 = s:taboption("basic", ListValue, "verbosity", translate("Output Verbosity Setting"), translate("Controls system log and console output verbosity."))
 o2:value("0", translate("Suppress output"))
 o2:value("1", translate("Some output"))
 o2:value("2", translate("Verbose output"))
@@ -161,13 +186,12 @@ o3.default = 1
 
 local sysfs_path = "/sys/class/leds/"
 local leds = {}
-if nixio.fs.access(sysfs_path) then
-       leds = nixio.util.consume((nixio.fs.dir(sysfs_path)))
+if fs.access(sysfs_path) then
+       leds = nutil.consume((fs.dir(sysfs_path)))
 end
 if #leds ~= 0 then
-       o4 = s:taboption("basic", Value, "led", translate("LED to indicate status"), translate("Pick the LED not already used in")
-               .. [[ <a href="]] .. luci.dispatcher.build_url("admin/system/leds") .. [[">]]
-               .. translate("System LED Configuration") .. [[</a>]] .. ".")
+       o4 = s:taboption("basic", Value, "led", translate("LED to indicate status"),
+               translatef("Pick the LED not already used in <a href=\"%s\">System LED Configuration</a>.", dispatcher.build_url("admin", "system", "leds")))
        o4.rmempty = false
        o4:value("", translate("none"))
        for k, v in ipairs(leds) do
@@ -177,13 +201,32 @@ end
 
 s:tab("advanced", translate("Advanced Configuration"))
 
-dns = s:taboption("advanced", ListValue, "dns", translate("DNS Service"), translate("Pick the DNS resolution option to create the adblock list for, see the") .. " "
-  .. [[<a href="]] .. readmeURL .. [[#dns-resolution-option" target="_blank">]]
-  .. translate("README") .. [[</a>]] .. " " .. translate("for details."))
-dns:value("dnsmasq.addnhosts", translate("DNSMASQ Additional Hosts"))
-dns:value("dnsmasq.conf", translate("DNSMASQ Config"))
-dns:value("dnsmasq.servers", translate("DNSMASQ Servers File"))
-dns:value("unbound.adb_list", translate("Unbound AdBlock List"))
+local dns_descr = translatef("Pick the DNS resolution option to create the adblock list for, see the <a href=\"%s#dns-resolution-option\" target=\"_blank\">README</a> for details.", readmeURL)
+
+if not checkDnsmasq then
+       dns_descr = dns_descr .. "<br />" .. translatef("Please note that %s is not supported on this system.", "<i>dnsmasq.addnhosts</i>")
+       dns_descr = dns_descr .. "<br />" .. translatef("Please note that %s is not supported on this system.", "<i>dnsmasq.conf</i>")
+       dns_descr = dns_descr .. "<br />" .. translatef("Please note that %s is not supported on this system.", "<i>dnsmasq.ipset</i>")
+       dns_descr = dns_descr .. "<br />" .. translatef("Please note that %s is not supported on this system.", "<i>dnsmasq.servers</i>")
+elseif not checkDnsmasqIpset then 
+       dns_descr = dns_descr .. "<br />" .. translatef("Please note that %s is not supported on this system.", "<i>dnsmasq.ipset</i>")
+end
+if not checkUnbound then 
+       dns_descr = dns_descr .. "<br />" .. translatef("Please note that %s is not supported on this system.", "<i>unbound.adb_list</i>")
+end
+
+dns = s:taboption("advanced", ListValue, "dns", translate("DNS Service"), dns_descr)
+if checkDnsmasq then
+       dns:value("dnsmasq.addnhosts", translate("DNSMASQ Additional Hosts"))
+       dns:value("dnsmasq.conf", translate("DNSMASQ Config"))
+       if checkDnsmasqIpset then
+               dns:value("dnsmasq.ipset", translate("DNSMASQ IP Set"))
+       end
+       dns:value("dnsmasq.servers", translate("DNSMASQ Servers File"))
+end
+if checkUnbound then
+       dns:value("unbound.adb_list", translate("Unbound AdBlock List"))
+end
 dns.default = "dnsmasq.servers"
 
 ipv6 = s:taboption("advanced", ListValue, "ipv6_enabled", translate("IPv6 Support"), translate("Add IPv6 entries to block-list."))
@@ -210,11 +253,6 @@ o8:value("0", translate("Do not use simultaneous processing"))
 o8:value("1", translate("Use simultaneous processing"))
 o8.default = 1
 
-o9 = s:taboption("advanced", ListValue, "allow_non_ascii", translate("Allow Non-ASCII characters in DNSMASQ file"), translate("Only enable if your version of DNSMASQ supports the use of Non-ASCII characters, otherwise DNSMASQ will fail to start."))
-o9:value("0", translate("Do not allow Non-ASCII"))
-o9:value("1", translate("Allow Non-ASCII"))
-o9.default = "0"
-
 o10 = s:taboption("advanced", ListValue, "compressed_cache", translate("Store compressed cache file on router"), translate("Attempt to create a compressed cache of block-list in the persistent memory."))
 o10:value("0", translate("Do not store compressed cache"))
 o10:value("1", translate("Store compressed cache"))