From 93b66993ce14d18aa0001fb27b2e8b21d18328e6 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Wed, 11 Mar 2009 23:40:08 +0000 Subject: [PATCH] applications/luci-asterisk: begin reworking dialplan stuff to separate dialzones from dialplans --- .../luci-asterisk/luasrc/asterisk.lua | 122 ++++++++++++++++ .../luasrc/controller/asterisk.lua | 1 + .../luasrc/model/cbi/asterisk/dialzones.lua | 135 ++++++++++++++++++ .../luasrc/view/asterisk/cbi/cell.htm | 22 +++ 4 files changed, 280 insertions(+) create mode 100644 applications/luci-asterisk/luasrc/model/cbi/asterisk/dialzones.lua create mode 100644 applications/luci-asterisk/luasrc/view/asterisk/cbi/cell.htm diff --git a/applications/luci-asterisk/luasrc/asterisk.lua b/applications/luci-asterisk/luasrc/asterisk.lua index c1b099dc5..908986366 100644 --- a/applications/luci-asterisk/luasrc/asterisk.lua +++ b/applications/luci-asterisk/luasrc/asterisk.lua @@ -17,6 +17,7 @@ $Id$ module("luci.asterisk", package.seeall) local _io = require("io") +local uci = require("luci.model.uci").cursor() local sys = require("luci.sys") local util = require("luci.util") @@ -196,3 +197,124 @@ function sip.peer(peer) return info, keys end + + +--- LuCI Asterisk - Internal helpers +-- @type module +tools = luci.util.class() + +--- Convert given value to a list of tokens. Split by white space. +-- @param val String or table value +-- @return Table containing tokens +function tools.parse_list(v) + local tokens = { } + + v = type(v) == "table" and v or { v } + for _, v in ipairs(v) do + if type(v) == "string" then + for v in v:gmatch("(%S+)") do + tokens[#tokens+1] = v + end + end + end + + return tokens +end + +--- Convert given list to a collection of hyperlinks +-- @param list Table of tokens +-- @param url String pattern or callback function to construct urls (optional) +-- @param sep String containing the seperator (optional, default is ", ") +-- @return String containing the html fragment +function tools.hyperlinks(list, url, sep) + local html + + local function mkurl(p, t) + if type(p) == "string" then + return p:format(t) + elseif type(p) == "function" then + return p(t) + else + return '#' + end + end + + list = list or { } + url = url or "%s" + sep = sep or ", " + + for _, token in ipairs(list) do + html = ( html and html .. sep or '' ) .. + '%s' %{ mkurl(url, token), token } + end + + return html or '' +end + + +--- LuCI Asterisk - Dialzone +-- @type module +dialzone = luci.util.class() + +--- Parse a dialzone section +-- @param zone Table containing the zone info +-- @return Table with parsed information +function dialzone.parse(z) + if z['.name'] then + return { + trunks = tools.parse_list(z.uses), + name = z['.name'], + description = z.description or z['.name'], + addprefix = z.addprefix, + matches = tools.parse_list(z.match), + intlmatches = tools.parse_list(z.international), + countrycode = z.countrycode, + localzone = z.localzone, + localprefix = z.localprefix + } + end +end + +--- Get a list of known dial zones +-- @return Associative table of zones and table of zone names +function dialzone.zones() + local zones = { } + local znames = { } + uci:foreach("asterisk", "dialzone", + function(z) + zones[z['.name']] = dialzone.parse(z) + znames[#znames+1] = z['.name'] + end) + return zones, znames +end + +--- Get a specific dial zone +-- @param name Name of the dial zone +-- @return Table containing zone information +function dialzone.zone(n) + local zone + uci:foreach("asterisk", "dialzone", + function(z) + if z['.name'] == n then + zone = dialzone.parse(z) + end + end) + return zone +end + +--- Find uci section hash for given zone number +-- @param idx Zone number +-- @return String containing the uci hash pointing to the section +function dialzone.ucisection(i) + local hash + local index = 1 + i = tonumber(i) + uci:foreach("asterisk", "dialzone", + function(z) + if not hash and index == i then + hash = z['.name'] + end + index = index + 1 + end) + return hash +end diff --git a/applications/luci-asterisk/luasrc/controller/asterisk.lua b/applications/luci-asterisk/luasrc/controller/asterisk.lua index 05d534317..04b4e42b3 100644 --- a/applications/luci-asterisk/luasrc/controller/asterisk.lua +++ b/applications/luci-asterisk/luasrc/controller/asterisk.lua @@ -52,6 +52,7 @@ function index() --entry({"admin", "asterisk", "dialplans"}, cbi("asterisk/dialplans"), "Call Routing", 3) entry({"admin", "asterisk", "dialplans"}, call("handle_dialplan"), "Call Routing", 3) entry({"admin", "asterisk", "dialplans", "out"}, cbi("asterisk/dialplan_out"), nil, 1).leaf = true + entry({"admin", "asterisk", "dialplans", "zones"}, cbi("asterisk/dialzones"), "Dial Zones", 2).leaf = true end diff --git a/applications/luci-asterisk/luasrc/model/cbi/asterisk/dialzones.lua b/applications/luci-asterisk/luasrc/model/cbi/asterisk/dialzones.lua new file mode 100644 index 000000000..4867911c5 --- /dev/null +++ b/applications/luci-asterisk/luasrc/model/cbi/asterisk/dialzones.lua @@ -0,0 +1,135 @@ +--[[ +LuCI - Lua Configuration Interface + +Copyright 2008 Jo-Philipp Wich + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +$Id: trunks.lua 4025 2009-01-11 23:37:21Z jow $ + +]]-- + +local ast = require("luci.asterisk") +local uci = require("luci.model.uci").cursor() + +--[[ + Dialzone overview table +]] + +if not arg[1] then + zonemap = Map("asterisk", "Dial Zones", [[ + Dial zones hold patterns of dialed numbers to match. + Each zone has one or more trunks assigned. If the first trunk is + congested, Asterisk will try to use the next available connection. + If all trunks fail, then the following zones in the parent dialplan + are tried. + ]]) + + local zones, znames = ast.dialzone.zones() + + zonetbl = zonemap:section(Table, zones, "Zone Overview") + zonetbl.sectionhead = "Zone" + zonetbl.addremove = true + zonetbl.anonymous = false + zonetbl.extedit = luci.dispatcher.build_url( + "admin", "asterisk", "dialplans", "zones", "%s" + ) + + function zonetbl.cfgsections(self) + return znames + end + + function zonetbl.parse(self) + for k, v in pairs(self.map:formvaluetable( + luci.cbi.REMOVE_PREFIX .. self.config + ) or {}) do + if k:sub(-2) == ".x" then k = k:sub(1, #k - 2) end + uci:delete("asterisk", k) + uci:save("asterisk") + self.data[k] = nil + for i = 1,#znames do + if znames[i] == k then + table.remove(znames, i) + break + end + end + end + + Table.parse(self) + end + + zonetbl:option(DummyValue, "description", "Description") + zonetbl:option(DummyValue, "addprefix") + + match = zonetbl:option(DummyValue, "matches") + function match.cfgvalue(self, s) + return table.concat(zones[s].matches, ", ") + end + + trunks = zonetbl:option(DummyValue, "trunk") + trunks.template = "asterisk/cbi/cell" + function trunks.cfgvalue(self, s) + return ast.tools.hyperlinks(zones[s].trunks) + end + + return zonemap + +--[[ + Zone edit form +]] + +else + zoneedit = Map("asterisk", "Edit Dialzone") + + entry = zoneedit:section(NamedSection, arg[1]) + entry.title = "Zone %q" % arg[1]; + + back = entry:option(DummyValue, "_overview", "Back to dialzone overview") + back.value = "" + back.titleref = luci.dispatcher.build_url( + "admin", "asterisk", "dialplans", "zones" + ) + + desc = entry:option(Value, "description", "Description") + function desc.cfgvalue(self, s, ...) + return Value.cfgvalue(self, s, ...) or s + end + + trunks = entry:option(MultiValue, "uses", "Used trunks") + trunks.widget = "checkbox" + uci:foreach("asterisk", "sip", + function(s) + if s.provider == "yes" then + trunks:value( + "SIP/%s" % s['.name'], + "SIP/%s (%s)" %{ s['.name'], s.host or 'n/a' } + ) + end + end) + + + match = entry:option(DynamicList, "match", "Number matches") + + intl = entry:option(DynamicList, "international", "Intl. prefix matches (optional)") + + aprefix = entry:option(Value, "addprefix", "Add prefix to dial out (optional)") + ccode = entry:option(Value, "countrycode", "Effective countrycode (optional)") + + lzone = entry:option(ListValue, "localzone", "Dialzone for local numbers") + lzone:value("", "no special treatment of local numbers") + for _, z in ipairs(ast.dialzone.zones()) do + lzone:value(z.name, "%q (%s)" %{ z.name, z.description }) + end + --for _, v in ipairs(find_outgoing_contexts(zoneedit.uci)) do + -- lzone:value(unpack(v)) + --end + + lprefix = entry:option(Value, "localprefix", "Prefix for local calls (optional)") + + return zoneedit + +end diff --git a/applications/luci-asterisk/luasrc/view/asterisk/cbi/cell.htm b/applications/luci-asterisk/luasrc/view/asterisk/cbi/cell.htm new file mode 100644 index 000000000..b5d618ff9 --- /dev/null +++ b/applications/luci-asterisk/luasrc/view/asterisk/cbi/cell.htm @@ -0,0 +1,22 @@ +<%# +LuCI - Lua Configuration Interface +Copyright 2008 Steven Barth +Copyright 2008 Jo-Philipp Wich + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +$Id: dvalue.htm 3367 2008-09-19 10:42:02Z Cyrus $ + +-%> + +<%+cbi/valueheader%> +<% if self.href then %><% end -%> + <%=self:cfgvalue(section)%> +<%- if self.href then %><%end%> +  + +<%+cbi/valuefooter%> -- 2.25.1