applications/luci-asterisk: initial dialplan voicemail box support
This commit is contained in:
parent
dd267f9457
commit
2c7a761054
5 changed files with 266 additions and 11 deletions
|
@ -310,6 +310,46 @@ function idd.idd(c)
|
|||
end
|
||||
end
|
||||
|
||||
--- Populate given CBI field with IDD codes.
|
||||
-- @param field CBI option object
|
||||
-- @return (nothing)
|
||||
function idd.cbifill(o)
|
||||
for i, v in ipairs(cc_idd.CC_IDD) do
|
||||
o:value("_%i" % i, util.pcdata(v[1]))
|
||||
end
|
||||
|
||||
o.formvalue = function(...)
|
||||
local val = luci.cbi.Value.formvalue(...)
|
||||
if val:sub(1,1) == "_" then
|
||||
val = tonumber((val:gsub("^_", "")))
|
||||
if val then
|
||||
return type(cc_idd.CC_IDD[val][3]) == "table"
|
||||
and cc_idd.CC_IDD[val][3] or { cc_idd.CC_IDD[val][3] }
|
||||
end
|
||||
end
|
||||
return val
|
||||
end
|
||||
|
||||
o.cfgvalue = function(...)
|
||||
local val = luci.cbi.Value.cfgvalue(...)
|
||||
if val then
|
||||
val = tools.parse_list(val)
|
||||
for i, v in ipairs(cc_idd.CC_IDD) do
|
||||
if type(v[3]) == "table" then
|
||||
if v[3][1] == val[1] then
|
||||
return "_%i" % i
|
||||
end
|
||||
else
|
||||
if v[3] == val[1] then
|
||||
return "_%i" % i
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return val
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- LuCI Asterisk - Country Code Prefixes
|
||||
-- @type module
|
||||
|
@ -363,6 +403,46 @@ function cc.cc(c)
|
|||
end
|
||||
end
|
||||
|
||||
--- Populate given CBI field with CC codes.
|
||||
-- @param field CBI option object
|
||||
-- @return (nothing)
|
||||
function cc.cbifill(o)
|
||||
for i, v in ipairs(cc_idd.CC_IDD) do
|
||||
o:value("_%i" % i, util.pcdata(v[1]))
|
||||
end
|
||||
|
||||
o.formvalue = function(...)
|
||||
local val = luci.cbi.Value.formvalue(...)
|
||||
if val:sub(1,1) == "_" then
|
||||
val = tonumber((val:gsub("^_", "")))
|
||||
if val then
|
||||
return type(cc_idd.CC_IDD[val][2]) == "table"
|
||||
and cc_idd.CC_IDD[val][2] or { cc_idd.CC_IDD[val][2] }
|
||||
end
|
||||
end
|
||||
return val
|
||||
end
|
||||
|
||||
o.cfgvalue = function(...)
|
||||
local val = luci.cbi.Value.cfgvalue(...)
|
||||
if val then
|
||||
val = tools.parse_list(val)
|
||||
for i, v in ipairs(cc_idd.CC_IDD) do
|
||||
if type(v[2]) == "table" then
|
||||
if v[2][1] == val[1] then
|
||||
return "_%i" % i
|
||||
end
|
||||
else
|
||||
if v[2] == val[1] then
|
||||
return "_%i" % i
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return val
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- LuCI Asterisk - Dialzone
|
||||
-- @type module
|
||||
|
@ -432,6 +512,101 @@ function dialzone.ucisection(i)
|
|||
end
|
||||
|
||||
|
||||
--- LuCI Asterisk - Voicemailbox
|
||||
-- @type module
|
||||
voicemail = luci.util.class()
|
||||
|
||||
--- Parse a voicemail section
|
||||
-- @param zone Table containing the mailbox info
|
||||
-- @return Table with parsed information
|
||||
function voicemail.parse(z)
|
||||
if z.number and #z.number > 0 then
|
||||
local v = {
|
||||
id = '%s@%s' %{ z.number, z.context or 'default' },
|
||||
number = z.number,
|
||||
context = z.context or 'default',
|
||||
name = z.name or z['.name'] or 'OpenWrt',
|
||||
zone = z.zone or 'homeloc',
|
||||
password = z.password or '0000',
|
||||
email = z.email or '',
|
||||
page = z.page or '',
|
||||
dialplans = { }
|
||||
}
|
||||
|
||||
uci:foreach("asterisk", "dialplanvoice",
|
||||
function(s)
|
||||
if s.dialplan and #s.dialplan > 0 and
|
||||
s.voicebox == v.number
|
||||
then
|
||||
v.dialplans[#v.dialplans+1] = s.dialplan
|
||||
end
|
||||
end)
|
||||
|
||||
return v
|
||||
end
|
||||
end
|
||||
|
||||
--- Get a list of known voicemail boxes
|
||||
-- @return Associative table of boxes and table of box numbers
|
||||
function voicemail.boxes()
|
||||
local vboxes = { }
|
||||
local vnames = { }
|
||||
uci:foreach("asterisk", "voicemail",
|
||||
function(z)
|
||||
local v = voicemail.parse(z)
|
||||
if v then
|
||||
local n = '%s@%s' %{ v.number, v.context }
|
||||
vboxes[n] = v
|
||||
vnames[#vnames+1] = n
|
||||
end
|
||||
end)
|
||||
return vboxes, vnames
|
||||
end
|
||||
|
||||
--- Get a specific voicemailbox
|
||||
-- @param number Number of the voicemailbox
|
||||
-- @return Table containing mailbox information
|
||||
function voicemail.box(n)
|
||||
local box
|
||||
n = n:gsub("@.+$","")
|
||||
uci:foreach("asterisk", "voicemail",
|
||||
function(z)
|
||||
if z.number == tostring(n) then
|
||||
box = voicemail.parse(z)
|
||||
end
|
||||
end)
|
||||
return box
|
||||
end
|
||||
|
||||
--- Find all voicemailboxes within the given dialplan
|
||||
-- @param plan Dialplan name or table
|
||||
-- @return Associative table containing extensions mapped to mailbox info
|
||||
function voicemail.in_dialplan(p)
|
||||
local plan = type(p) == "string" and p or p.name
|
||||
local boxes = { }
|
||||
uci:foreach("asterisk", "dialplanvoice",
|
||||
function(s)
|
||||
if s.extension and #s.extension > 0 and s.dialplan == plan then
|
||||
local box = voicemail.box(s.voicebox)
|
||||
if box then
|
||||
boxes[s.extension] = box
|
||||
end
|
||||
end
|
||||
end)
|
||||
return boxes
|
||||
end
|
||||
|
||||
--- Remove voicemailbox and associated extensions from config
|
||||
-- @param box Voicemailbox number or table
|
||||
-- @return Boolean indicating success
|
||||
function voicemail.remove(v)
|
||||
local box = type(v) == "string" and v or v.number
|
||||
local ok1 = uci:delete_all("asterisk", "voicemail", {number=box})
|
||||
local ok2 = uci:delete_all("asterisk", "dialplanvoice", {voicebox=box})
|
||||
return ( ok1 or ok2 ) and true or false
|
||||
end
|
||||
|
||||
|
||||
--- LuCI Asterisk - Dialplan
|
||||
-- @type module
|
||||
dialplan = luci.util.class()
|
||||
|
@ -447,6 +622,7 @@ function dialplan.parse(z)
|
|||
description = z.description or z['.name']
|
||||
}
|
||||
|
||||
-- dialzones
|
||||
for _, name in ipairs(tools.parse_list(z.include)) do
|
||||
local zone = dialzone.zone(name)
|
||||
if zone then
|
||||
|
@ -454,6 +630,9 @@ function dialplan.parse(z)
|
|||
end
|
||||
end
|
||||
|
||||
-- voicemailboxes
|
||||
plan.voicemailboxes = voicemail.in_dialplan(plan)
|
||||
|
||||
return plan
|
||||
end
|
||||
end
|
||||
|
|
|
@ -103,6 +103,31 @@ function handle_dialplan()
|
|||
end
|
||||
end
|
||||
|
||||
for k, v in pairs(luci.http.formvaluetable("delvbox")) do
|
||||
local plan = ast.dialplan.plan(k)
|
||||
if #v > 0 and plan then
|
||||
uci:delete_all("asterisk", "dialplanvoice",
|
||||
{ extension=v, dialplan=plan.name })
|
||||
uci:save("asterisk")
|
||||
end
|
||||
end
|
||||
|
||||
for k, v in pairs(luci.http.formvaluetable("addvbox")) do
|
||||
local plan = ast.dialplan.plan(k)
|
||||
local vbox = ast.voicemail.box(v)
|
||||
if plan and vbox then
|
||||
local vext = luci.http.formvalue("addvboxext.%s" % plan.name)
|
||||
vext = ( vext and #vext > 0 ) and vext or vbox.number
|
||||
uci:section("asterisk", "dialplanvoice", nil, {
|
||||
dialplan = plan.name,
|
||||
extension = vext,
|
||||
voicebox = vbox.number,
|
||||
voicecontext = vbox.context
|
||||
})
|
||||
uci:save("asterisk")
|
||||
end
|
||||
end
|
||||
|
||||
local aname = luci.http.formvalue("addplan")
|
||||
if aname and #aname > 0 then
|
||||
if aname:match("^[a-zA-Z0-9_]+$") then
|
||||
|
|
|
@ -120,7 +120,10 @@ if arg[1] then
|
|||
end
|
||||
|
||||
aprefix = entry:option(Value, "addprefix", "Add prefix to dial out (optional)")
|
||||
--ast.idd.cbifill(aprefix)
|
||||
|
||||
ccode = entry:option(Value, "countrycode", "Effective countrycode (optional)")
|
||||
ast.cc.cbifill(ccode)
|
||||
|
||||
lzone = entry:option(ListValue, "localzone", "Dialzone for local numbers")
|
||||
lzone:value("", "no special treatment of local numbers")
|
||||
|
|
|
@ -33,6 +33,10 @@ $Id$
|
|||
function format_matches(z)
|
||||
local html = { }
|
||||
|
||||
if type(z) ~= "table" then
|
||||
z = { matches = { z } }
|
||||
end
|
||||
|
||||
if z.localprefix then
|
||||
for _, m in ipairs(z.matches) do
|
||||
html[#html+1] =
|
||||
|
@ -41,7 +45,7 @@ $Id$
|
|||
end
|
||||
end
|
||||
|
||||
if #z.intlmatches > 0 then
|
||||
if z.intlmatches and #z.intlmatches > 0 then
|
||||
for _, i in ipairs(z.intlmatches) do
|
||||
for _, m in ipairs(z.matches) do
|
||||
html[#html+1] = "%s %s" %{
|
||||
|
@ -71,7 +75,10 @@ $Id$
|
|||
<div class="cbi-map" id="cbi-asterisk">
|
||||
<h2><a id="content" name="content">Outgoing Call Routing</a></h2>
|
||||
<div class="cbi-map-descr">
|
||||
Here you can manage your dial plans which are used to route outgoing calls from your local extensions.
|
||||
Here you can manage your dial plans which are used to route outgoing calls from your local extensions.<br /><br />
|
||||
Related tasks:<br />
|
||||
<a href="<%=luci.dispatcher.build_url('admin/asterisk/dialplans/zones')%>" class="cbi-title-ref">Manage dialzones</a> |
|
||||
<a href="<%=luci.dispatcher.build_url('admin/asterisk/dialplans/zones')%>" class="cbi-title-ref">Manage voicemailboxes</a>
|
||||
</div>
|
||||
<!-- tblsection -->
|
||||
<fieldset class="cbi-section" id="cbi-asterisk-sip">
|
||||
|
@ -93,9 +100,9 @@ $Id$
|
|||
</tr>
|
||||
|
||||
<!-- dialzones -->
|
||||
<% local zones_used = { } %>
|
||||
<% local zones_used = { }; local row = 0 %>
|
||||
<% for i, zone in ipairs(plan.zones) do zones_used[zone.name] = true %>
|
||||
<tr class="cbi-section-table-row <%=rowstyle(i)%>">
|
||||
<tr class="cbi-section-table-row <%=rowstyle(row)%>">
|
||||
<td style="text-align: left; padding: 3px" class="cbi-section-table-cell">
|
||||
<strong>└ Dialzone <em><%=zone.name%></em></strong> (<%=zone.description%>)
|
||||
<p style="padding-left: 1em; margin-bottom:0">
|
||||
|
@ -118,25 +125,65 @@ $Id$
|
|||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% row = row + 1; end %>
|
||||
<!-- /dialzones -->
|
||||
|
||||
<!-- voicemail -->
|
||||
<% local boxes_used = { } %>
|
||||
<% for ext, box in luci.util.kspairs(plan.voicemailboxes) do boxes_used[box.id] = true %>
|
||||
<tr class="cbi-section-table-row <%=rowstyle(row)%>">
|
||||
<td style="text-align: left; padding: 3px" class="cbi-section-table-cell">
|
||||
<strong>└ Voicemailbox <em><%=box.id%></em></strong> (<%=box.name%>)
|
||||
<p style="padding-left: 1em; margin-bottom:0">
|
||||
Owner: <%=box.name%> |
|
||||
eMail: <%=#box.email > 0 and box.email or 'n/a'%> |
|
||||
Pager: <%=#box.page > 0 and box.page or 'n/a'%><br />
|
||||
Matches: <%=format_matches(ext)%>
|
||||
</p>
|
||||
</td>
|
||||
<td style="width:5%" class="cbi-value-field">
|
||||
<a href="<%=luci.dispatcher.build_url('admin', 'asterisk', 'dialplans', 'out', box.name)%>">
|
||||
<img style="border:none" alt="Edit dialzone" title="Edit dialzone" src="/luci-static/resources/cbi/edit.gif" />
|
||||
</a>
|
||||
<a href="<%=luci.dispatcher.build_url('admin', 'asterisk', 'dialplans')%>?delvbox.<%=plan.name%>=<%=ext%>">
|
||||
<img style="border:none" alt="Remove from this dialplan" title="Remove from this dialplan" src="/luci-static/resources/cbi/remove.gif" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<% row = row + 1; end %>
|
||||
<!-- /voicemail -->
|
||||
|
||||
<tr class="cbi-section-table-row">
|
||||
<td style="text-align: left; padding: 3px" class="cbi-section-table-cell" colspan="2">
|
||||
<hr style="margin-bottom:0.5em; border-width:0 0 1px 0" />
|
||||
|
||||
Add Dialzone:<br />
|
||||
<select style="width:30%" name="addzone.<%=plan.name%>">
|
||||
<option value="">-- Add dialzone --</option>
|
||||
<option value="">-- please select --</option>
|
||||
<% for _, zone in pairs(ast.dialzone.zones()) do %>
|
||||
<% if not zones_used[zone.name] then %>
|
||||
<option value="<%=zone.name%>"><%=zone.name%> (<%=zone.description%>)</option>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</select>
|
||||
<input type="submit" class="cbi-button cbi-button-add" value=" » " title="Add Zone ..."/>
|
||||
|
||||
<a href="<%=luci.dispatcher.build_url('admin/asterisk/dialplans/zones')%>" class="cbi-title-ref">Manage dialzones</a>
|
||||
<br /><br />
|
||||
|
||||
Add Voicemailbox:<br />
|
||||
<select style="width:20%" name="addvbox.<%=plan.name%>" onchange="this.form['addvboxext.<%=plan.name%>'].value=this.options[this.selectedIndex].value.split('@')[0]">
|
||||
<option value="">-- please select --</option>
|
||||
<% for ext, box in pairs(ast.voicemail.boxes()) do %>
|
||||
<% if not boxes_used[box.id] then %>
|
||||
<option value="<%=box.id%>"><%=box.id%> (<%=box.name%>)</option>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</select>
|
||||
as extension
|
||||
<input type="text" style="width:5%" name="addvboxext.<%=plan.name%>" />
|
||||
<br /><br />
|
||||
|
||||
<input type="submit" class="cbi-button cbi-button-add" value="Add item »" title="Add item ..."/>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- /dialzones -->
|
||||
|
||||
</table>
|
||||
|
||||
|
|
|
@ -128,7 +128,8 @@ config 'iax' 'sam'
|
|||
config 'voicegeneral'
|
||||
option 'serveremail' 'voice@sip.mydomain.net'
|
||||
|
||||
config 'voicemail' '1001'
|
||||
config 'voicemail'
|
||||
option 'number' '1001'
|
||||
option 'context' 'default'
|
||||
option 'password' '0000'
|
||||
option 'name' 'Family'
|
||||
|
|
Loading…
Reference in a new issue