luci-app-privoxy: move from openwrt/packages to openwrt/luci
authorChristian Schoenebeck <christian.schoenebeck@gmail.com>
Sat, 24 Jan 2015 09:38:54 +0000 (10:38 +0100)
committerChristian Schoenebeck <christian.schoenebeck@gmail.com>
Sat, 24 Jan 2015 09:38:54 +0000 (10:38 +0100)
* move from openwrt/packages to openwrt/luci
* adaption to new LuCI subdirectory structure
* fix error handling
* modified version handling
* fixed translations

Signed-off-by: Christian Schoenebeck <christian.schoenebeck@gmail.com>
applications/luci-app-privoxy/Makefile [new file with mode: 0644]
applications/luci-app-privoxy/luasrc/controller/privoxy.lua [new file with mode: 0755]
applications/luci-app-privoxy/luasrc/model/cbi/privoxy/apperror.lua [new file with mode: 0755]
applications/luci-app-privoxy/luasrc/model/cbi/privoxy/detail.lua [new file with mode: 0755]
applications/luci-app-privoxy/luasrc/view/privoxy/detail_logview.htm [new file with mode: 0755]
applications/luci-app-privoxy/luasrc/view/privoxy/detail_startstop.htm [new file with mode: 0644]
applications/luci-app-privoxy/po/de/privoxy.po [new file with mode: 0644]
applications/luci-app-privoxy/po/templates/privoxy.pot [new file with mode: 0644]
applications/luci-app-privoxy/root/etc/uci-defaults/luci-privoxy [new file with mode: 0755]

diff --git a/applications/luci-app-privoxy/Makefile b/applications/luci-app-privoxy/Makefile
new file mode 100644 (file)
index 0000000..67284ef
--- /dev/null
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2008-2015 The LuCI Team <luci@lists.subsignal.org>
+#
+# This is free software, licensed under the Apache License, Version 2.0 .
+#
+
+include $(TOPDIR)/rules.mk
+
+# LuCI specific settings
+LUCI_TITLE:=LuCI Support for Privoxy WEB proxy
+LUCI_DEPENDS:=+luci-mod-admin-full +privoxy
+LUCI_PKGARCH:=all
+
+PKG_NAME:=luci-app-privoxy
+
+# Version == major.minor.patch
+# increase "minor" on new functionality and "patch" on patches/optimization
+PKG_VERSION:=1.0.2
+
+# Release == build
+# increase on changes of translation files
+PKG_RELEASE:=0
+
+PKG_LICENSE:=Apache-2.0
+PKG_MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com>
+
+define Package/$(PKG_NAME)/config
+# shown in make menuconfig <Help>
+help
+       $(LUCI_TITLE)
+
+       Version   : $(PKG_VERSION)-$(PKG_RELEASE)
+       Maintainer: $(PKG_MAINTAINER)
+endef
+
+include ./luci.mk
+
+# call BuildPackage - OpenWrt buildroot signature
diff --git a/applications/luci-app-privoxy/luasrc/controller/privoxy.lua b/applications/luci-app-privoxy/luasrc/controller/privoxy.lua
new file mode 100755 (executable)
index 0000000..de73d0c
--- /dev/null
@@ -0,0 +1,117 @@
+-- Copyright 2014 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
+-- Licensed under the Apache License, Version 2.0
+
+module("luci.controller.privoxy", package.seeall)
+
+local NX   = require "nixio"
+local NXFS = require "nixio.fs"
+local HTTP = require "luci.http"
+local UCI  = require "luci.model.uci"
+local SYS  = require "luci.sys"
+
+PRIVOXY_MIN = "3.0.22-0"       -- minimum version of service required
+
+function index()
+       local _sys      = require "luci.sys"
+       local _verinst  = _sys.exec([[opkg list-installed ]] .. "privoxy" .. [[ | cut -d " " -f 3 ]])
+       local _cmd      = [[opkg compare-versions "]] .. _verinst .. [[" ">=" "]] .. "3.0.22-0" .. [["]]
+       local _verok    = tonumber(_sys.call(_cmd))
+
+       -- check config file and version
+       if not nixio.fs.access("/etc/config/privoxy") or (_verok == 0) then
+               entry( {"admin", "services", "privoxy"}, cbi("privoxy/apperror",
+                       {hideapplybtn=true, hidesavebtn=true, hideresetbtn=true }), _("Privoxy WEB proxy"), 59)
+       else
+               entry( {"admin", "services", "privoxy"}, cbi("privoxy/detail"), _("Privoxy WEB proxy"), 59)
+               entry( {"admin", "services", "privoxy", "logview"}, call("logread") ).leaf = true
+               entry( {"admin", "services", "privoxy", "startstop"}, call("startstop") ).leaf = true
+               entry( {"admin", "services", "privoxy", "status"}, call("get_pid") ).leaf = true
+       end
+end
+
+-- called by XHR.get from detail_logview.htm
+function logread()
+       -- read application settings
+       local uci     = UCI.cursor()
+       local logdir  = uci:get("privoxy", "privoxy", "logdir") or "/var/log"
+       local logfile = uci:get("privoxy", "privoxy", "logfile") or "privoxy.log"
+       uci:unload("privoxy")
+
+       local lfile=logdir .. "/" .. logfile
+       local ldata=NXFS.readfile(lfile)
+       if not ldata or #ldata == 0 then
+               ldata="_nodata_"
+       end
+       HTTP.write(ldata)
+end
+
+-- called by XHR.get from detail_startstop.htm
+function startstop()
+       local pid = get_pid(true)
+       if pid > 0 then
+               SYS.call("/etc/init.d/privoxy stop")
+               NX.nanosleep(1)         -- sleep a second
+               if NX.kill(pid, 0) then -- still running
+                       NX.kill(pid, 9) -- send SIGKILL
+               end
+               pid = 0
+       else
+               SYS.call("/etc/init.d/privoxy start")
+               NX.nanosleep(1)         -- sleep a second
+               pid = tonumber(NXFS.readfile("/var/run/privoxy.pid") or 0 )
+               if pid > 0 and not NX.kill(pid, 0) then
+                       pid = 0         -- process did not start
+               end
+       end
+       HTTP.write(tostring(pid))       -- HTTP needs string not number
+end
+
+-- called by XHR.poll from detail_startstop.htm
+-- and from lua (with parameter "true")
+function get_pid(from_lua)
+       local pid = tonumber(NXFS.readfile("/var/run/privoxy.pid") or 0 )
+       if pid > 0 and not NX.kill(pid, 0) then
+               pid = 0
+       end
+       if from_lua then
+               return pid
+       else
+               HTTP.write(tostring(pid))       -- HTTP needs string not number
+       end
+end
+
+-- get the "name" of the current active theme
+function get_theme()
+       local _uci  = UCI.cursor()
+       local _base = _uci:get("luci", "main", "mediaurlbase")  -- only pathname
+       _uci:unload("luci")
+
+       for k, v in pairs(luci.config.themes) do
+               if k:sub(1, 1) ~= "." and v == _base then
+                       return k
+               end
+       end
+       return nil
+end
+
+-- replacement of build-in Flag.parse of cbi.lua
+-- modified to mark section as changed if value changes
+-- current parse did not do this, but it is done AbstaractValue.parse()
+function flag_parse(self, section)
+       local fexists = self.map:formvalue(
+               luci.cbi.FEXIST_PREFIX .. self.config .. "." .. section .. "." .. self.option)
+
+       if fexists then
+               local fvalue = self:formvalue(section) and self.enabled or self.disabled
+               local cvalue = self:cfgvalue(section)
+               if fvalue ~= self.default or (not self.optional and not self.rmempty) then
+                       self:write(section, fvalue)
+               else
+                       self:remove(section)
+               end
+               if (fvalue ~= cvalue) then self.section.changed = true end
+       else
+               self:remove(section)
+               self.section.changed = true
+       end
+end
diff --git a/applications/luci-app-privoxy/luasrc/model/cbi/privoxy/apperror.lua b/applications/luci-app-privoxy/luasrc/model/cbi/privoxy/apperror.lua
new file mode 100755 (executable)
index 0000000..fcbb880
--- /dev/null
@@ -0,0 +1,47 @@
+-- Copyright 2014 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
+-- Licensed under the Apache License, Version 2.0
+
+local CTRL = require "luci.controller.privoxy" -- this application's controller
+local DISP = require "luci.dispatcher"
+local SYS  = require "luci.sys"
+
+local HELP = [[<a href="http://www.privoxy.org/user-manual/config.html#%s" target="_blank">%s</a>]]
+
+-- cbi-map -- ##################################################################
+local m        = Map("privoxy")
+m.title        = [[</a><a href="javascript:alert(']]
+               .. translate("Version Information")
+               .. [[\n\nluci-app-privoxy]]
+               .. [[\n\t]] .. translate("Version") .. [[:\t]]
+               .. SYS.exec([[opkg list-installed ]] .. [[luci-app-privoxy]] .. [[ | cut -d " " -f 3 ]])
+               .. [[\n\nprivoxy ]] .. translate("required") .. [[:]]
+               .. [[\n\t]] .. translate("Version") .. [[:\t]] .. CTRL.PRIVOXY_MIN .. [[ ]] .. translate("or higher")
+               .. [[\n\nprivoxy ]] .. translate("installed") .. [[:]]
+               .. [[\n\t]] .. translate("Version") .. [[:\t]]
+               .. SYS.exec([[opkg list-installed ]] .. [[privoxy]] .. [[ | cut -d " " -f 3 ]])
+               .. [[\n\n]]
+       .. [[')">]]
+       .. translate("Privoxy WEB proxy")
+m.description = translate("Privoxy is a non-caching web proxy with advanced filtering "
+               .. "capabilities for enhancing privacy, modifying web page data and HTTP headers, "
+               .. "controlling access, and removing ads and other obnoxious Internet junk.")
+
+-- cbi-section -- ##############################################################
+local s = m:section(SimpleSection)
+s.title = [[<font color="red">]] .. [[<strong>]]
+       .. translate("Software update required")
+       .. [[</strong>]] .. [[</font>]]
+
+-- old privoxy sofware version --------------------------------------------------------------
+local v    = s:option(DummyValue, "_update_needed")
+v.titleref = DISP.build_url("admin", "system", "packages")
+v.rawhtml  = true
+--v.title    = [[<h3>]] .. [[<font color="red">]] .. [[<strong>]]
+--        .. translate("Software update required")
+--        .. [[</strong>]] .. [[</font>]] .. [[</h3>]] .. [[<br />]]
+v.value    = [[<h3>]] .. [[<strong>]]
+          .. translate("The currently installed 'privoxy' package is not supported by LuCI application.")
+          .. [[<br />]]
+          .. translate("Please update to the current version!")
+          .. [[</strong>]] .. [[</h3>]]
+return m
diff --git a/applications/luci-app-privoxy/luasrc/model/cbi/privoxy/detail.lua b/applications/luci-app-privoxy/luasrc/model/cbi/privoxy/detail.lua
new file mode 100755 (executable)
index 0000000..2c846a1
--- /dev/null
@@ -0,0 +1,928 @@
+-- Copyright 2014 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
+-- Licensed under the Apache License, Version 2.0
+
+local NXFS = require "nixio.fs"
+local SYS  = require "luci.sys"
+local UTIL = require "luci.util"
+local DTYP = require "luci.cbi.datatypes"
+local CTRL = require "luci.controller.privoxy" -- this application's controller
+
+-- Bootstrap theme needs 2 or 3 additional linefeeds for tab description for better optic
+local LFLF = (CTRL.get_theme() == "Bootstrap") and [[<br /><br /><br />]] or [[]]
+local HELP = [[<a href="http://www.privoxy.org/user-manual/config.html#%s" target="_blank">%s</a>]]
+
+-- cbi-map -- ##################################################################
+local m        = Map("privoxy")
+m.title        = [[</a><a href="javascript:alert(']]
+               .. translate("Version Information")
+               .. [[\n\nluci-app-privoxy]]
+               .. [[\n\t]] .. translate("Version") .. [[:\t]]
+               .. SYS.exec([[opkg list-installed ]] .. [[luci-app-privoxy]] .. [[ | cut -d " " -f 3 ]])
+               .. [[\n\nprivoxy ]] .. translate("required") .. [[:]]
+               .. [[\n\t]] .. translate("Version") .. [[:\t]] .. CTRL.PRIVOXY_MIN .. [[ ]] .. translate("or higher")
+               .. [[\n\nprivoxy ]] .. translate("installed") .. [[:]]
+               .. [[\n\t]] .. translate("Version") .. [[:\t]]
+               .. SYS.exec([[opkg list-installed ]] .. [[privoxy]] .. [[ | cut -d " " -f 3 ]])
+               .. [[\n\n]]
+       .. [[')">]]
+       .. translate("Privoxy WEB proxy")
+m.description = translate("Privoxy is a non-caching web proxy with advanced filtering "
+               .. "capabilities for enhancing privacy, modifying web page data and HTTP headers, "
+               .. "controlling access, and removing ads and other obnoxious Internet junk.")
+               .. [[<br /><strong>]]
+               .. translate("For help use link at the relevant option")
+               .. [[</strong>]]
+function m.commit_handler(self)
+       if self.changed then    -- changes ?
+               os.execute("/etc/init.d/privoxy reload &")      -- reload configuration
+       end
+end
+
+-- cbi-section -- ##############################################################
+local ns = m:section( NamedSection, "privoxy", "privoxy")
+
+ns:tab("local",
+       translate("Local Set-up"),
+       translate("If you intend to operate Privoxy for more users than just yourself, "
+               .. "it might be a good idea to let them know how to reach you, what you block "
+               .. "and why you do that, your policies, etc.")
+               .. LFLF )
+local function err_tab_local(title, msg)
+       return string.format(translate("Local Set-up") .. " - %s: %s", title, msg )
+end
+
+ns:tab("filter",
+       translate("Files and Directories"),
+       translate("Privoxy can (and normally does) use a number of other files "
+               .. "for additional configuration, help and logging. This section of "
+               .. "the configuration file tells Privoxy where to find those other files.")
+               .. LFLF )
+local function err_tab_filter(title, msg)
+       return string.format(translate("Files and Directories") .. " - %s: %s", title, msg )
+end
+
+ns:tab("access",
+       translate("Access Control"),
+       translate("This tab controls the security-relevant aspects of Privoxy's configuration.")
+               .. LFLF )
+local function err_tab_access(title, msg)
+       return string.format(translate("Access Control") .. " - %s: %s", title, msg )
+end
+
+ns:tab("forward",
+       translate("Forwarding"),
+       translate("Configure here the routing of HTTP requests through a chain of multiple proxies. "
+               .. "Note that parent proxies can severely decrease your privacy level. "
+               .. "Also specified here are SOCKS proxies.")
+               .. LFLF )
+
+ns:tab("misc",
+       translate("Miscellaneous"),
+       nil)
+local function err_tab_misc(self, msg)
+       return string.format(translate("Miscellaneous") .. " - %s: %s", self.title_base, msg )
+end
+
+ns:tab("debug",
+       translate("Logging"),
+       nil )
+
+ns:tab("logview",
+       translate("Log File Viewer"),
+       nil )
+
+-- tab: local -- ###############################################################
+
+-- start/stop button -----------------------------------------------------------
+local btn      = ns:taboption("local", Button, "_startstop")
+btn.title      = translate("Start / Stop")
+btn.description        = translate("Start/Stop Privoxy WEB Proxy")
+btn.template   = "privoxy/detail_startstop"
+function btn.cfgvalue(self, section)
+       local pid = CTRL.get_pid(true)
+       if pid > 0 then
+               btn.inputtitle  = "PID: " .. pid
+               btn.inputstyle  = "reset"
+               btn.disabled    = false
+       else
+               btn.inputtitle  = translate("Start")
+               btn.inputstyle  = "apply"
+               btn.disabled    = false
+       end
+       return true
+end
+
+-- enabled ---------------------------------------------------------------------
+local ena      = ns:taboption("local", Flag, "_enabled")
+ena.title       = translate("Enabled")
+ena.description = translate("Enable/Disable autostart of Privoxy on system startup and interface events")
+ena.orientation = "horizontal" -- put description under the checkbox
+ena.rmempty    = false
+function ena.cfgvalue(self, section)
+       return (SYS.init.enabled("privoxy")) and "1" or "0"
+end
+function ena.validate(self, value)
+       error("Validate " .. value)
+end
+function ena.write(self, section, value)
+       --error("Write " .. value)
+       if value == "1" then
+               return SYS.init.enable("privoxy")
+       else
+               return SYS.init.disable("privoxy")
+       end
+end
+
+-- hostname --------------------------------------------------------------------
+local hn       = ns:taboption("local", Value, "hostname")
+hn.title       = string.format(HELP, "HOSTNAME", "Hostname" )
+hn.description = translate("The hostname shown on the CGI pages.")
+hn.placeholder = SYS.hostname()
+hn.optional    = true
+hn.rmempty     = true
+
+-- user-manual -----------------------------------------------------------------
+local um       = ns:taboption("local", Value, "user_manual")
+um.title       = string.format(HELP, "USER-MANUAL", "User Manual" )
+um.description = translate("Location of the Privoxy User Manual.")
+um.placeholder = "http://www.privoxy.org/user-manual/"
+um.optional    = true
+um.rmempty     = true
+
+-- admin-address ---------------------------------------------------------------
+local aa       = ns:taboption("local", Value, "admin_address")
+aa.title_base  = "Admin Email"
+aa.title       = string.format(HELP, "ADMIN-ADDRESS", aa.title_base )
+aa.description = translate("An email address to reach the Privoxy administrator.")
+aa.placeholder = "privoxy.admin@example.com"
+aa.optional    = true
+aa.rmempty     = true
+function aa.validate(self, value)
+       if not value or #value == 0 then
+               return ""
+       end
+       if not (value:match("[A-Za-z0-9%.%%%+%-]+@[A-Za-z0-9%.%%%+%-]+%.%w%w%w?%w?")) then
+               return nil, err_tab_local(self.title_base, translate("Invalid email address") )
+       end
+       return value
+end
+
+-- proxy-info-url --------------------------------------------------------------
+local piu      = ns:taboption("local", Value, "proxy_info_url")
+piu.title      = string.format(HELP, "PROXY-INFO-URL", "Proxy Info URL" )
+piu.description        = translate("A URL to documentation about the local Privoxy setup, configuration or policies.")
+piu.optional   = true
+piu.rmempty    = true
+
+-- trust-info-url --------------------------------------------------------------
+local tiu      = ns:taboption("local", DynamicList, "trust_info_url")
+tiu.title      = string.format(HELP, "TRUST-INFO-URL", "Trust Info URLs" )
+tiu.description        = translate("A URL to be displayed in the error page that users will see if access to an untrusted page is denied.")
+               .. [[<br /><strong>]]
+               .. translate("The value of this option only matters if the experimental trust mechanism has been activated.")
+               .. [[</strong>]]
+tiu.optional   = true
+tiu.rmepty     = true
+
+-- tab: filter -- ##############################################################
+
+-- logdir ----------------------------------------------------------------------
+local ld       = ns:taboption("filter", Value, "logdir")
+ld.title_base  = "Log Directory"
+ld.title       = string.format(HELP, "LOGDIR", ld.title_base )
+ld.description = translate("The directory where all logging takes place (i.e. where the logfile is located).")
+               .. [[<br />]]
+               .. translate("No trailing '/', please.")
+ld.default     = "/var/log"
+ld.rmempty     = false
+function ld.validate(self, value)
+       if not value or #value == 0 then
+               return nil, err_tab_filter(self.title_base, translate("Mandatory Input: No Directory given!") )
+       elseif not NXFS.access(value) then
+               return nil, err_tab_filter(self.title_base, translate("Directory does not exist!") )
+       else
+               return value
+       end
+end
+
+-- logfile ---------------------------------------------------------------------
+local lf       = ns:taboption("filter", Value, "logfile")
+lf.title_base  = "Log File"
+lf.title       = string.format(HELP, "LOGFILE", lf.title_base )
+lf.description = translate("The log file to use. File name, relative to log directory.")
+lf.default     = "privoxy.log"
+lf.rmempty     = false
+function lf.validate(self, value)
+       if not value or #value == 0 then
+               return nil, err_tab_filter(self.title_base, translate("Mandatory Input: No File given!") )
+       else
+               return value
+       end
+end
+
+-- confdir ---------------------------------------------------------------------
+local cd       = ns:taboption("filter", Value, "confdir")
+cd.title_base  = "Configuration Directory"
+cd.title       = string.format(HELP, "CONFDIR", cd.title_base )
+cd.description = translate("The directory where the other configuration files are located.")
+               .. [[<br />]]
+               .. translate("No trailing '/', please.")
+cd.default     = "/etc/privoxy"
+cd.rmempty     = false
+function cd.validate(self, value)
+       if not value or #value == 0 then
+               return nil, err_tab_filter(self.title_base, translate("Mandatory Input: No Directory given!") )
+       elseif not NXFS.access(value) then
+               return nil, err_tab_filter(self.title_base, translate("Directory does not exist!") )
+       else
+               return value
+       end
+end
+
+-- templdir --------------------------------------------------------------------
+local td       = ns:taboption("filter", Value, "templdir")
+td.title_base  = "Template Directory"
+td.title       = string.format(HELP, "TEMPLDIR", td.title_base )
+td.description = translate("An alternative directory where the templates are loaded from.")
+               .. [[<br />]]
+               .. translate("No trailing '/', please.")
+td.placeholder = "/etc/privoxy/templates"
+td.rmempty     = true
+function td.validate(self, value)
+       if not NXFS.access(value) then
+               return nil, err_tab_filter(self.title_base, translate("Directory does not exist!") )
+       else
+               return value
+       end
+end
+
+-- actionsfile -----------------------------------------------------------------
+local af       = ns:taboption("filter", DynamicList, "actionsfile")
+af.title_base  = "Action Files"
+af.title       = string.format(HELP, "ACTIONSFILE", af.title_base)
+af.description = translate("The actions file(s) to use. Multiple actionsfile lines are permitted, and are in fact recommended!")
+               .. [[<br /><strong>match-all.action := </strong>]]
+               .. translate("Actions that are applied to all sites and maybe overruled later on.")
+               .. [[<br /><strong>default.action := </strong>]]
+               .. translate("Main actions file")
+               .. [[<br /><strong>user.action := </strong>]]
+               .. translate("User customizations")
+af.rmempty     = false
+function af.validate(self, value)
+       if not value or #value == 0 then
+               return nil, err_tab_access(self.title_base, translate("Mandatory Input: No files given!") )
+       end
+       local confdir = cd:formvalue(ns.section)
+       local err     = false
+       local file    = ""
+       if type(value) == "table" then
+               local x
+               for _, x in ipairs(value) do
+                       if x and #x > 0 then
+                               if not NXFS.access(confdir .."/".. x) then
+                                       err  = true
+                                       file = x
+                                       break   -- break/leave for on error
+                               end
+                       end
+               end
+       else
+               if not NXFS.access(confdir .."/".. value) then
+                       err  = true
+                       file = value
+               end
+       end
+       if err then
+               return nil, string.format(err_tab_filter(self.title_base, translate("File '%s' not found inside Configuration Directory") ), file)
+       end
+       return value
+end
+
+-- filterfile ------------------------------------------------------------------
+local ff       = ns:taboption("filter", DynamicList, "filterfile")
+ff.title_base  = "Filter files"
+ff.title       = string.format(HELP, "FILTERFILE", ff.title_base )
+ff.description = translate("The filter files contain content modification rules that use regular expressions.")
+ff.rmempty     = false
+function ff.validate(self, value)
+       if not value or #value == 0 then
+               return nil, err_tab_access(self.title_base, translate("Mandatory Input: No files given!") )
+       end
+       local confdir = cd:formvalue(ns.section)
+       local err     = false
+       local file    = ""
+       if type(value) == "table" then
+               local x
+               for _, x in ipairs(value) do
+                       if x and #x > 0 then
+                               if not NXFS.access(confdir .."/".. x) then
+                                       err  = true
+                                       file = x
+                                       break   -- break/leave for on error
+                               end
+                       end
+               end
+       else
+               if not NXFS.access(confdir .."/".. value) then
+                       err  = true
+                       file = value
+               end
+       end
+       if err then
+               return nil, string.format(err_tab_filter(self.title_base, translate("File '%s' not found inside Configuration Directory") ), file )
+       end
+       return value
+end
+
+-- trustfile -------------------------------------------------------------------
+local tf       = ns:taboption("filter", Value, "trustfile")
+tf.title_base  = "Trust file"
+tf.title       = string.format(HELP, "TRUSTFILE", tf.title_base )
+tf.description = translate("The trust mechanism is an experimental feature for building white-lists "
+               .."and should be used with care.")
+               .. [[<br /><strong>]]
+               .. translate("It is NOT recommended for the casual user.")
+               .. [[</strong>]]
+tf.placeholder = "sites.trust"
+tf.rmempty     = true
+function tf.validate(self, value)
+       local confdir = cd:formvalue(ns.section)
+       local err     = false
+       local file    = ""
+       if type(value) == "table" then
+               local x
+               for _, x in ipairs(value) do
+                       if x and #x > 0 then
+                               if not NCFS.access(confdir .."/".. x) then
+                                       err  = true
+                                       file = x
+                                       break   -- break/leave for on error
+                               end
+                       end
+               end
+       else
+               if not NXFS.access(confdir .."/".. value) then
+                       err  = true
+                       file = value
+               end
+       end
+       if err then
+               return nil, string.format(err_tab_filter(self.title_base, translate("File '%s' not found inside Configuration Directory") ), file )
+       end
+       return value
+end
+
+-- tab: access -- ##############################################################
+
+-- listen-address --------------------------------------------------------------
+local la       = ns:taboption("access", DynamicList, "listen_address")
+la.title_base  = "Listen addresses"
+la.title       = string.format(HELP, "LISTEN-ADDRESS", la.title_base )
+la.description = translate("The address and TCP port on which Privoxy will listen for client requests.")
+               .. [[<br />]]
+               .. translate("Syntax: ")
+               .. "IPv4:Port / [IPv6]:Port / Host:Port"
+la.default     = "127.0.0.1:8118"
+la.rmempty     = false
+function la.validate(self, value)
+       if not value or #value == 0 then
+               return nil, err_tab_access(self.title_base, translate("Mandatory Input: No Data given!") )
+       end
+
+       local function check_value(v)
+               local _ret = UTIL.split(v, "]:")
+               local _ip
+               if _ret[2] then -- ip6 with port
+                       _ip   = string.gsub(_ret[1], "%[", "")  -- remove "[" at beginning
+                       if not DTYP.ip6addr(_ip) then
+                               return translate("Mandatory Input: No valid IPv6 address given!")
+                       elseif not DTYP.port(_ret[2]) then
+                               return translate("Mandatory Input: No valid Port given!")
+                       else
+                               return nil
+                       end
+               end
+               _ret = UTIL.split(v, ":")
+               if not _ret[2] then
+                       return translate("Mandatory Input: No Port given!")
+               end
+               if #_ret[1] > 0 and not DTYP.host(_ret[1]) then -- :8118 is valid address
+                       return translate("Mandatory Input: No valid IPv4 address or host given!")
+               elseif not DTYP.port(_ret[2]) then
+                       return translate("Mandatory Input: No valid Port given!")
+               else
+                       return nil
+               end
+       end
+
+       local err   = ""
+       local entry = ""
+       if type(value) == "table" then
+               local x
+               for _, x in ipairs(value) do
+                       if x and #x > 0 then
+                               err = check_value(x)
+                               if err then
+                                       entry = x
+                                       break
+                               end
+                       end
+               end
+       else
+               err = check_value(value)
+               entry = value
+       end
+       if err then
+               return nil, string.format(err_tab_access(self.title_base, err .. " - %s"), entry )
+       end
+       return value
+end
+
+-- permit-access ---------------------------------------------------------------
+local pa       = ns:taboption("access", DynamicList, "permit_access")
+pa.title       = string.format(HELP, "ACLS", "Permit access" )
+pa.description = translate("Who can access what.")
+               .. [[<br /><strong>]]
+               .. translate("Please read Privoxy manual for details!")
+               .. [[</strong>]]
+pa.rmempty     = true
+
+-- deny-access -----------------------------------------------------------------
+local da       = ns:taboption("access", DynamicList, "deny_access")
+da.title       = string.format(HELP, "ACLS", "Deny Access" )
+da.description = translate("Who can access what.")
+               .. [[<br /><strong>]]
+               .. translate("Please read Privoxy manual for details!")
+               .. [[</strong>]]
+da.rmempty     = true
+
+-- buffer-limit ----------------------------------------------------------------
+local bl       = ns:taboption("access", Value, "buffer_limit")
+bl.title_base  = "Buffer Limit"
+bl.title       = string.format(HELP, "BUFFER-LIMIT", bl.title_base )
+bl.description = translate("Maximum size (in KB) of the buffer for content filtering.")
+               .. [[<br />]]
+               .. translate("Value range 1 to 4096, no entry defaults to 4096")
+bl.default     = 4096
+bl.rmempty     = true
+function bl.validate(self, value)
+       local v = tonumber(value)
+       if not v then
+               return nil, err_tab_access(self.title_base, translate("Value is not a number") )
+       elseif v < 1 or v > 4096 then
+               return nil, err_tab_access(self.title_base, translate("Value not between 1 and 4096") )
+       elseif v == self.default then
+               return ""       -- dont need to save default
+       end
+       return value
+end
+
+-- toggle ----------------------------------------------------------------------
+local tgl      = ns:taboption("access", Flag, "toggle")
+tgl.title      = string.format(HELP, "TOGGLE", "Toggle Status" )
+tgl.description        = translate("Enable/Disable filtering when Privoxy starts.")
+               .. [[<br />]]
+               .. translate("Disabled == Transparent Proxy Mode")
+tgl.orientation        = "horizontal"
+tgl.default    = "1"
+tgl.rmempty    = false
+function tgl.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- enable-remote-toggle --------------------------------------------------------
+local ert      = ns:taboption("access", Flag, "enable_remote_toggle")
+ert.title      = string.format(HELP, "ENABLE-REMOTE-TOGGLE", "Enable remote toggle" )
+ert.description        = translate("Whether or not the web-based toggle feature may be used.")
+ert.orientation        = "horizontal"
+ert.rmempty    = true
+function ert.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- enable-remote-http-toggle ---------------------------------------------------
+local eht      = ns:taboption("access", Flag, "enable_remote_http_toggle")
+eht.title      = string.format(HELP, "ENABLE-REMOTE-HTTP-TOGGLE", "Enable remote toggle via HTTP" )
+eht.description        = translate("Whether or not Privoxy recognizes special HTTP headers to change toggle state.")
+               .. [[<br /><strong>]]
+               .. translate("This option will be removed in future releases as it has been obsoleted by the more general header taggers.")
+               .. [[</strong>]]
+eht.orientation        = "horizontal"
+eht.rmempty    = true
+function eht.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- enable-edit-actions ---------------------------------------------------------
+local eea      = ns:taboption("access", Flag, "enable_edit_actions")
+eea.title      = string.format(HELP, "ENABLE-EDIT-ACTIONS", "Enable action file editor" )
+eea.description        = translate("Whether or not the web-based actions file editor may be used.")
+eea.orientation        = "horizontal"
+eea.rmempty    = true
+function eea.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- enforce-blocks --------------------------------------------------------------
+local eb       = ns:taboption("access", Flag, "enforce_blocks")
+eb.title       = string.format(HELP, "ENFORCE-BLOCKS", "Enforce page blocking" )
+eb.description = translate("If enabled, Privoxy hides the 'go there anyway' link. "
+               .. "The user obviously should not be able to bypass any blocks.")
+eb.orientation = "horizontal"
+eb.rmempty     = true
+function eb.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- tab: forward -- #############################################################
+
+-- enable-proxy-authentication-forwarding --------------------------------------
+local paf      = ns:taboption("forward", Flag, "enable_proxy_authentication_forwarding")
+paf.title      = string.format(HELP, "ENABLE-PROXY-AUTHENTICATION-FORWARDING",
+               translate("Enable proxy authentication forwarding") )
+paf.description        = translate("Whether or not proxy authentication through Privoxy should work.")
+               .. [[<br /><strong>]]
+               .. translate("Enabling this option is NOT recommended if there is no parent proxy that requires authentication!")
+               .. [[</strong>]]
+--paf.orientation      = "horizontal"
+paf.rmempty    = true
+function paf.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- forward ---------------------------------------------------------------------
+local fwd      = ns:taboption("forward", DynamicList, "forward")
+fwd.title      = string.format(HELP, "FORWARD", "Forward HTTP" )
+fwd.description        = translate("To which parent HTTP proxy specific requests should be routed.")
+               .. [[<br />]]
+               .. translate("Syntax: target_pattern http_parent[:port]")
+fwd.rmempty    = true
+
+-- forward-socks4 --------------------------------------------------------------
+local fs4      = ns:taboption("forward", DynamicList, "forward_socks4")
+fs4.title      = string.format(HELP, "SOCKS", "Forward SOCKS 4" )
+fs4.description        = translate("Through which SOCKS proxy (and optionally to which parent HTTP proxy) specific requests should be routed.")
+               .. [[<br />]]
+               .. translate("Syntax: target_pattern socks_proxy[:port] http_parent[:port]")
+fs4.rmempty    = true
+
+-- forward-socks4a -------------------------------------------------------------
+local f4a      = ns:taboption("forward", DynamicList, "forward_socks4a")
+f4a.title      = string.format(HELP, "SOCKS", "Forward SOCKS 4A" )
+f4a.description = fs4.description
+f4a.rmempty    = true
+
+-- forward-socks5 --------------------------------------------------------------
+local fs5      = ns:taboption("forward", DynamicList, "forward_socks5")
+fs5.title      = string.format(HELP, "SOCKS", "Forward SOCKS 5" )
+fs5.description = fs4.description
+fs5.rmempty    = true
+
+-- forward-socks5t -------------------------------------------------------------
+local f5t      = ns:taboption("forward", DynamicList, "forward_socks5t")
+f5t.title      = string.format(HELP, "SOCKS", "Forward SOCKS 5t" )
+f5t.description = fs4.description
+f5t.rmempty    = true
+
+-- tab: misc -- ################################################################
+
+-- accept-intercepted-requests -------------------------------------------------
+local air      = ns:taboption("misc", Flag, "accept_intercepted_requests")
+air.title      = string.format(HELP, "ACCEPT-INTERCEPTED-REQUESTS", "Accept intercepted requests" )
+air.description        = translate("Whether intercepted requests should be treated as valid.")
+air.orientation        = "horizontal"
+air.rmempty    = true
+function air.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- allow-cgi-request-crunching -------------------------------------------------
+local crc      = ns:taboption("misc", Flag, "allow_cgi_request_crunching")
+crc.title      = string.format(HELP, "ALLOW-CGI-REQUEST-CRUNCHING", "Allow CGI request crunching" )
+crc.description        = translate("Whether requests to Privoxy's CGI pages can be blocked or redirected.")
+crc.orientation        = "horizontal"
+crc.rmempty    = true
+function crc.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- split-large-forms -----------------------------------------------------------
+local slf      = ns:taboption("misc", Flag, "split_large_forms")
+slf.title      = string.format(HELP, "SPLIT-LARGE-FORMS", "Split large forms" )
+slf.description        = translate("Whether the CGI interface should stay compatible with broken HTTP clients.")
+slf.orientation        = "horizontal"
+slf.rmempty    = true
+function slf.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- keep-alive-timeout ----------------------------------------------------------
+local kat      = ns:taboption("misc", Value, "keep_alive_timeout")
+kat.title_base = "Keep-alive timeout"
+kat.title      = string.format(HELP, "KEEP-ALIVE-TIMEOUT", kat.title_base)
+kat.description        = translate("Number of seconds after which an open connection will no longer be reused.")
+kat.rmempty    = true
+function kat.validate(self, value)
+       local v = tonumber(value)
+       if not v then
+               return nil, err_tab_misc(self.title_base, translate("Value is not a number") )
+       elseif v < 1 then
+               return nil, err_tab_misc(self.title_base, translate("Value not greater 0 or empty") )
+       end
+       return value
+end
+
+-- tolerate-pipelining ---------------------------------------------------------
+local tp       = ns:taboption("misc", Flag, "tolerate_pipelining")
+tp.title       = string.format(HELP, "TOLERATE-PIPELINING", "Tolerate pipelining" )
+tp.description = translate("Whether or not pipelined requests should be served.")
+tp.orientation = "horizontal"
+tp.rmempty     = true
+function tp.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- default-server-timeout ------------------------------------------------------
+local dst      = ns:taboption("misc", Value, "default_server_timeout")
+dst.title_base = "Default server timeout"
+dst.title      = string.format(HELP, "DEFAULT-SERVER-TIMEOUT", dst.title_base)
+dst.description        = translate("Assumed server-side keep-alive timeout (in seconds) if not specified by the server.")
+dst.rmempty    = true
+function dst.validate(self, value)
+       local v = tonumber(value)
+       if not v then
+               return nil, err_tab_misc(self.title_base, translate("Value is not a number") )
+       elseif v < 1 then
+               return nil, err_tab_misc(self.title_base, translate("Value not greater 0 or empty") )
+       end
+       return value
+end
+
+-- connection-sharing ----------------------------------------------------------
+local cs       = ns:taboption("misc", Flag, "connection_sharing")
+cs.title       = string.format(HELP, "CONNECTION-SHARING", "Connection sharing" )
+cs.description = translate("Whether or not outgoing connections that have been kept alive should be shared between different incoming connections.")
+cs.orientation = "horizontal"
+cs.rmempty     = true
+function cs.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- socket-timeout --------------------------------------------------------------
+local st       = ns:taboption("misc", Value, "socket_timeout")
+st.title_base  = "Socket timeout"
+st.title       = string.format(HELP, "SOCKET-TIMEOUT", st.title_base )
+st.description = translate("Number of seconds after which a socket times out if no data is received.")
+st.default     = 300
+st.rmempty     = true
+function st.validate(self, value)
+       local v = tonumber(value)
+       if not v then
+               return nil, err_tab_misc(self.title_base, translate("Value is not a number") )
+       elseif v < 1 then
+               return nil, err_tab_misc(self.title_base, translate("Value not greater 0 or empty") )
+       elseif v == self.default then
+               return ""       -- dont need to save default
+       end
+       return value
+end
+
+-- max-client-connections ------------------------------------------------------
+local mcc      = ns:taboption("misc", Value, "max_client_connections")
+mcc.title_base = "Max. client connections"
+mcc.title      = string.format(HELP, "MAX-CLIENT-CONNECTIONS", mcc.title_base )
+mcc.description        = translate("Maximum number of client connections that will be served.")
+mcc.default    = 128
+mcc.rmempty    = true
+function mcc.validate(self, value)
+       local v = tonumber(value)
+       if not v then
+               return nil, err_tab_misc(self.title_base, translate("Value is not a number") )
+       elseif v < 1 then
+               return nil, err_tab_misc(self.title_base, translate("Value not greater 0 or empty") )
+       elseif v == self.default then
+               return ""       -- dont need to save default
+       end
+       return value
+end
+
+-- handle-as-empty-doc-returns-ok ----------------------------------------------
+local her      = ns:taboption("misc", Flag, "handle_as_empty_doc_returns_ok")
+her.title      = string.format(HELP, "HANDLE-AS-EMPTY-DOC-RETURNS-OK", "Handle as empty doc returns ok" )
+her.description        = translate("The status code Privoxy returns for pages blocked with +handle-as-empty-document.")
+her.orientation        = "horizontal"
+her.rmempty    = true
+function her.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- enable-compression ----------------------------------------------------------
+local ec       = ns:taboption("misc", Flag, "enable_compression")
+ec.title       = string.format(HELP, "ENABLE-COMPRESSION", "Enable compression" )
+ec.description = translate("Whether or not buffered content is compressed before delivery.")
+ec.orientation = "horizontal"
+ec.rmempty     = true
+function ec.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- compression-level -----------------------------------------------------------
+local cl       = ns:taboption("misc", Value, "compression_level")
+cl.title_base  = "Compression level"
+cl.title       = string.format(HELP, "COMPRESSION-LEVEL", cl.title_base )
+cl.description = translate("The compression level that is passed to the zlib library when compressing buffered content.")
+cl.default     = 1
+cl.rmempty     = true
+function cl.validate(self, value)
+       local v = tonumber(value)
+       if not v then
+               return nil, err_tab_misc(self.title_base, translate("Value is not a number") )
+       elseif v < 0 or v > 9 then
+               return nil, err_tab_misc(self.title_base, translate("Value not between 0 and 9") )
+       elseif v == self.default then
+               return ""       -- don't need to save default
+       end
+       return value
+end
+
+-- client-header-order ---------------------------------------------------------
+local cho      = ns:taboption("misc", Value, "client_header_order")
+cho.title      = string.format(HELP, "CLIENT-HEADER-ORDER", "Client header order" )
+cho.description        = translate("The order in which client headers are sorted before forwarding them.")
+               .. [[<br />]]
+               .. translate("Syntax: Client header names delimited by spaces.")
+cho.rmempty    = true
+
+-- "debug"-tab definition -- ###################################################
+
+-- single-threaded -------------------------------------------------------------
+local st       = ns:taboption("debug", Flag, "single_threaded")
+st.title       = string.format(HELP, "SINGLE-THREADED", "Single Threaded" )
+st.description = translate("Whether to run only one server thread.")
+               .. [[<br /><strong>]]
+               .. translate("This option is only there for debugging purposes. It will drastically reduce performance.")
+               .. [[</strong>]]
+st.rmempty     = true
+function st.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d1       = ns:taboption("debug", Flag, "debug_1")
+d1.title       = string.format(HELP, "DEBUG", "Debug 1" )
+d1.description = translate("Log the destination for each request Privoxy let through. See also 'Debug 1024'.")
+d1.rmempty     = true
+function d1.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d2       = ns:taboption("debug", Flag, "debug_2")
+d2.title       = string.format(HELP, "DEBUG", "Debug 2" )
+d2.description = translate("Show each connection status")
+d2.rmempty     = true
+function d2.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d3       = ns:taboption("debug", Flag, "debug_4")
+d3.title       = string.format(HELP, "DEBUG", "Debug 4" )
+d3.description = translate("Show I/O status")
+d3.rmempty     = true
+function d3.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d4       = ns:taboption("debug", Flag, "debug_8")
+d4.title       = string.format(HELP, "DEBUG", "Debug 8" )
+d4.description = translate("Show header parsing")
+d4.rmempty     = true
+function d4.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d5       = ns:taboption("debug", Flag, "debug_16")
+d5.title       = string.format(HELP, "DEBUG", "Debug 16" )
+d5.description = translate("Log all data written to the network")
+d5.rmempty     = true
+function d5.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d6       = ns:taboption("debug", Flag, "debug_32")
+d6.title       = string.format(HELP, "DEBUG", "Debug 32" )
+d6.description = translate("Debug force feature")
+d6.rmempty     = true
+function d6.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d7       = ns:taboption("debug", Flag, "debug_64")
+d7.title       = string.format(HELP, "DEBUG", "Debug 64" )
+d7.description = translate("Debug regular expression filters")
+d7.rmempty     = true
+function d7.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d8       = ns:taboption("debug", Flag, "debug_128")
+d8.title       = string.format(HELP, "DEBUG", "Debug 128" )
+d8.description = translate("Debug redirects")
+d8.rmempty     = true
+function d8.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d9       = ns:taboption("debug", Flag, "debug_256")
+d9.title       = string.format(HELP, "DEBUG", "Debug 256" )
+d9.description = translate("Debug GIF de-animation")
+d9.rmempty     = true
+function d9.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d10      = ns:taboption("debug", Flag, "debug_512")
+d10.title      = string.format(HELP, "DEBUG", "Debug 512" )
+d10.description        = translate("Common Log Format")
+d10.rmempty    = true
+function d10.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d11      = ns:taboption("debug", Flag, "debug_1024")
+d11.title      = string.format(HELP, "DEBUG", "Debug 1024" )
+d11.description        = translate("Log the destination for requests Privoxy didn't let through, and the reason why.")
+d11.rmempty    = true
+function d11.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d12      = ns:taboption("debug", Flag, "debug_2048")
+d12.title      = string.format(HELP, "DEBUG", "Debug 2048" )
+d12.description        = translate("CGI user interface")
+d12.rmempty    = true
+function d12.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d13      = ns:taboption("debug", Flag, "debug_4096")
+d13.title      = string.format(HELP, "DEBUG", "Debug 4096" )
+d13.description        = translate("Startup banner and warnings.")
+d13.rmempty    = true
+function d13.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d14      = ns:taboption("debug", Flag, "debug_8192")
+d14.title      = string.format(HELP, "DEBUG", "Debug 8192" )
+d14.description        = translate("Non-fatal errors - *we highly recommended enabling this*")
+d14.rmempty    = true
+function d14.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d15      = ns:taboption("debug", Flag, "debug_32768")
+d15.title      = string.format(HELP, "DEBUG", "Debug 32768" )
+d15.description        = translate("Log all data read from the network")
+d15.rmempty    = true
+function d15.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- debug -----------------------------------------------------------------------
+local d16      = ns:taboption("debug", Flag, "debug_65536")
+d16.title      = string.format(HELP, "DEBUG", "Debug 65536" )
+d16.description        = translate("Log the applying actions")
+d16.rmempty    = true
+function d16.parse(self, section)
+       CTRL.flag_parse(self, section)
+end
+
+-- tab: logview -- #############################################################
+
+local lv       = ns:taboption("logview", DummyValue, "_logview")
+lv.template    = "privoxy/detail_logview"
+lv.inputtitle  = translate("Read / Reread log file")
+lv.rows                = 50
+function lv.cfgvalue(self, section)
+       local lfile=self.map:get(ns.section, "logdir") .. "/" .. self.map:get(ns.section, "logfile")
+       if NXFS.access(lfile) then
+               return lfile .. "\n" .. translate("Please press [Read] button")
+       end
+       return lfile .. "\n" .. translate("File not found or empty")
+end
+
+return m
diff --git a/applications/luci-app-privoxy/luasrc/view/privoxy/detail_logview.htm b/applications/luci-app-privoxy/luasrc/view/privoxy/detail_logview.htm
new file mode 100755 (executable)
index 0000000..3e19070
--- /dev/null
@@ -0,0 +1,56 @@
+
+<!-- ++ BEGIN ++ Privoxy ++ detail_logview.htm ++ -->
+<script type="text/javascript">//<![CDATA[
+       function onclick_logview(section, bottom)  {
+               // get elements
+               var txt = document.getElementById("cbid.privoxy.privoxy._logview.txt"); // TextArea
+               if ( !txt ) { return; } // security check
+               var lvXHR = new XHR();
+               lvXHR.get('<%=luci.dispatcher.build_url("admin", "services", "privoxy", "logview")%>', null,
+                       function(x) {
+                               if (x.responseText == "_nodata_")
+                                       txt.value = "<%:File not found or empty%>";
+                               else
+                                       txt.value = x.responseText;
+                               if (bottom)
+                                       txt.scrollTop = txt.scrollHeight;
+                               else
+                                       txt.scrollTop = 0;                      }
+               );
+       }
+//]]></script>
+
+<%+cbi/valueheader%>
+
+<br />
+
+<%
+-- one button on top, one at the buttom
+%>
+<input class="cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick="onclick_logview(this.name, false)"
+<%=
+attr("name", section) .. attr("id", cbid .. ".btn1") .. attr("value", self.inputtitle)
+%> />
+
+<br /><br />
+
+<%
+-- set a readable style taken from openwrt theme for textarea#syslog
+-- in openwrt theme there are problems with a width of 100 so we check for theme and set to lower value
+%>
+<textarea style="width: <%if media == "/luci-static/openwrt.org" then%>98.7%<%else%>100%<%end%> ; min-height: 500px; border: 3px solid #cccccc; padding: 5px; font-family: monospace; resize: none;" wrap="off" readonly="readonly"
+<%=
+attr("name", cbid .. ".txt") .. attr("id", cbid .. ".txt") .. ifattr(self.rows, "rows")
+%> >
+<%-=pcdata(self:cfgvalue(section))-%>
+</textarea>
+<br /><br />
+
+<%
+-- one button on top, one at the buttom
+%>
+<input class="cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick="onclick_logview(this.name, true)"
+<%= attr("name", section) .. attr("id", cbid .. ".btn2") .. attr("value", self.inputtitle) %> />
+
+<%+cbi/valuefooter%>
+<!-- ++ END ++ Privoxy ++ detail_logview.htm ++ -->
diff --git a/applications/luci-app-privoxy/luasrc/view/privoxy/detail_startstop.htm b/applications/luci-app-privoxy/luasrc/view/privoxy/detail_startstop.htm
new file mode 100644 (file)
index 0000000..b9de886
--- /dev/null
@@ -0,0 +1,49 @@
+
+<!-- ++ BEGIN ++ Privoxy ++ detail_startstop.htm ++ -->
+<script type="text/javascript">//<![CDATA[
+
+       // show XHR.poll/XHR.get response on button
+       function _data2elements(x) {
+               var btn = document.getElementById("cbid.privoxy.privoxy._startstop");
+               if ( ! btn ) { return; }        // security check
+               if (x.responseText == "0") {
+                       btn.value = "<%:Start%>";
+                       btn.className = "cbi-button cbi-button-apply";
+                       btn.disabled = false;
+               } else {
+                       btn.value = "PID: " + x.responseText;
+                       btn.className = "cbi-button cbi-button-reset";
+                       btn.disabled = false;
+               }
+       }
+
+       // event handler for start/stop button
+       function onclick_startstop(id) {
+               // do start/stop
+               var btnXHR = new XHR();
+               btnXHR.get('<%=luci.dispatcher.build_url("admin", "services", "privoxy", "startstop")%>', null,
+                       function(x) { _data2elements(x); }
+               );
+       }
+
+       XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "services", "privoxy", "status")%>', null,
+               function(x, data) { _data2elements(x); }
+       );
+
+//]]></script>
+
+<%+cbi/valueheader%>
+
+<% if self:cfgvalue(section) ~= false then
+-- We need to garantie that function cfgvalue run first to set missing parameters
+%>
+       <!-- style="font-size: 100%;" needed for openwrt theme to fix font size -->
+       <!-- type="button" onclick="..." enable standard onclick functionalty   -->
+       <input class="cbi-button cbi-input-<%=self.inputstyle or "button" %>" style="font-size: 100%;" type="button" onclick="onclick_startstop(this.id)"
+       <%=
+       attr("name", section) .. attr("id", cbid) .. attr("value", self.inputtitle) .. ifattr(self.disabled, "disabled")
+       %> />
+<% end %>
+
+<%+cbi/valuefooter%>
+<!-- ++ END ++ Privoxy ++ detail_startstop.htm ++ -->
diff --git a/applications/luci-app-privoxy/po/de/privoxy.po b/applications/luci-app-privoxy/po/de/privoxy.po
new file mode 100644 (file)
index 0000000..6ee3af4
--- /dev/null
@@ -0,0 +1,496 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: luci-app-privoxy\n"
+"POT-Creation-Date: 2015-01-18 21:48+0100\n"
+"PO-Revision-Date: 2015-01-18 21:51+0100\n"
+"Last-Translator: Christian Schoenebeck <christian.schoenebeck@gmail.com>\n"
+"Language-Team: \n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.5.4\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+
+msgid ""
+"A URL to be displayed in the error page that users will see if access to an "
+"untrusted page is denied."
+msgstr ""
+"Ein Link auf der Fehlerseite, der Benutzern angezeigt wird, wenn der Zugang "
+"zu einer nicht vertrauenswürdigen Seite verweigert wird."
+
+msgid ""
+"A URL to documentation about the local Privoxy setup, configuration or "
+"policies."
+msgstr ""
+"Ein Link zur Dokumentation über die lokale Privoxy Konfiguration und die "
+"Sicherheitseinstellungen."
+
+msgid "Access Control"
+msgstr "Zugriffskontrolle"
+
+msgid "Actions that are applied to all sites and maybe overruled later on."
+msgstr ""
+"Aktionen, die für alle Websites angewendet werden, und vielleicht später "
+"überschrieben werden."
+
+msgid "An alternative directory where the templates are loaded from."
+msgstr "Eine alternatives Verzeichnis, aus dem die Vorlagen geladen werden."
+
+msgid "An email address to reach the Privoxy administrator."
+msgstr "Eine E-Mail-Adresse, um die Privoxy-Administrator zu erreichen."
+
+msgid ""
+"Assumed server-side keep-alive timeout (in seconds) if not specified by the "
+"server."
+msgstr ""
+"Angenommenes serverseitiges Keep-Alive-Timeout (in Sekunden), falls nicht "
+"vom Server festgelegt."
+
+msgid "CGI user interface"
+msgstr "Protokolliert die CGI Benutzer Schnittstelle"
+
+msgid "Common Log Format"
+msgstr "Gemeinsames Protokollformat"
+
+msgid ""
+"Configure here the routing of HTTP requests through a chain of multiple "
+"proxies. Note that parent proxies can severely decrease your privacy level. "
+"Also specified here are SOCKS proxies."
+msgstr ""
+"Konfigurieren Sie hier das Weiterleiten von HTTP-Anforderungen durch eine "
+"Kette von mehreren Proxies. Beachten Sie, dass  übergeordnete Proxies Ihre "
+"Privatsphäre stark verringern können. Auch hier angegeben werden SOCKS-"
+"Proxies."
+
+msgid "Debug GIF de-animation"
+msgstr "Protokolliert die GIF de-animation"
+
+msgid "Debug force feature"
+msgstr "Protokolliert die 'Force' Eigenschaft"
+
+msgid "Debug redirects"
+msgstr "Protokolliert Weiterleitungen"
+
+msgid "Debug regular expression filters"
+msgstr "Protokolliert Filter für reguläre Ausdrücke"
+
+msgid "Directory does not exist!"
+msgstr "Verzeichnis existiert nicht!"
+
+msgid "Disabled == Transparent Proxy Mode"
+msgstr "Deaktiviert == Transparent Proxy Betrieb"
+
+msgid "Enable proxy authentication forwarding"
+msgstr "Aktivieren die Weiterleitung von Proxy-Authentifizierungen"
+
+msgid ""
+"Enable/Disable autostart of Privoxy on system startup and interface events"
+msgstr ""
+"Aktivieren / Deaktivieren des Autostart von Privoxy beim Systemstart und "
+"Schnittstellenereignissen."
+
+msgid "Enable/Disable filtering when Privoxy starts."
+msgstr "Aktivieren / Deaktivieren der Filterung, wenn Privoxy startet."
+
+msgid "Enabled"
+msgstr "Aktiviert"
+
+msgid ""
+"Enabling this option is NOT recommended if there is no parent proxy that "
+"requires authentication!"
+msgstr ""
+"Die Aktivierung dieser Option wird NICHT empfohlen, wenn es keinen "
+"übergeordneten Proxy gibt, der eine Authentifizierung erfordert!"
+
+msgid "File '%s' not found inside Configuration Directory"
+msgstr "Datei '%s' nicht im Konfigurationsverzeichnis gefunden!"
+
+msgid "File not found or empty"
+msgstr "Datei nicht gefunden oder leer"
+
+msgid "Files and Directories"
+msgstr "Dateien und Verzeichnisse"
+
+msgid "For help use link at the relevant option"
+msgstr ""
+"Für Hilfe zur Verwendung, benutzen Sie die Verknüpfung der betreffenden "
+"Option."
+
+msgid "Forwarding"
+msgstr "Weiterleitung"
+
+msgid ""
+"If enabled, Privoxy hides the 'go there anyway' link. The user obviously "
+"should not be able to bypass any blocks."
+msgstr ""
+"Wenn aktiviert, verbirgt Privoxy den Link 'go there anyway'. Normalerweise "
+"sollten Benutzer nicht in der Lage sein, Blockierungen zu umgehen."
+
+msgid ""
+"If you intend to operate Privoxy for more users than just yourself, it might "
+"be a good idea to let them know how to reach you, what you block and why you "
+"do that, your policies, etc."
+msgstr ""
+"Wenn Sie beabsichtigen, Privoxy für mehr Nutzer als nur sich selbst zu "
+"betreiben, ist es eine gute Idee, sie wissen zu lassen, wie sie Sie "
+"erreichen können, was Sie blockieren und warum Sie das tun, etc."
+
+msgid "Invalid email address"
+msgstr "Ungültige Email Adresse"
+
+msgid "It is NOT recommended for the casual user."
+msgstr "Es wird NICHT für den gelegentlichen Anwender empfohlen."
+
+msgid "Local Set-up"
+msgstr "Lokale Einstellungen"
+
+msgid "Location of the Privoxy User Manual."
+msgstr "Ort des Privoxy Benutzer Handbuches"
+
+msgid "Log File Viewer"
+msgstr "Protokolldatei"
+
+msgid "Log all data read from the network"
+msgstr "Protokolliert alle Daten, die vom Netzwerk gelesen werden."
+
+msgid "Log all data written to the network"
+msgstr "Protokolliert alle Daten, die auf das Netzwerk geschrieben werden."
+
+msgid "Log the applying actions"
+msgstr "Protokiolliert angewendete Aktionen"
+
+msgid ""
+"Log the destination for each request Privoxy let through. See also 'Debug "
+"1024'."
+msgstr ""
+"Protokolliert das Ziel für jede Anforderung die Privoxy durchlässt. Siehe "
+"auch 'Debug 1024'."
+
+msgid ""
+"Log the destination for requests Privoxy didn't let through, and the reason "
+"why."
+msgstr ""
+"Protokolliert das Ziel für Anfragen die Privoxy nicht durchgelassen hat, und "
+"den Grund dafür."
+
+msgid "Logging"
+msgstr "Protokollierung"
+
+msgid "Main actions file"
+msgstr "Wichtige Aktionen-Datei"
+
+msgid "Mandatory Input: No Data given!"
+msgstr "Pflichtfeld: Keine Daten angegeben!"
+
+msgid "Mandatory Input: No Directory given!"
+msgstr "Pflichtfeld: Kein Verzeichnis angegeben!"
+
+msgid "Mandatory Input: No File given!"
+msgstr "Pflichtfeld: Keine Datei angegeben!"
+
+msgid "Mandatory Input: No Port given!"
+msgstr "Pflichtfeld: Kein Port angegeben!"
+
+msgid "Mandatory Input: No files given!"
+msgstr "Pflichtfeld: Keine Dateien angegeben!"
+
+msgid "Mandatory Input: No valid IPv4 address or host given!"
+msgstr ""
+"Pflichtfeld: Keine gültige IPv4 Adresse oder gültiger Hostname angegeben!"
+
+msgid "Mandatory Input: No valid IPv6 address given!"
+msgstr "Pflichtfeld: Keine gültige IPv6 Adresse angegeben!"
+
+msgid "Mandatory Input: No valid Port given!"
+msgstr "Pflichtfeld: Keine gültige Port Nummer angegeben!"
+
+msgid "Maximum number of client connections that will be served."
+msgstr "Maximale Anzahl von Client-Verbindungen."
+
+msgid "Maximum size (in KB) of the buffer for content filtering."
+msgstr "Maximale Größe (in KB) des Puffers für die Inhaltsfilterung."
+
+msgid "Miscellaneous"
+msgstr "Verschiedenes"
+
+msgid "No trailing '/', please."
+msgstr "Bitte kein '/' am Ende."
+
+msgid "Non-fatal errors - *we highly recommended enabling this*"
+msgstr ""
+"Protokolliert nicht schwerwiegende Fehler - * Es wird dringend empfohlen, "
+"dieses zu aktivieren *"
+
+msgid ""
+"Number of seconds after which a socket times out if no data is received."
+msgstr ""
+"Anzahl der Sekunden, nach der eine Socket Timeout erfolgt, wenn keine Daten "
+"empfangen werden."
+
+msgid ""
+"Number of seconds after which an open connection will no longer be reused."
+msgstr ""
+"Anzahl von Sekunden, nach der eine offene Verbindung nicht mehr "
+"wiederverwendet wird."
+
+msgid "Please press [Read] button"
+msgstr "Bitte Protokolldatei einlesen"
+
+msgid "Please read Privoxy manual for details!"
+msgstr "Bitte lesen Sie das Privoxy Handbuch für Details!"
+
+msgid "Please update to the current version!"
+msgstr "Aktualisieren Sie bitte auf die aktuelle Version!"
+
+msgid "Privoxy WEB proxy"
+msgstr "Privoxy WEB proxy"
+
+msgid ""
+"Privoxy can (and normally does) use a number of other files for additional "
+"configuration, help and logging. This section of the configuration file "
+"tells Privoxy where to find those other files."
+msgstr ""
+"Privoxy verwendet  (was in der Regel der Fall ist), eine Reihe von anderen "
+"Dateien für eine zusätzliche Konfiguration, Hilfe und Protokollierung. "
+"Dieser Abschnitt der Konfigurationsdatei definiert, wo diese Dateien zu "
+"finden sind."
+
+msgid ""
+"Privoxy is a non-caching web proxy with advanced filtering capabilities for "
+"enhancing privacy, modifying web page data and HTTP headers, controlling "
+"access, and removing ads and other obnoxious Internet junk."
+msgstr ""
+"Privoxy ist ein non-caching Web-Proxy mit erweiterten Filterfunktion zur "
+"Verbesserung der Privatsphäre. Er modifiziert Webseitendaten und HTTP-"
+"Header, kontrolliert den Zugang und das Entfernen von Anzeigen und anderem "
+"abscheulichen Internet Schrott."
+
+msgid "Read / Reread log file"
+msgstr "Protokolldatei (neu) lesen"
+
+msgid "Show I/O status"
+msgstr "Protokolliert den I/O Status"
+
+msgid "Show each connection status"
+msgstr "Protokolliert jeden Verbindungsstatus"
+
+msgid "Show header parsing"
+msgstr "Protokolliert das 'Header parsing'"
+
+msgid "Software update required"
+msgstr "Softwareaktualisierung nötig"
+
+msgid "Start"
+msgstr "Start"
+
+msgid "Start / Stop"
+msgstr "Start / Stopp"
+
+msgid "Start/Stop Privoxy WEB Proxy"
+msgstr "Start/Stopp Privoxy WEB Proxy"
+
+msgid "Startup banner and warnings."
+msgstr "Protokolliert Start-Meldungen und Warnungen"
+
+msgid "Syntax:"
+msgstr "Syntax:"
+
+msgid "Syntax: Client header names delimited by spaces."
+msgstr "Syntax: Client header Namen getrennt durch Leerzeichen."
+
+msgid "Syntax: target_pattern http_parent[:port]"
+msgstr "Syntax: target_pattern http_parent[:port]"
+
+msgid "Syntax: target_pattern socks_proxy[:port] http_parent[:port]"
+msgstr "Syntax: target_pattern socks_proxy[:port] http_parent[:port]"
+
+msgid ""
+"The actions file(s) to use. Multiple actionsfile lines are permitted, and "
+"are in fact recommended!"
+msgstr ""
+"Die zu verwendenden Aktion-Datei(en). Mehrere Dateien sind gestattet und "
+"empfohlen!"
+
+msgid ""
+"The address and TCP port on which Privoxy will listen for client requests."
+msgstr ""
+"Die Adresse und das TCP-Port, auf dem Privoxy auf Client-Anforderungen "
+"wartet."
+
+msgid ""
+"The compression level that is passed to the zlib library when compressing "
+"buffered content."
+msgstr ""
+"Die Komprimierungsstufe (0-9), die der zlib-Bibliothek beim Komprimieren "
+"gepufferten Inhaltes übergeben wird."
+
+msgid ""
+"The currently installed 'privoxy' package is not supported by LuCI "
+"application."
+msgstr ""
+"Das aktuell installierte 'privoxy' Paket wird von dieser LuCI Anwendung "
+"NICHT unterstützt."
+
+msgid ""
+"The directory where all logging takes place (i.e. where the logfile is "
+"located)."
+msgstr "Das Verzeichnis in dem die Protokolldatei gespeichert wird."
+
+msgid "The directory where the other configuration files are located."
+msgstr "Das Verzeichnis in dem weitere Konfigurationsdateien gespeichert sind."
+
+msgid ""
+"The filter files contain content modification rules that use regular "
+"expressions."
+msgstr ""
+"Die Filterdateien enthalten Änderung des Inhalts, die reguläre Ausdrücke "
+"als  Regeln verwenden."
+
+msgid "The hostname shown on the CGI pages."
+msgstr "Der Hostname der auf CGI-Seiten angezeigt wird."
+
+msgid "The log file to use. File name, relative to log directory."
+msgstr ""
+"Zu verwendende Protokolldatei. Dateiname relativ zum Protokoll-Verzeichnis."
+
+msgid "The order in which client headers are sorted before forwarding them."
+msgstr ""
+"Die Reihenfolge, in der Client-Header sortiert werden, bevor sie "
+"weitergeleitet werden."
+
+msgid ""
+"The status code Privoxy returns for pages blocked with +handle-as-empty-"
+"document."
+msgstr ""
+"Ob Statuscode 200(OK) oder 403(forbidden) für Seiten gemeldet wird, die "
+"durch den Filter 'handle-as-empty-document' blockiert werden."
+
+msgid ""
+"The trust mechanism is an experimental feature for building white-lists and "
+"should be used with care."
+msgstr ""
+"Der Trust-Mechanismus ist eine experimentelle Funktion für den Aufbau von "
+"White-Listen und sollte mit Vorsicht verwendet werden."
+
+msgid ""
+"The value of this option only matters if the experimental trust mechanism "
+"has been activated."
+msgstr ""
+"Der Wert dieser Option ist nur wirksam, wenn der experimentelle Trust-"
+"Mechanismus aktiviert wurde."
+
+msgid ""
+"This option is only there for debugging purposes. It will drastically reduce "
+"performance."
+msgstr ""
+"Diese Option ist ausschließlich zur Fehlersuche. Es wird drastisch die "
+"Leistung beeinträchtigt."
+
+msgid ""
+"This option will be removed in future releases as it has been obsoleted by "
+"the more general header taggers."
+msgstr "Diese Option wird in zukünftigen Versionen entfernt werden."
+
+msgid ""
+"This tab controls the security-relevant aspects of Privoxy's configuration."
+msgstr ""
+"Diese Registerkarte steuert die sicherheitsrelevanten Aspekte der Privoxy "
+"Konfiguration."
+
+msgid ""
+"Through which SOCKS proxy (and optionally to which parent HTTP proxy) "
+"specific requests should be routed."
+msgstr ""
+"An welchen SOCKS-Proxy (und gegebenenfalls an welchen übergeordneten HTTP-"
+"Proxy) spezifischen Anforderungen weitergeleitet werden."
+
+msgid "To which parent HTTP proxy specific requests should be routed."
+msgstr ""
+"An welchen übergeordneten HTTP-Proxy spezifischen Anforderungen "
+"weitergeleitet werden."
+
+msgid "User customizations"
+msgstr "Benutzerdefinierte Anpassungen"
+
+msgid "Value is not a number"
+msgstr "Eingabe ist keine Zahl"
+
+msgid "Value not between 0 and 9"
+msgstr "Wert nicht zwischen 0 und 9"
+
+msgid "Value not between 1 and 4096"
+msgstr "Wert nicht zwischen 1 und 4096"
+
+msgid "Value not greater 0 or empty"
+msgstr "Wert nicht größer 0 oder leer"
+
+msgid "Value range 1 to 4096, no entry defaults to 4096"
+msgstr "Wertebereich: 1 bis 4096; Keine Angabe setzt 4096."
+
+msgid "Version"
+msgstr "Version"
+
+msgid "Version Information"
+msgstr "Versionsinformation"
+
+msgid "Whether intercepted requests should be treated as valid."
+msgstr "Ob abgefangen Anfragen als gültig behandelt werden."
+
+msgid ""
+"Whether or not Privoxy recognizes special HTTP headers to change toggle "
+"state."
+msgstr ""
+"Ob Privoxy erkannte spezielle HTTP-Header zur Änderung des Toggle-Status "
+"verwendet.."
+
+msgid "Whether or not buffered content is compressed before delivery."
+msgstr ""
+"Ob gepufferte Inhalte vor der Weiterleitung komprimiert werden oder nicht."
+
+msgid ""
+"Whether or not outgoing connections that have been kept alive should be "
+"shared between different incoming connections."
+msgstr ""
+"Ob ausgehende Verbindungen, die am Leben gehalten werden, für verschiedenen "
+"eingehenden Verbindungen gemeinsam genutzt werden oder nicht."
+
+msgid "Whether or not pipelined requests should be served."
+msgstr "Ob Pipeline-Anfragen bedient werden oder nicht."
+
+msgid "Whether or not proxy authentication through Privoxy should work."
+msgstr ""
+"Ob Proxy-Authentifizierungen durch Privoxy weitergeleitet werden oder nicht."
+
+msgid "Whether or not the web-based actions file editor may be used."
+msgstr "De-/Aktiviert den webbasierte Action-Datei Editor."
+
+msgid "Whether or not the web-based toggle feature may be used."
+msgstr "De-Aktiviert die webbasierte Umschaltfunktion."
+
+msgid "Whether requests to Privoxy's CGI pages can be blocked or redirected."
+msgstr ""
+"Ob Anfragen an Privoxy CGI-Seiten gesperrt oder umgeleitet werden können "
+"oder nicht."
+
+msgid ""
+"Whether the CGI interface should stay compatible with broken HTTP clients."
+msgstr ""
+"Ob die CGI-Schnittstelle mit broken HTTP-Clients kompatibel bleibt oder "
+"nicht."
+
+msgid "Whether to run only one server thread."
+msgstr "Ob nur ein Server-Thread ausgeführt wird."
+
+msgid "Who can access what."
+msgstr "Wer kann auf Was zugreifen."
+
+msgid "installed"
+msgstr "installiert"
+
+msgid "or higher"
+msgstr "oder höher"
+
+msgid "required"
+msgstr "benötigt"
diff --git a/applications/luci-app-privoxy/po/templates/privoxy.pot b/applications/luci-app-privoxy/po/templates/privoxy.pot
new file mode 100644 (file)
index 0000000..8f836be
--- /dev/null
@@ -0,0 +1,405 @@
+msgid ""
+msgstr "Content-Type: text/plain; charset=UTF-8"
+
+msgid ""
+"A URL to be displayed in the error page that users will see if access to an "
+"untrusted page is denied."
+msgstr ""
+
+msgid ""
+"A URL to documentation about the local Privoxy setup, configuration or "
+"policies."
+msgstr ""
+
+msgid "Access Control"
+msgstr ""
+
+msgid "Actions that are applied to all sites and maybe overruled later on."
+msgstr ""
+
+msgid "An alternative directory where the templates are loaded from."
+msgstr ""
+
+msgid "An email address to reach the Privoxy administrator."
+msgstr ""
+
+msgid ""
+"Assumed server-side keep-alive timeout (in seconds) if not specified by the "
+"server."
+msgstr ""
+
+msgid "CGI user interface"
+msgstr ""
+
+msgid "Common Log Format"
+msgstr ""
+
+msgid ""
+"Configure here the routing of HTTP requests through a chain of multiple "
+"proxies. Note that parent proxies can severely decrease your privacy level. "
+"Also specified here are SOCKS proxies."
+msgstr ""
+
+msgid "Debug GIF de-animation"
+msgstr ""
+
+msgid "Debug force feature"
+msgstr ""
+
+msgid "Debug redirects"
+msgstr ""
+
+msgid "Debug regular expression filters"
+msgstr ""
+
+msgid "Directory does not exist!"
+msgstr ""
+
+msgid "Disabled == Transparent Proxy Mode"
+msgstr ""
+
+msgid "Enable proxy authentication forwarding"
+msgstr ""
+
+msgid ""
+"Enable/Disable autostart of Privoxy on system startup and interface events"
+msgstr ""
+
+msgid "Enable/Disable filtering when Privoxy starts."
+msgstr ""
+
+msgid "Enabled"
+msgstr ""
+
+msgid ""
+"Enabling this option is NOT recommended if there is no parent proxy that "
+"requires authentication!"
+msgstr ""
+
+msgid "File '%s' not found inside Configuration Directory"
+msgstr ""
+
+msgid "File not found or empty"
+msgstr ""
+
+msgid "Files and Directories"
+msgstr ""
+
+msgid "For help use link at the relevant option"
+msgstr ""
+
+msgid "Forwarding"
+msgstr ""
+
+msgid ""
+"If enabled, Privoxy hides the 'go there anyway' link. The user obviously "
+"should not be able to bypass any blocks."
+msgstr ""
+
+msgid ""
+"If you intend to operate Privoxy for more users than just yourself, it might "
+"be a good idea to let them know how to reach you, what you block and why you "
+"do that, your policies, etc."
+msgstr ""
+
+msgid "Invalid email address"
+msgstr ""
+
+msgid "It is NOT recommended for the casual user."
+msgstr ""
+
+msgid "Local Set-up"
+msgstr ""
+
+msgid "Location of the Privoxy User Manual."
+msgstr ""
+
+msgid "Log File Viewer"
+msgstr ""
+
+msgid "Log all data read from the network"
+msgstr ""
+
+msgid "Log all data written to the network"
+msgstr ""
+
+msgid "Log the applying actions"
+msgstr ""
+
+msgid ""
+"Log the destination for each request Privoxy let through. See also 'Debug "
+"1024'."
+msgstr ""
+
+msgid ""
+"Log the destination for requests Privoxy didn't let through, and the reason "
+"why."
+msgstr ""
+
+msgid "Logging"
+msgstr ""
+
+msgid "Main actions file"
+msgstr ""
+
+msgid "Mandatory Input: No Data given!"
+msgstr ""
+
+msgid "Mandatory Input: No Directory given!"
+msgstr ""
+
+msgid "Mandatory Input: No File given!"
+msgstr ""
+
+msgid "Mandatory Input: No Port given!"
+msgstr ""
+
+msgid "Mandatory Input: No files given!"
+msgstr ""
+
+msgid "Mandatory Input: No valid IPv4 address or host given!"
+msgstr ""
+
+msgid "Mandatory Input: No valid IPv6 address given!"
+msgstr ""
+
+msgid "Mandatory Input: No valid Port given!"
+msgstr ""
+
+msgid "Maximum number of client connections that will be served."
+msgstr ""
+
+msgid "Maximum size (in KB) of the buffer for content filtering."
+msgstr ""
+
+msgid "Miscellaneous"
+msgstr ""
+
+msgid "No trailing '/', please."
+msgstr ""
+
+msgid "Non-fatal errors - *we highly recommended enabling this*"
+msgstr ""
+
+msgid ""
+"Number of seconds after which a socket times out if no data is received."
+msgstr ""
+
+msgid ""
+"Number of seconds after which an open connection will no longer be reused."
+msgstr ""
+
+msgid "Please press [Read] button"
+msgstr ""
+
+msgid "Please read Privoxy manual for details!"
+msgstr ""
+
+msgid "Please update to the current version!"
+msgstr ""
+
+msgid "Privoxy WEB proxy"
+msgstr ""
+
+msgid ""
+"Privoxy can (and normally does) use a number of other files for additional "
+"configuration, help and logging. This section of the configuration file "
+"tells Privoxy where to find those other files."
+msgstr ""
+
+msgid ""
+"Privoxy is a non-caching web proxy with advanced filtering capabilities for "
+"enhancing privacy, modifying web page data and HTTP headers, controlling "
+"access, and removing ads and other obnoxious Internet junk."
+msgstr ""
+
+msgid "Read / Reread log file"
+msgstr ""
+
+msgid "Show I/O status"
+msgstr ""
+
+msgid "Show each connection status"
+msgstr ""
+
+msgid "Show header parsing"
+msgstr ""
+
+msgid "Software update required"
+msgstr ""
+
+msgid "Start"
+msgstr ""
+
+msgid "Start / Stop"
+msgstr ""
+
+msgid "Start/Stop Privoxy WEB Proxy"
+msgstr ""
+
+msgid "Startup banner and warnings."
+msgstr ""
+
+msgid "Syntax:"
+msgstr ""
+
+msgid "Syntax: Client header names delimited by spaces."
+msgstr ""
+
+msgid "Syntax: target_pattern http_parent[:port]"
+msgstr ""
+
+msgid "Syntax: target_pattern socks_proxy[:port] http_parent[:port]"
+msgstr ""
+
+msgid ""
+"The actions file(s) to use. Multiple actionsfile lines are permitted, and "
+"are in fact recommended!"
+msgstr ""
+
+msgid ""
+"The address and TCP port on which Privoxy will listen for client requests."
+msgstr ""
+
+msgid ""
+"The compression level that is passed to the zlib library when compressing "
+"buffered content."
+msgstr ""
+
+msgid ""
+"The currently installed 'privoxy' package is not supported by LuCI "
+"application."
+msgstr ""
+
+msgid ""
+"The directory where all logging takes place (i.e. where the logfile is "
+"located)."
+msgstr ""
+
+msgid "The directory where the other configuration files are located."
+msgstr ""
+
+msgid ""
+"The filter files contain content modification rules that use regular "
+"expressions."
+msgstr ""
+
+msgid "The hostname shown on the CGI pages."
+msgstr ""
+
+msgid "The log file to use. File name, relative to log directory."
+msgstr ""
+
+msgid "The order in which client headers are sorted before forwarding them."
+msgstr ""
+
+msgid ""
+"The status code Privoxy returns for pages blocked with +handle-as-empty-"
+"document."
+msgstr ""
+
+msgid ""
+"The trust mechanism is an experimental feature for building white-lists and "
+"should be used with care."
+msgstr ""
+
+msgid ""
+"The value of this option only matters if the experimental trust mechanism "
+"has been activated."
+msgstr ""
+
+msgid ""
+"This option is only there for debugging purposes. It will drastically reduce "
+"performance."
+msgstr ""
+
+msgid ""
+"This option will be removed in future releases as it has been obsoleted by "
+"the more general header taggers."
+msgstr ""
+
+msgid ""
+"This tab controls the security-relevant aspects of Privoxy's configuration."
+msgstr ""
+
+msgid ""
+"Through which SOCKS proxy (and optionally to which parent HTTP proxy) "
+"specific requests should be routed."
+msgstr ""
+
+msgid "To which parent HTTP proxy specific requests should be routed."
+msgstr ""
+
+msgid "User customizations"
+msgstr ""
+
+msgid "Value is not a number"
+msgstr ""
+
+msgid "Value not between 0 and 9"
+msgstr ""
+
+msgid "Value not between 1 and 4096"
+msgstr ""
+
+msgid "Value not greater 0 or empty"
+msgstr ""
+
+msgid "Value range 1 to 4096, no entry defaults to 4096"
+msgstr ""
+
+msgid "Version"
+msgstr ""
+
+msgid "Version Information"
+msgstr ""
+
+msgid "Whether intercepted requests should be treated as valid."
+msgstr ""
+
+msgid ""
+"Whether or not Privoxy recognizes special HTTP headers to change toggle "
+"state."
+msgstr ""
+
+msgid "Whether or not buffered content is compressed before delivery."
+msgstr ""
+
+msgid ""
+"Whether or not outgoing connections that have been kept alive should be "
+"shared between different incoming connections."
+msgstr ""
+
+msgid "Whether or not pipelined requests should be served."
+msgstr ""
+
+msgid "Whether or not proxy authentication through Privoxy should work."
+msgstr ""
+
+msgid "Whether or not the web-based actions file editor may be used."
+msgstr ""
+
+msgid "Whether or not the web-based toggle feature may be used."
+msgstr ""
+
+msgid "Whether requests to Privoxy's CGI pages can be blocked or redirected."
+msgstr ""
+
+msgid ""
+"Whether the CGI interface should stay compatible with broken HTTP clients."
+msgstr ""
+
+msgid "Whether to run only one server thread."
+msgstr ""
+
+msgid "Who can access what."
+msgstr ""
+
+msgid "installed"
+msgstr ""
+
+msgid "or higher"
+msgstr ""
+
+msgid "required"
+msgstr ""
diff --git a/applications/luci-app-privoxy/root/etc/uci-defaults/luci-privoxy b/applications/luci-app-privoxy/root/etc/uci-defaults/luci-privoxy
new file mode 100755 (executable)
index 0000000..3405479
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# no longer needed for "Save and Apply" to restart privoxy
+# luci-app-privoxy calls /etc/init.d/privoxy reload
+uci -q batch <<-EOF >/dev/null
+       delete ucitrack.@privoxy[-1]
+       commit ucitrack
+EOF
+
+rm -f /tmp/luci-indexcache
+
+exit 0