Loading tosca2doc.py 0 → 100755 +192 −0 Original line number Diff line number Diff line #!/usr/bin/python2.7 ''' Parses a TOSCA template and generates a docx file ''' import sys import toscaparser.utils.yamlparser as yaml import docx from docx.enum.text import WD_PARAGRAPH_ALIGNMENT PRINT_TRESHOLD = 1 TEMPLATES = {} FNS = { 'VNFD' : 'etsi_nfv_sol001_vnfd_2_5_1_types.yaml', 'NSD' : 'etsi_nfv_sol001_nsd_2_5_1_types.yaml', 'PNFD' : 'etsi_nfv_sol001_pnfd_2_5_1_types.yaml' } TOSCA_TYPES = [ 'data_types', 'artifact_types', 'capability_types', 'requirements_types', 'relationship_types', 'interface_types', 'node_types', 'group_types', 'policy_types' ] TOSCA_TYPES_PRETTYPRINT = { 'data_types': 'Data Types', 'artifact_types': 'Artifact Types', 'capability_types': 'Capability Types', 'requirements_types': 'Requirements types', 'relationship_types': 'Relationship Types', 'interface_types': 'Interface Types', 'node_types': 'Node Types', 'group_types': 'Group Types', 'policy_types': 'Policy Types' } IDS = [6, 2, 1, 1] def load_template(file_path, templs, key): ''' Loads the content of the file at file_patch into the YAML templates array ''' yaml_data = open(file_path).read() #print("+++++++++++++++++++++++++++++++++++++") #print(yaml_data) #print("+++++++++++++++++++++++++++++++++++++") templs[key] = yaml.simple_ordered_parse(yaml_data) def print_lvl(num, txt): if num + 1 > PRINT_TRESHOLD: return index = ".".join(map(str, IDS[:(num+1)])) print index + " " + ('-'*(num+1)) + ' ' + txt def add_heading_with_num(num, txt, doc): ''' Add a new heading to the document, with the calculated index number ''' index = ".".join(map(str, IDS[:(num+1)])) doc.add_heading(index + " " + txt, num) def cell_text_bold(cell): cell.paragraphs[0].runs[0].font.bold = True def cell_text_centered(cell): cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER def mk_props_table_hdr(table): hdr_cells = table.rows[0].cells hdr_cells[0].text = 'Name' hdr_cells[1].text = 'Required' hdr_cells[2].text = 'Type' hdr_cells[3].text = 'Constraints' hdr_cells[4].text = 'Description' map(cell_text_bold, hdr_cells) map(cell_text_centered, hdr_cells) def dt_name_from_path(dt_path): return dt_path.split('.')[-1] def prop_field_to_str(prop_field): if type(prop_field) == bool: return 'yes' if prop_field else 'no' return str(prop_field) def add_prop_row(prop_name, prop_fields, table): ''' Add a row to table and fills it with info from prop ''' nrow = table.add_row() prop_cells = nrow.cells prop_cells[0].text = prop_name all_fields = ['required', 'type', 'constraints', 'description'] counter = 1 for field in all_fields: if field in prop_fields: prop_cells[counter].text = prop_field_to_str(prop_fields[field]) counter = counter + 1 def print_all_types(templ, lvl, doc): for tosca_type in TOSCA_TYPES: if not tosca_type in templ: continue print_lvl(lvl, tosca_type) add_heading_with_num(lvl, TOSCA_TYPES_PRETTYPRINT[tosca_type], doc) for data_type in templ[tosca_type]: print_lvl(lvl + 1, data_type) add_heading_with_num(lvl + 1, data_type, doc) if 'description' in templ[tosca_type][data_type]: print_lvl(lvl + 2, 'Description') add_heading_with_num(lvl + 2, 'Description', doc) doc.add_paragraph(templ[tosca_type][data_type]['description']) IDS[lvl+2] = IDS[lvl+2] + 1 if 'properties' in templ[tosca_type][data_type]: print_lvl(lvl + 2, 'Properties') add_heading_with_num(lvl + 2, 'Properties', doc) # num_row = templ[tosca_type][data_type]['properties'].items() doc.add_paragraph("The properties of the "+ dt_name_from_path(data_type) +" data type shall comply with the provisions set out in table REF_TBD.") table = doc.add_table(rows=1, cols=5) mk_props_table_hdr(table) for prop in templ[tosca_type][data_type]['properties']: # print "PROP: " + prop + ", VAL: " + str(templ[tosca_type][data_type]['properties'][prop]) add_prop_row(prop, templ[tosca_type][data_type]['properties'][prop], table) IDS[lvl+2] = IDS[lvl+2] + 1 print_lvl(lvl + 2, 'Definition') add_heading_with_num(lvl + 2, 'Definition', doc) doc.add_paragraph("The syntax of the "+ dt_name_from_path(data_type)+ " data type shall comply with the following definition:") def_table = doc.add_table(rows=1, cols=1) def_table.rows[0].cells[0].text = 'TBD' IDS[lvl+2] = IDS[lvl+2] + 1 print_lvl(lvl + 2, 'Examples') add_heading_with_num(lvl + 2, 'Examples', doc) def_table = doc.add_table(rows=1, cols=1) def_table.rows[0].cells[0].text = 'TBD' IDS[lvl+2] = IDS[lvl+2] + 1 print_lvl(lvl + 2, 'Additional Requirements') add_heading_with_num(lvl + 2, 'Additional Requirements', doc) doc.add_paragraph("None.") IDS[lvl+2] = IDS[lvl+2] + 1 IDS[lvl+1] = IDS[lvl+1] + 1 IDS[lvl+2] = 1 IDS[lvl+1] = 1 IDS[lvl] = IDS[lvl] + 1 IDS[lvl] = 2 def generate_from_file(fn, doc, fpath): load_template(fpath, TEMPLATES, fn) print_lvl(0, fn) add_heading_with_num(0, fn, doc) print_all_types(TEMPLATES[fn], 1, doc) #print TEMPLATES[fn] if __name__ == "__main__": doc = docx.Document() if len(sys.argv) < 2: print "Usage: robot2doc <robot_file_or_dir> [<out_file> [spec_section_title]]" sys.exit() FOLDR = sys.argv[1] print "Using folder: " + sys.argv[1] for fn in ['VNFD', 'NSD', 'PNFD']: generate_from_file(fn, doc, FOLDR + '/' + FNS[fn]) IDS[0] = IDS[0] + 1 doc.save('sol001.docx') web_app.py 0 → 100644 +94 −0 Original line number Diff line number Diff line #!/bin/bash import os from flask import Flask, flash, request, redirect, url_for, send_file from werkzeug.utils import secure_filename import docx import tosca2doc app = Flask(__name__) UPLOAD_FOLDER = '/tmp/upload' ALLOWED_EXTENSIONS = set(['txt', 'yaml', 'docx']) app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER app.secret_key = 'super secret key' app.config['SESSION_TYPE'] = 'filesystem' HOME=''' <!doctype html> <title>tosca2doc</title> <h1>tosca2doc & doc2tosca</h1> <h2>tosca2doc</h2> <form action="/tosca2doc" method="post" enctype="multipart/form-data"> Tosca YAML file: <input type="file" name="file" multiple=""/> <input type="submit" value="Upload" /> </form> <h2>doc2tosca</h2> ''' TOSCA_DEFS=['VNFD', 'NSD', 'PNFD'] def allowed_file(filename): ''' Check filename is in the list of allowed extensions ''' return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @app.route("/") def hello(): return HOME @app.route("/tosca2doc", methods=['POST']) def mk_tosca2doc(): if 'file' not in request.files: flash('No file part') return redirect(request.url) ufiles=request.files.getlist("file") for tosca_def in TOSCA_DEFS: found=False for uploaded_file in ufiles: if tosca_def in uploaded_file.filename or \ tosca_def.lower() in uploaded_file.filename: found=True #if uploaded_file: # print "-------------------" # print uploaded_file.read() # print "-------------------" if not found: flash('No file part') print('No file part') return redirect("/") for file in ufiles: if file.filename == '': print('No selected file') flash('No selected file') return redirect("/") doc = docx.Document() for tosca_def in TOSCA_DEFS: for file in ufiles: if tosca_def in uploaded_file.filename or \ tosca_def.lower() in uploaded_file.filename: filename = secure_filename(file.filename) filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(filepath) file.close() tosca2doc.generate_from_file(tosca_def, doc, filepath) doc.save('/tmp/myfile.docx') return send_file('/tmp/myfile.docx') return ("No content found") No newline at end of file Loading
tosca2doc.py 0 → 100755 +192 −0 Original line number Diff line number Diff line #!/usr/bin/python2.7 ''' Parses a TOSCA template and generates a docx file ''' import sys import toscaparser.utils.yamlparser as yaml import docx from docx.enum.text import WD_PARAGRAPH_ALIGNMENT PRINT_TRESHOLD = 1 TEMPLATES = {} FNS = { 'VNFD' : 'etsi_nfv_sol001_vnfd_2_5_1_types.yaml', 'NSD' : 'etsi_nfv_sol001_nsd_2_5_1_types.yaml', 'PNFD' : 'etsi_nfv_sol001_pnfd_2_5_1_types.yaml' } TOSCA_TYPES = [ 'data_types', 'artifact_types', 'capability_types', 'requirements_types', 'relationship_types', 'interface_types', 'node_types', 'group_types', 'policy_types' ] TOSCA_TYPES_PRETTYPRINT = { 'data_types': 'Data Types', 'artifact_types': 'Artifact Types', 'capability_types': 'Capability Types', 'requirements_types': 'Requirements types', 'relationship_types': 'Relationship Types', 'interface_types': 'Interface Types', 'node_types': 'Node Types', 'group_types': 'Group Types', 'policy_types': 'Policy Types' } IDS = [6, 2, 1, 1] def load_template(file_path, templs, key): ''' Loads the content of the file at file_patch into the YAML templates array ''' yaml_data = open(file_path).read() #print("+++++++++++++++++++++++++++++++++++++") #print(yaml_data) #print("+++++++++++++++++++++++++++++++++++++") templs[key] = yaml.simple_ordered_parse(yaml_data) def print_lvl(num, txt): if num + 1 > PRINT_TRESHOLD: return index = ".".join(map(str, IDS[:(num+1)])) print index + " " + ('-'*(num+1)) + ' ' + txt def add_heading_with_num(num, txt, doc): ''' Add a new heading to the document, with the calculated index number ''' index = ".".join(map(str, IDS[:(num+1)])) doc.add_heading(index + " " + txt, num) def cell_text_bold(cell): cell.paragraphs[0].runs[0].font.bold = True def cell_text_centered(cell): cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER def mk_props_table_hdr(table): hdr_cells = table.rows[0].cells hdr_cells[0].text = 'Name' hdr_cells[1].text = 'Required' hdr_cells[2].text = 'Type' hdr_cells[3].text = 'Constraints' hdr_cells[4].text = 'Description' map(cell_text_bold, hdr_cells) map(cell_text_centered, hdr_cells) def dt_name_from_path(dt_path): return dt_path.split('.')[-1] def prop_field_to_str(prop_field): if type(prop_field) == bool: return 'yes' if prop_field else 'no' return str(prop_field) def add_prop_row(prop_name, prop_fields, table): ''' Add a row to table and fills it with info from prop ''' nrow = table.add_row() prop_cells = nrow.cells prop_cells[0].text = prop_name all_fields = ['required', 'type', 'constraints', 'description'] counter = 1 for field in all_fields: if field in prop_fields: prop_cells[counter].text = prop_field_to_str(prop_fields[field]) counter = counter + 1 def print_all_types(templ, lvl, doc): for tosca_type in TOSCA_TYPES: if not tosca_type in templ: continue print_lvl(lvl, tosca_type) add_heading_with_num(lvl, TOSCA_TYPES_PRETTYPRINT[tosca_type], doc) for data_type in templ[tosca_type]: print_lvl(lvl + 1, data_type) add_heading_with_num(lvl + 1, data_type, doc) if 'description' in templ[tosca_type][data_type]: print_lvl(lvl + 2, 'Description') add_heading_with_num(lvl + 2, 'Description', doc) doc.add_paragraph(templ[tosca_type][data_type]['description']) IDS[lvl+2] = IDS[lvl+2] + 1 if 'properties' in templ[tosca_type][data_type]: print_lvl(lvl + 2, 'Properties') add_heading_with_num(lvl + 2, 'Properties', doc) # num_row = templ[tosca_type][data_type]['properties'].items() doc.add_paragraph("The properties of the "+ dt_name_from_path(data_type) +" data type shall comply with the provisions set out in table REF_TBD.") table = doc.add_table(rows=1, cols=5) mk_props_table_hdr(table) for prop in templ[tosca_type][data_type]['properties']: # print "PROP: " + prop + ", VAL: " + str(templ[tosca_type][data_type]['properties'][prop]) add_prop_row(prop, templ[tosca_type][data_type]['properties'][prop], table) IDS[lvl+2] = IDS[lvl+2] + 1 print_lvl(lvl + 2, 'Definition') add_heading_with_num(lvl + 2, 'Definition', doc) doc.add_paragraph("The syntax of the "+ dt_name_from_path(data_type)+ " data type shall comply with the following definition:") def_table = doc.add_table(rows=1, cols=1) def_table.rows[0].cells[0].text = 'TBD' IDS[lvl+2] = IDS[lvl+2] + 1 print_lvl(lvl + 2, 'Examples') add_heading_with_num(lvl + 2, 'Examples', doc) def_table = doc.add_table(rows=1, cols=1) def_table.rows[0].cells[0].text = 'TBD' IDS[lvl+2] = IDS[lvl+2] + 1 print_lvl(lvl + 2, 'Additional Requirements') add_heading_with_num(lvl + 2, 'Additional Requirements', doc) doc.add_paragraph("None.") IDS[lvl+2] = IDS[lvl+2] + 1 IDS[lvl+1] = IDS[lvl+1] + 1 IDS[lvl+2] = 1 IDS[lvl+1] = 1 IDS[lvl] = IDS[lvl] + 1 IDS[lvl] = 2 def generate_from_file(fn, doc, fpath): load_template(fpath, TEMPLATES, fn) print_lvl(0, fn) add_heading_with_num(0, fn, doc) print_all_types(TEMPLATES[fn], 1, doc) #print TEMPLATES[fn] if __name__ == "__main__": doc = docx.Document() if len(sys.argv) < 2: print "Usage: robot2doc <robot_file_or_dir> [<out_file> [spec_section_title]]" sys.exit() FOLDR = sys.argv[1] print "Using folder: " + sys.argv[1] for fn in ['VNFD', 'NSD', 'PNFD']: generate_from_file(fn, doc, FOLDR + '/' + FNS[fn]) IDS[0] = IDS[0] + 1 doc.save('sol001.docx')
web_app.py 0 → 100644 +94 −0 Original line number Diff line number Diff line #!/bin/bash import os from flask import Flask, flash, request, redirect, url_for, send_file from werkzeug.utils import secure_filename import docx import tosca2doc app = Flask(__name__) UPLOAD_FOLDER = '/tmp/upload' ALLOWED_EXTENSIONS = set(['txt', 'yaml', 'docx']) app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER app.secret_key = 'super secret key' app.config['SESSION_TYPE'] = 'filesystem' HOME=''' <!doctype html> <title>tosca2doc</title> <h1>tosca2doc & doc2tosca</h1> <h2>tosca2doc</h2> <form action="/tosca2doc" method="post" enctype="multipart/form-data"> Tosca YAML file: <input type="file" name="file" multiple=""/> <input type="submit" value="Upload" /> </form> <h2>doc2tosca</h2> ''' TOSCA_DEFS=['VNFD', 'NSD', 'PNFD'] def allowed_file(filename): ''' Check filename is in the list of allowed extensions ''' return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @app.route("/") def hello(): return HOME @app.route("/tosca2doc", methods=['POST']) def mk_tosca2doc(): if 'file' not in request.files: flash('No file part') return redirect(request.url) ufiles=request.files.getlist("file") for tosca_def in TOSCA_DEFS: found=False for uploaded_file in ufiles: if tosca_def in uploaded_file.filename or \ tosca_def.lower() in uploaded_file.filename: found=True #if uploaded_file: # print "-------------------" # print uploaded_file.read() # print "-------------------" if not found: flash('No file part') print('No file part') return redirect("/") for file in ufiles: if file.filename == '': print('No selected file') flash('No selected file') return redirect("/") doc = docx.Document() for tosca_def in TOSCA_DEFS: for file in ufiles: if tosca_def in uploaded_file.filename or \ tosca_def.lower() in uploaded_file.filename: filename = secure_filename(file.filename) filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(filepath) file.close() tosca2doc.generate_from_file(tosca_def, doc, filepath) doc.save('/tmp/myfile.docx') return send_file('/tmp/myfile.docx') return ("No content found") No newline at end of file