Skip to content
Snippets Groups Projects
  • Matthew Jordan's avatar
    82a7409c
    Add AMI event documentation · 82a7409c
    Matthew Jordan authored
    This patch adds the core changes necessary to support AMI event documentation
    in the source files of Asterisk, and adds documentation to those AMI events
    defined in the core application modules.  Event documentation is built from
    the source by two new python scripts, located in build_tools:
    get_documentation.py and post_process_documentation.py.
    
    The get_documentation.py script mirrors the actions of the existing AWK
    get_documentation scripts, except that it will scan the entirety of a source
    file for Asterisk documentation.  Upon encountering it, if the documentation
    happens to be an AMI event, it will attempt to extract information about the
    event directly from the manager event macro calls that raise the event.  The
    post_process_documentation.py script combines manager event instances that
    are the same event but documented in multiple source files.  It generates
    the final core-[lang].xml file.
    
    As this process can take longer to complete than a typical 'make all', it
    is only performed if a new make target, 'full', is chosen.
    
    Review: https://reviewboard.asterisk.org/r/1967/
    
    git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@369346 65c4cc65-6c06-0410-ace0-fbb531ad65f3
    82a7409c
    History
    Add AMI event documentation
    Matthew Jordan authored
    This patch adds the core changes necessary to support AMI event documentation
    in the source files of Asterisk, and adds documentation to those AMI events
    defined in the core application modules.  Event documentation is built from
    the source by two new python scripts, located in build_tools:
    get_documentation.py and post_process_documentation.py.
    
    The get_documentation.py script mirrors the actions of the existing AWK
    get_documentation scripts, except that it will scan the entirety of a source
    file for Asterisk documentation.  Upon encountering it, if the documentation
    happens to be an AMI event, it will attempt to extract information about the
    event directly from the manager event macro calls that raise the event.  The
    post_process_documentation.py script combines manager event instances that
    are the same event but documented in multiple source files.  It generates
    the final core-[lang].xml file.
    
    As this process can take longer to complete than a typical 'make all', it
    is only performed if a new make target, 'full', is chosen.
    
    Review: https://reviewboard.asterisk.org/r/1967/
    
    git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@369346 65c4cc65-6c06-0410-ace0-fbb531ad65f3
post_process_documentation.py 3.38 KiB
#! /usr/bin/env python
# vin: sw=3 et:
'''
Copyright (C) 2012, Digium, Inc.
Matt Jordan <mjordan@digium.com>

This program is free software, distributed under the terms of
the GNU General Public License Version 2.
'''

import sys
import os
import optparse
import xml.dom.minidom

from xml.dom.minidom import Element, parse


def merge_parameter_information(managerEvent):
    ''' Merge the parameter information across all managerEventInstances
    within a managerEvent node '''

    def __swap_parameter_documentation(one, two):
        # See who has the better documentation and use it
        if (one.hasChildNodes()):
            two.parentNode.replaceChild(one.cloneNode(True), two)
        elif (two.hasChildNodes()):
            one.parentNode.replaceChild(two.cloneNode(True), one)

    def __merge_parameter(param, other_instances):
        # Compare the parameter to every other instance's set of parameters
        for other in other_instances:
            other_parameters = other.getElementsByTagName("parameter")
            match = [p for p in other_parameters
                     if p.getAttribute('name') == param.getAttribute('name')]
            if (match):
                # See who has the better documentation and use it
                __swap_parameter_documentation(param, match[0])

    instances = managerEvent.getElementsByTagName("managerEventInstance")
    merged = []
    for instance in instances:
        others = [i for i in instances if i != instance]
        parameters = instance.getElementsByTagName("parameter")
        for parameter in parameters:
            if parameter not in merged:
                merged.append(parameter)
                __merge_parameter(parameter, others)


def collapse_event_pair(managerEventOne, managerEventTwo):
    # Move all children of managerEventTwo to managerEventOne
    for node in managerEventTwo.childNodes:
        managerEventOne.appendChild(node.cloneNode(True))

    return managerEventOne


def collapse_manager_events(rootNode, managerEvents):
    events = {}
    for managerEvent in managerEvents:
        rootNode.removeChild(managerEvent)
        attr = managerEvent.getAttribute('name')
        if attr in events:
            # match, collapse the two managerEvents
            events[attr] = collapse_event_pair(events[attr], managerEvent)
        else:
            events[attr] = managerEvent

    # Combine parameter information and re-add the manager Events
    for k, event in events.items():
        merge_parameter_information(event)
        rootNode.appendChild(event)
    return


def main(argv=None):

    if argv is None:
        argv = sys.argv

    parser = optparse.OptionParser()
    parser.add_option('-i', '--input', dest='input_file',
                      default='doc/core-full-en_US.xml',
                      help='The XML file to process')
    parser.add_option('-o', '--output', dest='output_file',
                      default='doc/core-en_US.xml',
                      help='The XML file to create')
    (options, args) = parser.parse_args(argv)

    dom = parse(options.input_file)

    datasource = open(options.output_file, 'w')
    docs = dom.getElementsByTagName("docs")[0]
    managerEvents = dom.getElementsByTagName("managerEvent")
    if (managerEvents):
        collapse_manager_events(docs, managerEvents)

    dom.writexml(datasource)
    datasource.close()

    return 0

if __name__ == "__main__":
    sys.exit(main() or 0)