Skip to content

Instantly share code, notes, and snippets.

@ndenev
Created February 3, 2014 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ndenev/8784232 to your computer and use it in GitHub Desktop.
Save ndenev/8784232 to your computer and use it in GitHub Desktop.
#!/opt/local/bin/python
#
# Autogenerate Nsnitro exception classes from NITRO API Docs.
# Author: ndenev@amazon.com January, 2014
#
# Requires: BeautifulSoup for the html parsing
#
from collections import OrderedDict
import argparse
import bs4
import re
import string
import sys
import textwrap
""" location on the netscaler /var/netscaler/nitro/nitro-rest.tgz """
DOC = '/Users/ndenev/Netscaler/doc/html/errorlisting.html'
""" NSNitroError class definition at the beginning of the file """
HEADER = '''\
from collections import defaultdict
class NSNitroError(Exception):
""" Custom exception class """
def __init__(self, value, code=0):
self.message = value
self.code = code
def __str__(self):
return repr(self.message)
'''
""" Template for specific exception classes """
SPEC_EXC = string.Template('''\
class $exc($err_cls):
"""
Nitro error code $errc
$desc
"""
pass
''')
""" Template for base exception classes """
BASE_EXC = string.Template('''\
class $err_cls(NSNitroError):
"""
Base exception class $err_cls
"""
pass
''')
def gen_exception_lookup_dict(exceptions):
lines = []
lines.append("NSNitroExceptionClassMap = defaultdict(lambda: NSNitroError)")
lines.append("NSNitroExceptions = {")
for code, exception in exceptions.iteritems():
lines.append(" {}: {},".format(code, exception))
lines.append("}")
lines.append("NSNitroExceptionClassMap.update(NSNitroExceptions)")
lines.append("")
return "\n".join(lines)
def gen__init__(exceptions):
lines = []
lines.append("from nsexceptions import NSNitroError")
lines.append("from nsexceptions import NSNitroExceptionClassMap")
for exception in exceptions.values():
lines.append("from nsexceptions import {}".format(exception))
lines.append("")
lines.append("__all__ = [")
for exception in exceptions.values():
lines.append(" '{}',".format(exception))
lines.append(" ]")
lines.append("")
return "\n".join(lines)
def main():
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument("--write-files", dest='write_files', default=False, action='store_true',
help="If specified writes __init__.py and nsexceptions.py files in the current directory.")
args = arg_parser.parse_args()
if args.write_files:
init_file = open('__init__.py', 'w')
exceptions_file = open('nsexceptions.py', 'w')
else:
init_file = exceptions_file = sys.stdout
sys.stderr.write("printing header...\n")
exceptions_file.write(HEADER)
sys.stderr.write("opening HTML doc file.\n")
with open(DOC, 'r') as doc:
html_doc = doc.read()
sys.stderr.write("parsing HTML doc file...")
soup = bs4.BeautifulSoup(html_doc)
sys.stderr.write("done.\n")
error_class = ""
exceptions = OrderedDict()
sys.stderr.write("generating exception classes...")
rows = soup.find_all('tr')
for row in rows:
cells = row.find_all('td')
if len(cells) == 1:
m = re.search("^\s*(.*\s+ERRORS)$", cells[0].get_text())
if m:
error_class = m.group(1)
error_class = string.capwords(error_class)
error_class = re.sub("\s", "", error_class)
error_class = "NSNitro{}".format(error_class)
exceptions_file.write(BASE_EXC.substitute(err_cls=error_class))
next
if len(cells) == 4:
m1 = re.search("\d+", cells[1].get_text())
m2 = re.search("0x[a-f0-9]+", cells[2].get_text())
if m1 and m2:
error_name = cells[0].get_text()
error_code = cells[1].get_text()
error_desc = cells[3].get_text()
exception = string.capwords(error_name, "_")
exception = re.sub("[_\s]", "", exception)
exception = "NSNitro{}".format(exception)
if error_code in exceptions:
raise
exceptions[error_code] = exception
desc = "\n ".join(textwrap.wrap(error_desc,64))
exceptions_file.write(SPEC_EXC.substitute(exc=exception, err_cls=error_class, errc=error_code, desc=desc))
sys.stderr.write("done.\n")
sys.stderr.write("generating exception lookup dictionary...")
exceptions_file.write(gen_exception_lookup_dict(exceptions))
sys.stderr.write("done.\n")
sys.stderr.write("generating __init__.py file...")
init_file.write(gen__init__(exceptions))
sys.stderr.write("done.\n")
exceptions_file.close()
init_file.close()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment