1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
|
------------------------------------------------------------
-- Dynamic proxy settings --
-- Copyright © Piotr Husiatyński <phusiatynski@gmail.com> --
------------------------------------------------------------
-- Grab environment we need
local io = io
local os = os
local pairs = pairs
local ipairs = ipairs
local error = error
local string = string
local lousy = require "lousy"
local theme = theme
local unpack = unpack
local table = table
local capi = { luakit = luakit, soup = soup }
local webview = webview
local widget = widget
local window = window
-- Check for mode/bind functions
local add_binds, add_cmds = add_binds, add_cmds
local new_mode, menu_binds = new_mode, menu_binds
module("proxy")
--- Module global variables
local proxies_file = capi.luakit.data_dir .. '/proxymenu'
local proxies = {}
local noproxy = { address = '' }
local active = noproxy
-- Return ordered list of proxy names
function get_names()
return lousy.util.table.keys(proxies)
end
-- Return address of proxy given by name
function get(name)
return proxies[name]
end
--- Get active proxy configuration: { name = "name", address = "address" }
function get_active()
return active
end
--- Load proxies list from file
-- @param fd_name custom proxy storage of nil to use default
function load(fd_name)
local fd_name = fd_name or proxies_file
if not os.exists(fd_name) then return end
local strip = lousy.util.string.strip
for line in io.lines(fd_name) do
local status, name, address = string.match(line, "^(.)%s(.+)%s(.+)$")
if address then
name, address = strip(name), strip(address)
if status == '*' then
active = { address = address, name = name }
end
proxies[name] = address
end
end
end
--- Save proxies list to file
-- @param fd_name custom proxy storage of nil to use default
function save(fd_name)
local fd = io.open(fd_name or proxies_file, "w")
for name, address in pairs(proxies) do
if address ~= "" then
local status = (active.name == name and '*') or ' '
fd:write(string.format("%s %s %s\n", status, name, address))
end
end
io.close(fd)
end
--- Add new proxy server to current list
-- @param name proxy configuration name
-- @param address proxy server address
-- @param save_file do not save configuration if false
function set(name, address, save_file)
local name = lousy.util.string.strip(name)
if not string.match(name, "^([%w%p]+)$") then
error("Invalid proxy name: " .. name)
end
proxies[name] = lousy.util.string.strip(address)
if save_file ~= false then save() end
end
--- Delete selected proxy from list
-- @param name proxy server name
function del(name)
local name = lousy.util.string.strip(name)
if proxies[name] then
-- if deleted proxy was the active one, turn proxy off
if name == active.name then
active = noproxy
end
proxies[name] = nil
save()
end
end
--- Set given proxy to active. Return true on success, else false
-- @param name proxy configuration name or nil to unset proxy.
function set_active(name)
if name then
local name = lousy.util.string.strip(name)
if not proxies[name] then
error("Unknown proxy: " .. name)
end
active = { name = name, address = proxies[name] }
else
active = noproxy
end
save()
return true
end
-- Load the initial proxy address
webview.init_funcs.set_proxy = function (view, w)
local active = get_active()
if active and active.address ~= '' then
capi.soup.proxy_uri = active.address
end
-- The proxy property is set globablly so this function only needs to be
-- called once. Other proxy changes take place from the interactive
-- `:proxy` menu.
webview.init_funcs.set_proxy = nil
end
-- Create a proxy indicator widget and add it to the status bar
window.init_funcs.build_proxy_indicator = function (w)
local r = w.sbar.r
r.proxyi = widget{type="label"}
r.layout:pack(r.proxyi)
r.layout:reorder(r.proxyi, 2)
r.proxyi.fg = theme.proxyi_sbar_fg
r.proxyi.font = theme.proxyi_sbar_font
w:update_proxy_indicator()
end
-- Helper function to update text in proxy indicator
window.methods.update_proxy_indicator = function (w)
local name = get_active().name
local proxyi = w.sbar.r.proxyi
if name then
local text = string.format("[%s]", name)
if proxyi.text ~= text then proxyi.text = text end
proxyi:show()
else
proxyi:hide()
end
end
-- Update proxy indicator in status bar on change of address
webview.init_funcs.proxy_indicator_update = function (view, w)
view:add_signal("property::proxy-uri", function (v)
w:update_proxy_indicator()
end)
end
new_mode("proxymenu", {
enter = function (w)
local afg, ifg = theme.proxy_active_menu_fg, theme.proxy_inactive_menu_fg
local abg, ibg = theme.proxy_active_menu_bg, theme.proxy_inactive_menu_bg
local a = get_active()
local rows = {{ "Proxy Name", " Server address", title = true },
{" None", "", address = '',
fg = (a.address == '' and afg) or ifg,
bg = (a.address == '' and abg) or ibg},}
for _, name in ipairs(get_names()) do
local address = get(name)
table.insert(rows, {
" " .. name, " " .. address,
name = name, address = lousy.util.escape(address),
fg = (a.name == name and afg) or ifg,
bg = (a.name == name and abg) or ibg,
})
end
w.menu:build(rows)
w:notify("Use j/k to move, d delete, e edit, a add, Return activate.", false)
end,
leave = function (w)
w.menu:hide()
end,
})
local cmd = lousy.bind.cmd
add_cmds({
cmd("proxy", "add proxy server",
function (w, a)
local params = lousy.util.string.split(a or '')
if not a then
w:set_mode("proxymenu")
elseif #params == 2 then
local name, address = unpack(params)
set(name, address)
else
w:error("Bad usage. Correct format :proxy <name> <address>")
end
end),
})
local key = lousy.bind.key
add_binds("proxymenu", lousy.util.table.join({
-- Select proxy
key({}, "Return",
function (w)
local row = w.menu:get()
if row and row.address then
set_active(row.name)
w:set_mode()
capi.soup.proxy_uri = row.address
if row.name then
w:notify(string.format("Using proxy: %s (%s)", row.name, row.address))
else
w:notify("Unset proxy.")
end
end
end),
-- Delete proxy
key({}, "d",
function (w)
local row = w.menu:get()
if row and row.name then
del(row.name)
w.menu:del()
end
end),
-- Edit proxy
key({}, "e",
function (w)
local row = w.menu:get()
if row and row.name then
w:enter_cmd(string.format(":proxy %s %s", row.name, row.address))
end
end),
-- New proxy
key({}, "a", function (w) w:enter_cmd(":proxy ") end),
-- Exit menu
key({}, "q", function (w) w:set_mode() end),
}, menu_binds))
-- Initialize module
load()
-- vim: et:sw=4:ts=8:sts=4:tw=80
|