[asterisk-commits] dlee: branch dlee/ASTERISK-22296 r397678 - in /team/dlee/ASTERISK-22296: ./ b...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Aug 26 16:58:59 CDT 2013
Author: dlee
Date: Mon Aug 26 16:58:57 2013
New Revision: 397678
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=397678
Log:
Merged revisions 397565-397674 from http://svn.asterisk.org/svn/asterisk/trunk
Added:
team/dlee/ASTERISK-22296/include/asterisk/bucket.h
- copied unchanged from r397674, trunk/include/asterisk/bucket.h
team/dlee/ASTERISK-22296/main/bucket.c
- copied unchanged from r397674, trunk/main/bucket.c
team/dlee/ASTERISK-22296/tests/test_bucket.c
- copied unchanged from r397674, trunk/tests/test_bucket.c
Modified:
team/dlee/ASTERISK-22296/ (props changed)
team/dlee/ASTERISK-22296/bridges/bridge_builtin_interval_features.c
team/dlee/ASTERISK-22296/bridges/bridge_native_rtp.c
team/dlee/ASTERISK-22296/build_tools/menuselect-deps.in
team/dlee/ASTERISK-22296/channels/Makefile
team/dlee/ASTERISK-22296/channels/sig_pri.c
team/dlee/ASTERISK-22296/configure
team/dlee/ASTERISK-22296/configure.ac
team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/astconfigparser.py
team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/astdicts.py
team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/sip_to_res_sip.py
team/dlee/ASTERISK-22296/include/asterisk/astmm.h
team/dlee/ASTERISK-22296/include/asterisk/autoconfig.h.in
team/dlee/ASTERISK-22296/include/asterisk/backtrace.h
team/dlee/ASTERISK-22296/include/asterisk/bridge_channel.h
team/dlee/ASTERISK-22296/include/asterisk/bridge_channel_internal.h
team/dlee/ASTERISK-22296/include/asterisk/channel.h
team/dlee/ASTERISK-22296/include/asterisk/config_options.h
team/dlee/ASTERISK-22296/include/asterisk/lock.h
team/dlee/ASTERISK-22296/include/asterisk/sorcery.h
team/dlee/ASTERISK-22296/include/asterisk/stasis_app.h
team/dlee/ASTERISK-22296/include/asterisk/stasis_app_impl.h
team/dlee/ASTERISK-22296/include/asterisk/utils.h
team/dlee/ASTERISK-22296/main/Makefile
team/dlee/ASTERISK-22296/main/asterisk.c
team/dlee/ASTERISK-22296/main/astmm.c
team/dlee/ASTERISK-22296/main/astobj2.c
team/dlee/ASTERISK-22296/main/backtrace.c
team/dlee/ASTERISK-22296/main/bridge.c
team/dlee/ASTERISK-22296/main/bridge_channel.c
team/dlee/ASTERISK-22296/main/channel.c
team/dlee/ASTERISK-22296/main/channel_internal_api.c
team/dlee/ASTERISK-22296/main/config_options.c
team/dlee/ASTERISK-22296/main/lock.c
team/dlee/ASTERISK-22296/main/logger.c
team/dlee/ASTERISK-22296/main/pbx.c
team/dlee/ASTERISK-22296/main/sorcery.c
team/dlee/ASTERISK-22296/main/stasis_channels.c
team/dlee/ASTERISK-22296/main/utils.c
team/dlee/ASTERISK-22296/makeopts.in
team/dlee/ASTERISK-22296/res/ari/resource_bridges.c
team/dlee/ASTERISK-22296/res/res_ari_bridges.c
team/dlee/ASTERISK-22296/res/res_musiconhold.c
team/dlee/ASTERISK-22296/res/res_pjsip.c
team/dlee/ASTERISK-22296/res/res_pjsip/pjsip_configuration.c
team/dlee/ASTERISK-22296/res/stasis/control.c
team/dlee/ASTERISK-22296/rest-api/api-docs/bridges.json
team/dlee/ASTERISK-22296/tests/test_config.c
team/dlee/ASTERISK-22296/tests/test_sorcery.c
team/dlee/ASTERISK-22296/tests/test_sorcery_astdb.c
team/dlee/ASTERISK-22296/tests/test_sorcery_realtime.c
Propchange: team/dlee/ASTERISK-22296/
('branch-11-blocked' removed)
Propchange: team/dlee/ASTERISK-22296/
('branch-11-merged' removed)
Propchange: team/dlee/ASTERISK-22296/
------------------------------------------------------------------------------
branch-12-merged = /branches/12:1-397673
Propchange: team/dlee/ASTERISK-22296/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Mon Aug 26 16:58:57 2013
@@ -1,1 +1,1 @@
-/trunk:1-397563
+/trunk:1-397677
Modified: team/dlee/ASTERISK-22296/bridges/bridge_builtin_interval_features.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/bridges/bridge_builtin_interval_features.c?view=diff&rev=397678&r1=397677&r2=397678
==============================================================================
--- team/dlee/ASTERISK-22296/bridges/bridge_builtin_interval_features.c (original)
+++ team/dlee/ASTERISK-22296/bridges/bridge_builtin_interval_features.c Mon Aug 26 16:58:57 2013
@@ -103,12 +103,14 @@
/*
* It may be necessary to resume music on hold after we finish
* playing the announcment.
- *
- * XXX We have no idea what MOH class was in use before playing
- * the file.
*/
if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_MOH)) {
- ast_moh_start(bridge_channel->chan, NULL, NULL);
+ const char *latest_musicclass;
+
+ ast_channel_lock(bridge_channel->chan);
+ latest_musicclass = ast_strdupa(ast_channel_latest_musicclass(bridge_channel->chan));
+ ast_channel_unlock(bridge_channel->chan);
+ ast_moh_start(bridge_channel->chan, latest_musicclass, NULL);
}
}
Modified: team/dlee/ASTERISK-22296/bridges/bridge_native_rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/bridges/bridge_native_rtp.c?view=diff&rev=397678&r1=397677&r2=397678
==============================================================================
--- team/dlee/ASTERISK-22296/bridges/bridge_native_rtp.c (original)
+++ team/dlee/ASTERISK-22296/bridges/bridge_native_rtp.c Mon Aug 26 16:58:57 2013
@@ -112,8 +112,7 @@
return audio_glue0_res;
}
-/*! \brief Start RTP native bridging */
-static int native_rtp_bridge_start(struct ast_bridge *bridge)
+static int native_rtp_bridge_start(struct ast_bridge *bridge, struct ast_channel *target)
{
struct ast_bridge_channel *c0 = AST_LIST_FIRST(&bridge->channels);
struct ast_bridge_channel *c1 = AST_LIST_LAST(&bridge->channels);
@@ -152,10 +151,26 @@
break;
case AST_RTP_GLUE_RESULT_REMOTE:
- glue0->update_peer(c0->chan, instance1, vinstance1, tinstance1, cap1, 0);
- glue1->update_peer(c1->chan, instance0, vinstance0, tinstance0, cap0, 0);
- ast_debug(2, "Remotely bridged '%s' and '%s' - media will flow directly between them\n",
- ast_channel_name(c0->chan), ast_channel_name(c1->chan));
+
+ /* If we have a target, it's the channel that received the UNHOLD or UPDATE_RTP_PEER frame and was told to resume */
+ if (!target) {
+ glue0->update_peer(c0->chan, instance1, vinstance1, tinstance1, cap1, 0);
+ glue1->update_peer(c1->chan, instance0, vinstance0, tinstance0, cap0, 0);
+ ast_debug(2, "Remotely bridged '%s' and '%s' - media will flow directly between them\n",
+ ast_channel_name(c0->chan), ast_channel_name(c1->chan));
+ } else {
+ /*
+ * If a target was provided, it is the recipient of an unhold or an update and needs to have
+ * its media redirected to fit the current remote bridging needs. The other channel is either
+ * already set up to handle the new media path or will have its own set of updates independent
+ * of this pass.
+ */
+ if (c0->chan == target) {
+ glue0->update_peer(c0->chan, instance1, vinstance1, tinstance1, cap1, 0);
+ } else {
+ glue1->update_peer(c1->chan, instance0, vinstance0, tinstance0, cap0, 0);
+ }
+ }
break;
case AST_RTP_GLUE_RESULT_FORBID:
break;
@@ -164,8 +179,7 @@
return 0;
}
-/*! \brief Stop RTP native bridging */
-static void native_rtp_bridge_stop(struct ast_bridge *bridge)
+static void native_rtp_bridge_stop(struct ast_bridge *bridge, struct ast_channel *target)
{
struct ast_bridge_channel *c0 = AST_LIST_FIRST(&bridge->channels);
struct ast_bridge_channel *c1 = AST_LIST_LAST(&bridge->channels);
@@ -193,9 +207,21 @@
}
break;
case AST_RTP_GLUE_RESULT_REMOTE:
- glue0->update_peer(c0->chan, NULL, NULL, NULL, NULL, 0);
- if (glue1) {
- glue1->update_peer(c1->chan, NULL, NULL, NULL, NULL, 0);
+ if (!target) {
+ glue0->update_peer(c0->chan, NULL, NULL, NULL, NULL, 0);
+ if (glue1) {
+ glue1->update_peer(c1->chan, NULL, NULL, NULL, NULL, 0);
+ }
+ } else {
+ /*
+ * If a target was provided, it is being put on hold and should expect to
+ * receive mediafrom sterisk instead of what it was previously connected to.
+ */
+ if (c0->chan == target) {
+ glue0->update_peer(c0->chan, NULL, NULL, NULL, NULL, 0);
+ } else if (glue1) {
+ glue1->update_peer(c1->chan, NULL, NULL, NULL, NULL, 0);
+ }
}
break;
case AST_RTP_GLUE_RESULT_FORBID:
@@ -221,9 +247,9 @@
if (bridge) {
if (f->subclass.integer == AST_CONTROL_HOLD) {
- native_rtp_bridge_stop(bridge);
+ native_rtp_bridge_stop(bridge, chan);
} else if ((f->subclass.integer == AST_CONTROL_UNHOLD) || (f->subclass.integer == AST_CONTROL_UPDATE_RTP_PEER)) {
- native_rtp_bridge_start(bridge);
+ native_rtp_bridge_start(bridge, chan);
}
}
@@ -375,7 +401,7 @@
return -1;
}
- return native_rtp_bridge_start(bridge);
+ return native_rtp_bridge_start(bridge, NULL);
}
static void native_rtp_bridge_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
@@ -387,7 +413,7 @@
{
native_rtp_bridge_framehook_detach(bridge_channel);
- native_rtp_bridge_stop(bridge);
+ native_rtp_bridge_stop(bridge, NULL);
}
static int native_rtp_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Modified: team/dlee/ASTERISK-22296/build_tools/menuselect-deps.in
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/build_tools/menuselect-deps.in?view=diff&rev=397678&r1=397677&r2=397678
==============================================================================
--- team/dlee/ASTERISK-22296/build_tools/menuselect-deps.in (original)
+++ team/dlee/ASTERISK-22296/build_tools/menuselect-deps.in Mon Aug 26 16:58:57 2013
@@ -26,6 +26,7 @@
IXJUSER=@PBX_IXJUSER@
JACK=@PBX_JACK@
JANSSON=@PBX_JANSSON@
+URIPARSER=@PBX_URIPARSER@
KQUEUE=@PBX_KQUEUE@
LDAP=@PBX_LDAP@
LIBEDIT=@PBX_LIBEDIT@
Modified: team/dlee/ASTERISK-22296/channels/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/channels/Makefile?view=diff&rev=397678&r1=397677&r2=397678
==============================================================================
--- team/dlee/ASTERISK-22296/channels/Makefile (original)
+++ team/dlee/ASTERISK-22296/channels/Makefile Mon Aug 26 16:58:57 2013
@@ -63,6 +63,7 @@
clean::
$(MAKE) -C misdn clean
+ rm -f dahdi/*.o dahdi/*.i
rm -f sip/*.o sip/*.i
rm -f iax2/*.o iax2/*.i
rm -f h323/libchanh323.a h323/Makefile.ast h323/*.o h323/*.dep
Modified: team/dlee/ASTERISK-22296/channels/sig_pri.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/channels/sig_pri.c?view=diff&rev=397678&r1=397677&r2=397678
==============================================================================
--- team/dlee/ASTERISK-22296/channels/sig_pri.c (original)
+++ team/dlee/ASTERISK-22296/channels/sig_pri.c Mon Aug 26 16:58:57 2013
@@ -9430,7 +9430,7 @@
info_str = pri_dump_info_str(pri->pri);
if (info_str) {
ast_cli(fd, "%s", info_str);
- free(info_str);
+ ast_std_free(info_str);
}
#else
pri_dump_info(pri->pri);
Modified: team/dlee/ASTERISK-22296/configure.ac
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/configure.ac?view=diff&rev=397678&r1=397677&r2=397678
==============================================================================
--- team/dlee/ASTERISK-22296/configure.ac (original)
+++ team/dlee/ASTERISK-22296/configure.ac Mon Aug 26 16:58:57 2013
@@ -408,6 +408,7 @@
AST_EXT_LIB_SETUP([ISDNNET], [ISDN4Linux], [isdnnet])
AST_EXT_LIB_SETUP([JACK], [Jack Audio Connection Kit], [jack])
AST_EXT_LIB_SETUP([JANSSON], [Jansson JSON library], [jansson])
+AST_EXT_LIB_SETUP([URIPARSER], [uriparser library], [uriparser])
AST_EXT_LIB_SETUP([KQUEUE], [kqueue support], [kqueue])
AST_EXT_LIB_SETUP([LDAP], [OpenLDAP], [ldap])
AST_LIBCURL_CHECK_CONFIG([], [7.10.1])
@@ -543,6 +544,8 @@
if test "x$JANSSON_LIB" == "x"; then
AC_MSG_ERROR([*** JSON support not found (this typically means the libjansson development package is missing)])
fi
+
+AST_EXT_LIB_CHECK([URIPARSER], [uriparser], [uriParseUriA], [uriparser/Uri.h])
# Another mandatory item (unless it's explicitly disabled)
AC_ARG_ENABLE([xmldoc],
Modified: team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/astconfigparser.py
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/astconfigparser.py?view=diff&rev=397678&r1=397677&r2=397678
==============================================================================
--- team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/astconfigparser.py (original)
+++ team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/astconfigparser.py Mon Aug 26 16:58:57 2013
@@ -1,3 +1,6 @@
+import re
+
+from astdicts import OrderedDict
from astdicts import MultiOrderedDict
def merge_values(left, right, key):
@@ -21,93 +24,197 @@
added default sections. If not found at that point then a 'KeyError'
exception is raised.
"""
- def __init__(self, defaults = []):
+ count = 0
+
+ def __init__(self, defaults=None, templates=None):
MultiOrderedDict.__init__(self)
- self._defaults = defaults
+ # track an ordered id of sections
+ Section.count += 1
+ self.id = Section.count
+ self._defaults = [] if defaults is None else defaults
+ self._templates = [] if templates is None else templates
+
+ def __cmp__(self, other):
+ return cmp(self.id, other.id)
+
+ def get(self, key, from_self=True, from_templates=True, from_defaults=True):
+ if from_self and key in self:
+ return MultiOrderedDict.__getitem__(self, key)
+
+ if from_templates:
+ if self in self._templates:
+ return []
+ for t in self._templates:
+ try:
+ # fail if not found on the search - doing it this way
+ # allows template's templates to be searched.
+ return t.get(key, True, from_templates, from_defaults)
+ except KeyError:
+ pass
+
+ if from_defaults:
+ for d in self._defaults:
+ try:
+ return d.get(key, True, from_templates, from_defaults)
+ except KeyError:
+ pass
+
+ raise KeyError(key)
def __getitem__(self, key):
"""Get the value for the given key. If it is not found in the 'self'
- then check inside the defaults before declaring unable to locate."""
- if key in self:
- return MultiOrderedDict.__getitem__(self, key)
-
- for default in self._defaults:
- if key in default:
- return default[key]
-
- raise KeyError(key)
-
- def keys(self):
+ then check inside templates and defaults before declaring raising
+ a KeyError exception.
+ """
+ return self.get(key)
+
+ def keys(self, self_only=False):
res = MultiOrderedDict.keys(self)
+ if self_only:
+ return res
+
+ for d in self._templates:
+ for key in d.keys():
+ if key not in res:
+ res.append(key)
+
for d in self._defaults:
for key in d.keys():
if key not in res:
res.append(key)
return res
- def add_default(self, default):
- self._defaults.append(default)
+ def add_defaults(self, defaults):
+ defaults.sort()
+ for i in defaults:
+ self._defaults.insert(0, i)
+
+ def add_templates(self, templates):
+ templates.sort(reverse=True);
+ self._templates.extend(templates)
def get_merged(self, key):
"""Return a list of values for a given key merged from default(s)"""
# first merge key/values from defaults together
merged = []
- for i in self._defaults:
+ for i in reversed(self._defaults):
if not merged:
merged = i
continue
merged = merge_values(merged, i, key)
+
+ for i in reversed(self._templates):
+ if not merged:
+ merged = i
+ continue
+ merged = merge_values(merged, i, key)
+
# then merge self in
return merge_values(merged, self, key)
###############################################################################
-def remove_comment(line):
- """Remove any commented elements from the given line"""
- line = line.partition(COMMENT)[0]
- return line.rstrip()
+COMMENT = ';'
+COMMENT_START = ';--'
+COMMENT_END = '--;'
+
+DEFAULTSECT = 'general'
+
+def remove_comment(line, is_comment):
+ """Remove any commented elements from the line."""
+ if not line: return line, is_comment
+
+ if is_comment:
+ part = line.partition(COMMENT_END)
+ if part[1]:
+ # found multi-line comment end check string after it
+ return remove_comment(part[2], False)
+ return "", True
+
+ part = line.partition(COMMENT_START)
+ if part[1]:
+ # found multi-line comment start check string before
+ # it to make sure there wasn't an eol comment in it
+ has_comment = part[0].partition(COMMENT)
+ if has_comment[1]:
+ # eol comment found return anything before it
+ return has_comment[0], False
+
+ # check string after it to see if the comment ends
+ line, is_comment = remove_comment(part[2], True)
+ if is_comment:
+ # return possible string data before comment
+ return part[0].strip(), True
+
+ # otherwise it was an embedded comment so combine
+ return ''.join([part[0].strip(), ' ', line]).rstrip(), False
+
+ # check for eol comment
+ return line.partition(COMMENT)[0].strip(), False
+
+def try_include(line):
+ """Checks to see if the given line is an include. If so return the
+ included filename, otherwise None.
+ """
+ if not line.startswith('#'):
+ return None
+
+ # it is an include - get file name
+ try:
+ return line[line.index('"') + 1:line.rindex('"')]
+ except ValueError:
+ print "Invalid include - could not parse filename."
+ return None
def try_section(line):
"""Checks to see if the given line is a section. If so return the section
name, otherwise return 'None'.
"""
+ # leading spaces were stripped when checking for comments
if not line.startswith('['):
- return None
-
- first, second, third = line.partition(']')
- # TODO - third may contain template, parse to see if it is a template
- # or is a list of templates...return?
- return first[1:]
+ return None, False, []
+
+ section, delim, templates = line.partition(']')
+ if not templates:
+ return section[1:], False, []
+
+ # strip out the parens and parse into an array
+ templates = templates.replace('(', "").replace(')', "").split(',')
+ # go ahead and remove extra whitespace
+ templates = [i.strip() for i in templates]
+ try:
+ templates.remove('!')
+ return section[1:], True, templates
+ except:
+ return section[1:], False, templates
def try_option(line):
"""Parses the line as an option, returning the key/value pair."""
- first, second, third = line.partition('=')
- return first.strip(), third.strip()
+ data = re.split('=>?', line)
+ # should split in two (key/val), but either way use first two elements
+ return data[0].rstrip(), data[1].lstrip()
###############################################################################
-def get_value(mdict, key, index=-1):
- """Given a multi-dict, retrieves a value for the given key. If the key only
- holds a single value return that value. If the key holds more than one
- value and an index is given that is greater than or equal to zero then
- return the value at the index. Otherwise return the list of values."""
- vals = mdict[key]
- if len(vals) == 1:
- return vals[0]
- if index >= 0:
- return vals[index]
- return vals
-
-def find_value(mdicts, key, index=-1):
- """Given a list of multi-dicts, try to find value(s) for the given key."""
- if not isinstance(mdicts, list):
- # given a single multi-dict
- return get_value(mdicts, key, index)
-
- for d in mdicts:
- if key in d:
- return d[key]
- # not found, throw error
+def find_value(sections, key):
+ """Given a list of sections, try to find value(s) for the given key."""
+ # always start looking in the last one added
+ sections.sort(reverse=True);
+ for s in sections:
+ try:
+ # try to find in section and section's templates
+ return s.get(key, from_defaults=False)
+ except KeyError:
+ pass
+
+ # wasn't found in sections or a section's templates so check in defaults
+ for s in sections:
+ try:
+ # try to find in section's defaultsects
+ return s.get(key, from_self=False, from_templates=False)
+ except KeyError:
+ pass
+
raise KeyError(key)
def find_dict(mdicts, key, val):
@@ -115,80 +222,128 @@
the given key/value pair."""
def found(d):
- # just check the first value of the key
- return key in d and d[key][0] == val
-
- if isinstance(mdicts, list):
- try:
- return [d for d in mdicts if found(d)][0]
- except IndexError:
- pass
- elif found(mdicts):
- return mdicts
-
- raise LookupError("Dictionary not located for key = %s, value = %s"
- % (key, val))
+ return key in d and val in d[key]
+
+ try:
+ return [d for d in mdicts if found(d)][0]
+ except IndexError:
+ raise LookupError("Dictionary not located for key = %s, value = %s"
+ % (key, val))
+
+def get_sections(parser, key, attr='_sections', searched=None):
+ if searched is None:
+ searched = []
+ if parser is None or parser in searched:
+ return []
+
+ try:
+ sections = getattr(parser, attr)
+ res = sections[key] if key in sections else []
+ searched.append(parser)
+ return res + get_sections(parser._includes, key, attr, searched) \
+ + get_sections(parser._parent, key, attr, searched)
+ except:
+ # assume ordereddict of parsers
+ res = []
+ for p in parser.itervalues():
+ res.extend(get_sections(p, key, attr, searched))
+ return res
+
+def get_defaults(parser, key):
+ return get_sections(parser, key, '_defaults')
+
+def write_dicts(file, mdicts):
+ for section, sect_list in mdicts.iteritems():
+ # every section contains a list of dictionaries
+ for sect in sect_list:
+ file.write("[%s]\n" % section)
+ for key, val_list in sect.iteritems():
+ # every value is also a list
+ for v in val_list:
+ key_val = key
+ if v is not None:
+ key_val += " = " + str(v)
+ file.write("%s\n" % (key_val))
+ file.write("\n")
###############################################################################
-COMMENT = ';'
-DEFAULTSECT = 'general'
-
class MultiOrderedConfigParser:
- def __init__(self):
- self._default = MultiOrderedDict()
- # sections contain dictionaries of dictionaries
+ def __init__(self, parent=None):
+ self._parent = parent
+ self._defaults = MultiOrderedDict()
self._sections = MultiOrderedDict()
-
- def default(self):
- return self._default
+ self._includes = OrderedDict()
+
+ def defaults(self):
+ return self._defaults
+
+ def default(self, key):
+ """Retrieves a list of dictionaries for a default section."""
+ return get_defaults(self, key)
+
+ def add_default(self, key, template_keys=None):
+ """Adds a default section to defaults, returning the
+ default Section object.
+ """
+ if template_keys is None:
+ template_keys = []
+ return self.add_section(key, template_keys, self._defaults)
def sections(self):
return self._sections
- def section(self, section, index=-1):
- """Retrieves a section dictionary for the given section. If the section
- holds only a single section dictionary return that dictionary. If
- the section holds more than one dictionary and an index is given
- that is greater than or equal to zero then return the dictionary at
- the index. Otherwise return the list of dictionaries for the given
- section name."""
- try:
- return get_value(self._sections, section, index)
+ def section(self, key):
+ """Retrieves a list of dictionaries for a section."""
+ return get_sections(self, key)
+
+ def add_section(self, key, template_keys=None, mdicts=None):
+ if template_keys is None:
+ template_keys = []
+ if mdicts is None:
+ mdicts = self._sections
+ res = Section()
+ for t in template_keys:
+ res.add_templates(get_defaults(self, t))
+ res.add_defaults(get_defaults(self, DEFAULTSECT))
+ mdicts.insert(0, key, res)
+ return res
+
+ def includes(self):
+ return self._includes
+
+ def add_include(self, filename, parser=None):
+ if filename in self._includes:
+ return self._includes[filename]
+
+ self._includes[filename] = res = \
+ MultiOrderedConfigParser(self) if parser is None else parser
+ return res;
+
+ def get(self, section, key):
+ """Retrieves the list of values from a section for a key."""
+ try:
+ # search for the value in the list of sections
+ return find_value(self.section(section), key)
except KeyError:
- raise LookupError("section %r not found" % section)
-
- def add_section(self, section, defaults=[]):
- """Adds a section with the given name and defaults."""
- self._sections[section] = res = Section(defaults)
- return res
-
- def get(self, key, section=DEFAULTSECT, index=-1):
- """Retrieves a value for the given key from the given section. If the
- key only holds a single value return that value. If the key holds
- more than one value and an index is given that is greater than or
- equal to zero then return the value at the index. Otherwise return
- the list of values."""
- try:
- if section == DEFAULTSECT:
- return get_value(self._default, key, index)
-
- # search section(s)
- return find_value(self.section(section), key, index)
+ pass
+
+ try:
+ # section may be a default section so, search
+ # for the value in the list of defaults
+ return find_value(self.default(section), key)
except KeyError:
- # check default section if we haven't already
- if section != DEFAULTSECT:
- return self.get(key, DEFAULTSECT, index)
- raise LookupError("key %r not found in section %r"
+ raise LookupError("key %r not found for section %r"
% (key, section))
- def set(self, key, val, section=DEFAULTSECT):
+ def set(self, section, key, val):
"""Sets an option in the given section."""
- if section == DEFAULTSECT:
- self._default[key] = val
+ # TODO - set in multiple sections? (for now set in first)
+ # TODO - set in both sections and defaults?
+ if section in self._sections:
+ self.section(section)[0][key] = val
else:
- # for now only set value in first section
- self.section(section, 0)[key] = val
+ self.defaults(section)[0][key] = val
def read(self, filename):
try:
@@ -198,45 +353,42 @@
print "Could not open file ", filename, " for reading"
def _read(self, file, filename):
+ is_comment = False # used for multi-lined comments
for line in file:
- line = remove_comment(line)
+ line, is_comment = remove_comment(line, is_comment)
if not line:
# line was empty or was a comment
continue
- section = try_section(line)
+ include_name = try_include(line)
+ if include_name:
+ parser = self.add_include(include_name)
+ parser.read(include_name)
+ continue
+
+ section, is_template, templates = try_section(line)
if section:
- if section == DEFAULTSECT:
- sect = self._default
+ if section == DEFAULTSECT or is_template:
+ sect = self.add_default(section, templates)
else:
- self._sections[section] = sect = Section([self._default])
- # TODO - if section has templates add those
- # with sect.add_default
+ sect = self.add_section(section, templates)
continue
key, val = try_option(line)
sect[key] = val
- def write(self, filename):
- try:
- with open(filename, 'wt') as file:
- self._write(file)
- except IOError:
- print "Could not open file ", filename, " for writing"
- pass
-
- def _write(self, file):
- # TODO - need to write out default section, but right now in
- # our case res_sip.conf has not default/general section
- for section, sect_list in self._sections.iteritems():
- # every section contains a list of dictionaries
- for sect in sect_list:
- file.write("[%s]\n" % section)
- for key, val_list in sect.iteritems():
- # every value is also a list
- for v in val_list:
- key_val = key
- if (v is not None):
- key_val += " = " + str(v)
- file.write("%s\n" % (key_val))
- file.write("\n")
+ def write(self, f):
+ try:
+ for key, val in self._includes.iteritems():
+ val.write(key)
+ f.write('#include "%s"\n' % key)
+
+ f.write('\n')
+ write_dicts(f, self._defaults)
+ write_dicts(f, self._sections)
+ except:
+ try:
+ with open(f, 'wt') as fp:
+ self.write(fp)
+ except IOError:
+ print "Could not open file ", f, " for writing"
Modified: team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/astdicts.py
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/astdicts.py?view=diff&rev=397678&r1=397677&r2=397678
==============================================================================
--- team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/astdicts.py (original)
+++ team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/astdicts.py Mon Aug 26 16:58:57 2013
@@ -265,11 +265,28 @@
def __init__(self, *args, **kwds):
OrderedDict.__init__(self, *args, **kwds)
- def __setitem__(self, key, val):
+ def __setitem__(self, key, val, i=None):
if key not in self:
- OrderedDict.__setitem__(self, key, [val])
- elif val not in self[key]:
- self[key].append(val)
+# print "__setitem__ key = ", key, " val = ", val
+ OrderedDict.__setitem__(
+ self, key, val if isinstance(val, list) else [val])
+ return
+# print "inserting key = ", key, " val = ", val
+ vals = self[key]
+ if i is None:
+ i = len(vals)
+
+ if not isinstance(val, list):
+ if val not in vals:
+ vals.insert(i, val)
+ else:
+ for j in val.reverse():
+ if j not in vals:
+ vals.insert(i, j)
+
+
+ def insert(self, i, key, val):
+ self.__setitem__(key, val, i)
def copy(self):
# TODO - find out why for some reason copies
@@ -279,28 +296,3 @@
for v in val:
c[key] = v
return c
-
- # def update(self, other=None, **kwds):
- # if other is None:
- # pass
-
- # if isinstance(other, list):
- # for val in other:
- # update(self, val)
- # return
-
- # for key, val in other.iteritems():
- # # key = [ v1, v2, ...n ]
- # if key in self and len(self[key]) > 1:
- # # merge values adding only those not already in list
- # val = self[key] + [v for v in val if v not in self[key]]
- # OrderedDict.__setitem__(self, key, val)
- # # if hasattr(other, 'keys'):
- # # other = other.keys()
- # # for (key, val) in obj.iteritems():
- # # if key in self and len(self[key]) > 1:
- # # # add only values not already in list
- # # val = self[key] + [v for v in val if v not in self[key]]
- # # OrderedDict.__setitem__(self, key, val)
- # if kwds:
- # self.update(kwds)
Modified: team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/sip_to_res_sip.py
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/sip_to_res_sip.py?view=diff&rev=397678&r1=397677&r2=397678
==============================================================================
--- team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/sip_to_res_sip.py (original)
+++ team/dlee/ASTERISK-22296/contrib/scripts/sip_to_res_sip/sip_to_res_sip.py Mon Aug 26 16:58:57 2013
@@ -1,17 +1,24 @@
#!/usr/bin/python
+###############################################################################
+# TODO:
+# (1) There is more work to do here, at least for the sip.conf items that
+# aren't currently parsed. An issue will be created for that.
+# (2) All of the scripts should probably be passed through pylint and have
+# as many PEP8 issues fixed as possible
+# (3) A public review is probably warranted at that point of the entire script
+###############################################################################
+
+import optparse
+import astdicts
import astconfigparser
-# configuration parser for sip.conf
-sip = astconfigparser.MultiOrderedConfigParser()
-
-# configuration writer for res_sip.conf
-res_sip = astconfigparser.MultiOrderedConfigParser()
+PREFIX = 'res_sip_'
###############################################################################
### some utility functions
###############################################################################
-def section_by_type(section, type='endpoint'):
+def section_by_type(section, res_sip, type):
"""Finds a section based upon the given type, adding it if not found."""
try:
return astconfigparser.find_dict(
@@ -22,10 +29,11 @@
sect['type'] = type
return sect
-def set_value(key=None, val=None, section=None, type='endpoint'):
+def set_value(key=None, val=None, section=None, res_sip=None,
+ nmapped=None, type='endpoint'):
"""Sets the key to the value within the section in res_sip.conf"""
- def _set_value(k, v, s):
- set_value(key if key else k, v, s, type)
+ def _set_value(k, v, s, r, n):
+ set_value(key if key else k, v, s, r, n, type)
# if no value or section return the set_value
# function with the enclosed key and type
@@ -33,135 +41,151 @@
return _set_value
# otherwise try to set the value
- section_by_type(section, type)[key] = val
-
-def merge_value(key=None, val=None, section=None,
- type='endpoint', section_to=None):
+ section_by_type(section, res_sip, type)[key] = \
+ val[0] if isinstance(val, list) else val
+
+def merge_value(key=None, val=None, section=None, res_sip=None,
+ nmapped=None, type='endpoint', section_to=None):
"""Merge values from the given section with those from the default."""
- def _merge_value(k, v, s):
- merge_value(key if key else k, v, s, type, section_to)
+ def _merge_value(k, v, s, r, n):
+ merge_value(key if key else k, v, s, r, n, type, section_to)
# if no value or section return the merge_value
# function with the enclosed key and type
if not val and not section:
return _merge_value
- # should return single section
- sect = sip.section(section)
+ # should return a single value section list
+ sect = sip.section(section)[0]
# for each merged value add it to res_sip.conf
for i in sect.get_merged(key):
- set_value(key, i, section_to if section_to else section, type)
+ set_value(key, i, section_to if section_to else section,
+ res_sip, nmapped, type)
def is_in(s, sub):
"""Returns true if 'sub' is in 's'"""
return s.find(sub) != -1
+def non_mapped(nmapped):
+ def _non_mapped(section, key, val):
+ """Writes a non-mapped value from sip.conf to the non-mapped object."""
+ if section not in nmapped:
+ nmapped[section] = astconfigparser.Section()
+ if isinstance(val, list):
+ for v in val:
+ # since coming from sip.conf we can assume
+ # single section lists
+ nmapped[section][0][key] = v
+ else:
+ nmapped[section][0][key] = val
+ return _non_mapped
+
###############################################################################
### mapping functions -
### define f(key, val, section) where key/val are the key/value pair to
### write to given section in res_sip.conf
###############################################################################
-def set_dtmfmode(key, val, section):
+def set_dtmfmode(key, val, section, res_sip, nmapped):
"""Sets the dtmfmode value. If value matches allowable option in res_sip
then map it, otherwise set it to none.
"""
# available res_sip.conf values: frc4733, inband, info, none
if val != 'inband' or val != 'info':
- print "sip.conf: dtmfmode = %s did not fully map into " \
- "res_sip.conf - setting to 'none'" % val
+ nmapped(section, key, val + " ; did not fully map - set to none")
val = 'none'
- set_value(key, val, section)
-
-def from_nat(key, val, section):
+ set_value(key, val, section, res_sip, nmapped)
+
+def from_nat(key, val, section, res_sip, nmapped):
"""Sets values from nat into the appropriate res_sip.conf options."""
# nat from sip.conf can be comma separated list of values:
# yes/no, [auto_]force_rport, [auto_]comedia
if is_in(val, 'yes'):
- set_value('rtp_symmetric', 'yes', section)
- set_value('rewrite_contact', 'yes', section)
+ set_value('rtp_symmetric', 'yes', section, res_sip, nmapped)
+ set_value('rewrite_contact', 'yes', section, res_sip, nmapped)
if is_in(val, 'comedia'):
- set_value('rtp_symmetric', 'yes', section)
+ set_value('rtp_symmetric', 'yes', section, res_sip, nmapped)
if is_in(val, 'force_rport'):
- set_value('force_rport', 'yes', section)
- set_value('rewrite_contact', 'yes', section)
-
[... 2285 lines stripped ...]
More information about the asterisk-commits
mailing list