applications/luci-asterisk: begin reworking dialplan stuff to separate dialzones...
authorJo-Philipp Wich <jow@openwrt.org>
Wed, 11 Mar 2009 23:40:08 +0000 (23:40 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Wed, 11 Mar 2009 23:40:08 +0000 (23:40 +0000)
applications/luci-asterisk/luasrc/asterisk.lua
applications/luci-asterisk/luasrc/controller/asterisk.lua
applications/luci-asterisk/luasrc/model/cbi/asterisk/dialzones.lua [new file with mode: 0644]
applications/luci-asterisk/luasrc/view/asterisk/cbi/cell.htm [new file with mode: 0644]

index c1b099dc5a7f13918f88eb8324b3668d172709b1..90898636632909d65848cec2a3395fc83d6e4c7f 100644 (file)
@@ -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 '' ) ..
+                       '<a href="%s">%s</a>' %{ 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
index 05d534317d19cf55c350eaa21f7517e37af0b28b..04b4e42b375ea202ef87ae6e783d1a53589880e9 100644 (file)
@@ -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 (file)
index 0000000..4867911
--- /dev/null
@@ -0,0 +1,135 @@
+--[[
+LuCI - Lua Configuration Interface
+
+Copyright 2008 Jo-Philipp Wich <xm@subsignal.org>
+
+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 (file)
index 0000000..b5d618f
--- /dev/null
@@ -0,0 +1,22 @@
+<%#
+LuCI - Lua Configuration Interface
+Copyright 2008 Steven Barth <steven@midlink.org>
+Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
+
+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 %><a href="<%=self.href%>"><% end -%>
+       <%=self:cfgvalue(section)%>
+<%- if self.href then %></a><%end%>
+&#160;
+<input type="hidden" id="<%=cbid%>" value="<%=luci.util.pcdata(self:cfgvalue(section))%>" />
+<%+cbi/valuefooter%>