Commit 4ab1bfec authored by carignani's avatar carignani
Browse files

prototype of webapp

parent a38b63b3
Loading
Loading
Loading
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