<p>Matthew Fredrickson has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/8233">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">contrib/script/sip_to_pjsip: add support for realtime<br><br>Add a new script that can read from legacy realtime peers & generate<br>an sql file for populating pjsip endpoints, identify, and aor records.<br><br>ASTERISK-27348 #close<br><br>Change-Id: Idd3d7968a3c9c3ee7936d21acbdaf001b429bf65<br>---<br>M contrib/scripts/sip_to_pjsip/sip_to_pjsip.py<br>A contrib/scripts/sip_to_pjsip/sip_to_pjsql.py<br>A contrib/scripts/sip_to_pjsip/sqlconfigparser.py<br>3 files changed, 151 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/33/8233/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py b/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py<br>index 533e4ba..9f7d991 100755<br>--- a/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py<br>+++ b/contrib/scripts/sip_to_pjsip/sip_to_pjsip.py<br>@@ -1203,7 +1203,7 @@<br>     map specific sections from sip.conf into it.<br>     Returns the new pjsip.conf object once completed<br>     """<br>-    pjsip = astconfigparser.MultiOrderedConfigParser()<br>+    pjsip = sip.__class__()<br>     non_mappings[filename] = astdicts.MultiOrderedDict()<br>     nmapped = non_mapped(non_mappings[filename])<br>     if not include:<br>diff --git a/contrib/scripts/sip_to_pjsip/sip_to_pjsql.py b/contrib/scripts/sip_to_pjsip/sip_to_pjsql.py<br>new file mode 100755<br>index 0000000..d93bca5<br>--- /dev/null<br>+++ b/contrib/scripts/sip_to_pjsip/sip_to_pjsql.py<br>@@ -0,0 +1,81 @@<br>+#!/usr/bin/python<br>+<br>+from sip_to_pjsip import cli_options<br>+from sip_to_pjsip import convert<br>+import sip_to_pjsip<br>+import optparse<br>+<br>+<br>+import sqlconfigparser<br>+<br>+<br>+def write_pjsip(filename, pjsip, non_mappings):<br>+    """<br>+    Write pjsip.sql file to disk<br>+    """<br>+    try:<br>+        with open(filename, 'wt') as fp:<br>+            pjsip.write(fp)<br>+<br>+    except IOError:<br>+        print "Could not open file ", filename, " for writing"<br>+<br>+def cli_options():<br>+    """<br>+    Parse command line options and apply them. If invalid input is given,<br>+    print usage information<br>+<br>+    """<br>+    global user<br>+    global password<br>+    global host<br>+    global port<br>+    global database<br>+    global table<br>+<br>+    usage = "usage: %prog [options] [input-file [output-file]]\n\n" \<br>+        "Converts the chan_sip configuration input-file to mysql output-file.\n" \<br>+        "The input-file defaults to 'sip.conf'.\n" \<br>+        "The output-file defaults to 'pjsip.sql'."<br>+    parser = optparse.OptionParser(usage=usage)<br>+    parser.add_option('-u', '--user', dest='user', default="root",<br>+                      help='mysql username')<br>+    parser.add_option('-p', '--password', dest='password', default="root",<br>+                      help='mysql password')<br>+    parser.add_option('-H', '--host', dest='host', default="127.0.0.1",<br>+                      help='mysql host ip')<br>+    parser.add_option('-P', '--port', dest='port', default="3306",<br>+                      help='mysql port number')<br>+    parser.add_option('-D', '--database', dest='database', default="asterisk",<br>+                      help='mysql port number')<br>+    parser.add_option('-t', '--table', dest='table', default="sippeers",<br>+                      help='name of sip realtime peers table')<br>+<br>+    options, args = parser.parse_args()<br>+<br>+    user = options.user<br>+    password = options.password<br>+    host = options.host<br>+    port = options.port<br>+    database = options.database<br>+    table = options.table<br>+<br>+    sip_filename = args[0] if len(args) else 'sip.conf'<br>+    pjsip_filename = args[1] if len(args) == 2 else 'pjsip.sql'<br>+<br>+    return sip_filename, pjsip_filename<br>+<br>+if __name__ == "__main__":<br>+    sip_filename, pjsip_filename = cli_options()<br>+    sip = sqlconfigparser.SqlConfigParser(table)<br>+    sip_to_pjsip.sip = sip<br>+    sip.connect(user,password,host,port,database)<br>+    print 'Please, report any issue at:'<br>+    print '    https://issues.asterisk.org/'<br>+    print 'Reading', sip_filename<br>+    sip.read(sip_filename)<br>+    print 'Converting to PJSIP realtime sql...'<br>+    pjsip, non_mappings = convert(sip, pjsip_filename, dict(), False)<br>+    print 'Writing', pjsip_filename<br>+    write_pjsip(pjsip_filename, pjsip, non_mappings)<br>+<br>diff --git a/contrib/scripts/sip_to_pjsip/sqlconfigparser.py b/contrib/scripts/sip_to_pjsip/sqlconfigparser.py<br>new file mode 100644<br>index 0000000..e87224f<br>--- /dev/null<br>+++ b/contrib/scripts/sip_to_pjsip/sqlconfigparser.py<br>@@ -0,0 +1,69 @@<br>+from astconfigparser import MultiOrderedConfigParser<br>+<br>+import MySQLdb<br>+import traceback<br>+<br>+class SqlConfigParser(MultiOrderedConfigParser):<br>+<br>+    _tablename = "sippeers"<br>+<br>+    def __init__(self,tablename="sippeers"):<br>+        self._tablename=tablename<br>+        MultiOrderedConfigParser.__init__(self)<br>+<br>+    def connect(self, user, password, host, port, database):<br>+        self.cnx = MySQLdb.connect(user=user,passwd=password,host=host,port=int(port),db=database)<br>+<br>+    def read(self, filename, sect=None):<br>+        MultiOrderedConfigParser.read(self, filename, sect)<br>+        # cursor = self.cnx.cursor(dictionary=True)<br>+        cursor = self.cnx.cursor(cursorclass=MySQLdb.cursors.DictCursor)<br>+        cursor.execute("SELECT * from `" + MySQLdb.escape_string(self._tablename) + "`")<br>+        rows = cursor.fetchall()<br>+<br>+        for row in rows:<br>+            sect = self.add_section(row['name'])<br>+            for key in row:<br>+                if (row[key] != None):<br>+                    for elem in str(row[key]).split(";"):<br>+                        sect[key] = elem<br>+                    #sect[key] = str(row[key]).split(";")<br>+<br>+    def write_dicts(self, config_file, mdicts):<br>+        """Write the contents of the mdicts to the specified config file"""<br>+        for section, sect_list in mdicts.iteritems():<br>+            # every section contains a list of dictionaries<br>+            for sect in sect_list:<br>+                sql = "INSERT INTO "<br>+                if (sect.get('type')[0] == "endpoint"):<br>+                    sql += "ps_endpoints "<br>+                elif (sect.get('type')[0] == "aor" and section != "sbc"):<br>+                    sql += "ps_aors "<br>+                elif (sect.get('type')[0] == "identify"):<br>+                    sql += "ps_endpoint_id_ips"<br>+                else:<br>+                    continue<br>+<br>+                sql += " SET `id` = " + "\"" + MySQLdb.escape_string(section) + "\""<br>+                for key, val_list in sect.iteritems():<br>+                    if key == "type":<br>+                        continue<br>+                    # every value is also a list<br>+<br>+                    key_val = " `" + key + "`"<br>+                    key_val += " = " + "\"" + MySQLdb.escape_string(";".join(val_list)) + "\""<br>+                    sql += ","<br>+                    sql += key_val<br>+<br>+                config_file.write("%s;\n" % (sql))<br>+<br>+    def write(self, config_file):<br>+        """Write configuration information out to a file"""<br>+        try:<br>+            self.write_dicts(config_file, self._sections)<br>+        except Exception,e:<br>+                print "Could not open file ", config_file, " for writing"<br>+                traceback.print_exc()<br>+<br>+<br>+<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/8233">change 8233</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/8233"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Idd3d7968a3c9c3ee7936d21acbdaf001b429bf65 </div>
<div style="display:none"> Gerrit-Change-Number: 8233 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Matthew Fredrickson <creslin@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Torrey Searle <tsearle@gmail.com> </div>