Ejemplo n.º 1
0
    def load_template(stream, configfile, ending=".vtpl"):
        if not configfile.endswith(ending):
            raise Exception("Template does not have vtpl ending")

        loader = airspeed.CachingFileLoader(os.path.dirname(os.path.abspath(configfile)))
        tpl = loader.load_template(configfile)
        merged_template = tpl.merge({}, loader)
        orig_file_name = configfile[:-1 * len(ending)]

        tpl_stream = StringIO(merged_template)
        print("Velocity Macro found!")
        print("Merging template to final configuration: ")
        print("------ final configuration begin ------")
        print(tpl_stream.getvalue())
        print("------ final configuration end ------")
        return Config.load_file(tpl_stream, orig_file_name)
Ejemplo n.º 2
0
def createLIP(name):
    dataLIP = {
        'learner': {
            'id':
            'LIP_' + name,
            'first_name':
            name,
            'last_name':
            'x-none',
            'gender':
            'x-none',
            'email':
            'x-none',
            'preferences': [{
                'id': 'sc_easy',
                'value': '0.0'
            }, {
                'id': 'sc_medium',
                'value': '0.0'
            }, {
                'id': 'sc_difficult',
                'value': '0.0'
            }, {
                'id': 'mc_easy',
                'value': '0.0'
            }, {
                'id': 'mc_medium',
                'value': '0.0'
            }, {
                'id': 'mc_difficult',
                'value': '0.0'
            }, {
                'id': 'txt_easy',
                'value': '0.0'
            }, {
                'id': 'txt_medium',
                'value': '0.0'
            }, {
                'id': 'txt_difficult',
                'value': '0.0'
            }, {
                'id': 'order_easy',
                'value': '0.0'
            }, {
                'id': 'order_medium',
                'value': '0.0'
            }, {
                'id': 'order_difficult',
                'value': '0.0'
            }, {
                'id': 'asso_easy',
                'value': '0.0'
            }, {
                'id': 'asso_medium',
                'value': '0.0'
            }, {
                'id': 'asso_difficult',
                'value': '0.0'
            }, {
                'id': 'fact_easy',
                'value': '0.0'
            }, {
                'id': 'fact_medium',
                'value': '0.0'
            }, {
                'id': 'fact_difficult',
                'value': '0.0'
            }],
            'ts':
            '0',
            'activities': [{
                'topic': 'x-none',
                'subtopic': 'x-none',
                'ref': 'x-none',
                'status': 'x-none',
                'datetime': 'x-none'
            }]
        }
    }
    loader = airspeed.CachingFileLoader("../templates")
    t = loader.load_template("template_lip.vm")
    lip = t.merge(dataLIP, loader=loader)
    return lip
Ejemplo n.º 3
0
def keyw_main(opmoptn, opmsys):
    """OPMRUN Keyword Generation Utility

    OPM Flow Keyword Generation Utility is a Graphical User Interface ("GUI") program for the Open Porous Media ("OPM")
    Flow simulator

    This module generates input decks based of the keywords available for the simulator and users the Apache Velocity
    Template Language ("VTL") for the templates. VTL is a common templating language used by many programming editors,
    and therefore the templates can also be used directly with an editor provided the editor supports VTL. The Python
    airspeed module is used to parse the templates and the key templates are comparable to the examples depicted in the
    OPM Flow Manual.

    This is the main display GUI module for the OPM Keyword Generator program. The window object, window1, is the main
    global window object for other routines to access in this module.

    Parameters
    ----------
    opmoptn; dict
        A dictionary containing the OPMRUN default parameters
    opmsys : dict
        A dictionary containing the OPMRUN system parameters

    Returns
    -------
    Nothing
    """

    # ------------------------------------------------------------------------------------------------------------------
    # Initialize
    # ------------------------------------------------------------------------------------------------------------------
    set_gui_options()
    keywdir = opmoptn['opm-keywdir']
    patherr = keyw_check_directory(keywdir)

    if patherr:
        keywdir = Path(Path().absolute()).joinpath('opmvtl')
        patherr = keyw_check_directory(keywdir)

        if patherr:
            sg.popup_error('Error in "keyw_main" Module \n',
                          'Cannot Find Keyword Template Directory: \n \n' + str(keywdir) + '\n',
                          'Please Set Keyword Template Directory',
                          no_titlebar=False, grab_anywhere=False, keep_on_top=True)

            keywdir = sg.popup_get_folder('Set Keyword Template Directory', default_path=str(Path().absolute()),
                                        initial_folder=str(Path().absolute()),
                                        no_titlebar=False, grab_anywhere=False, keep_on_top=True)
            #
            # Process Cancel with Return to OPMRUN Main
            #
            if keywdir is None:
                return ()
            #
            # Process Directory
            #
            patherr = keyw_check_directory(keywdir)
            if patherr:
                sg.popup_error('Error in "keyw_main" Module RUNSPEC Directory Missing: \n ',
                              str(keywdir) + '\n',
                              'Does Not Contain Template Directories - Process Stopped',
                              no_titlebar=False, grab_anywhere=False, keep_on_top=True)
                return ()


    opmoptn['opm-keywdir'] = keywdir
    text = sg.popup_ok ('Using Keyword Template Directory \n \n' + str(keywdir) + '\n ',
                        no_titlebar=False, grab_anywhere=False, keep_on_top=True)
    if text == sg.WIN_CLOSED:
        return ()

    filetype = 'OPM FLOW SIMULATION FILE'
    helptext = (
            'OPM Flow Input Keyword Generation Utility is a Graphical User Interface ("GUI") program for the '
            'Open Porous Media ("OPM") Flow simulator \n' +
            '\n'
            'This module generates input decks based of the keywords available for the simulator and users the ' +
            'Apache Velocity Template Language ("VTL") for the templates. VTL is a common templating language ' +
            'used by many programming editors, and therefore the templates can also be used directly with an ' +
            'editor provided the editor supports VTL. The Python airspeed module is used to parse the templates ' +
            'and the key templates are comparable to the examples depicted in the OPM Flow Manual. \n'
            '\n'
            'The "Keyword Filter" button allows for the filtering of the various keywords in the selected ' +
            'section, including being able to list all the keywords available for all sections. Clicking on a ' +
            'keyword will result in the keyword being "pasted" into the Deck element. This element is editable ' +
            'by simply clicking anywhere in the element and making changes. \n'
            '\n'
            'The "Clear" button will will clear the Deck element of all text, and the "Copy" button will copy ' +
            'the text in the Deck element to the clipboard from which you can paste the text in your chosen  ' +
            'editor. The text can also be save saved to a file by selecting the "Save" button \n' +
            '\n'
            'See the OPM Flow manual for further information. \n')
    helptemp = (
            'Velocity Template Language \n' +
            '\n'
            'The Velocity Template Language (VTL) is used to embed dynamic elements within what would otherwise ' +
            'be static templates. By using VTL it is possible to interact with the user, calculate values, ' +
            'incorporate conditional logic, and much more. \n' +
            '\n' +
            'Directives \n' +
            'Directives are script elements in the Velocity Template Language that can be used to manipulate ' +
            'the output generated by the Velocity engine.Brief summaries of the standard VTL directives are ' +
            'included below. For a more detailed description, refer to the Velocity User Guide on the Apache ' +
            'website. \n' +
            '\n' +
            'Comment Directive \n' +
            'Like most programming languages, VTL includes constructs for inserting descriptive text comments ' +
            'into a template.Both single-line and multi-line (block) comments are supported. A single - line ' +
            'comment starts with  ## and only lasts until the end of the line. The following are examples of ' +
            'single-line comments: \n' +
            '\n' +
            '                            This is not a comment.  ## This is a comment \n' +
            '                            ## This whole line is a comment \n' +
            '\n' +
            'Multi-line comments are indicated by a start (  # *) and end comment indicator (*#). ' +
            'For example: \n' +
            '\n' +
            '                           This text is outside of the comment block.It will be processed by the \n' +
            '                           template engine \n' +
            '                           #* \n' +
            '                              This text is inside the comment block \n' +
            '                              Therefore it will be ignored by the template engine \n' +
            '                           *# \n' +
            '                           Back outside the comment block.This text will be processed \n' +
            '\n' +
            'Set Directive (#set) \n' +
            'One  of the most basic VTL directives is the  # set directive. It is used to assign a value to ' +
            'either a variable reference or a property reference. For example, the following are all valid  ' +
            '# set statements: \n' +
            '\n' +
            '                          $set ($ANS = "Yes") \n' +
            '                          #srt ($YearStart = 2020) \n' +
            '\n' +
            'Conditional Directives(#if/#elseif/#else) \n' +
            'Velocity allows for the optional inclusion of text through the use of the conditional  #if ' +
            'directive. The statement is considered true if it is passed; that is a boolean variable whose ' +
            'value is true, an expression which evaluates to true, and an object which is not null. The ' +
            'following code illustrates these three cases: \n' +
            '\n' +
            '                          #set ( $test = "true" )                           ## boolean variable \n' +
            '                          #if ( $test ) \n' +
            '                          This text is processed. \n' +
            '                          #end \n' +
            '\n' +
            '                          #if ($Year < $YearEnd)                            ## boolean expression \n' +
            '                          $Year = $Year + 1 \n' +
            '                          #end \n' +
            '\n' +
            '                          #set ( $ANS = "Yes") \n' +
            '                          #if ( $Ans )                                       ## non-null object \n' +
            '                          This text is processed. \n' +
            '                          #end \n' +
            '\n' +
            'In addition, Velocity supports the logical AND ( & &), OR( | |) and NOT(!) operators, as well as ' +
            'standard relational operators  such as equivalence( ==), greater than( >) and less than( <). Refer ' +
            'to the Velocity User"s Guide for more information. \n' +
            '\n' +
            'Loop Directive (# foreach) \n' +
            'The #foreach directive provides a way to loop over a template segment once for each object in a ' +
            'list of objects. For example, the following template code: \n' +
            '\n' +
            '                          #foreach ( $Year in [$YearStart .. $YearEnd] ) \n' +
            '                          RPTSCHED \n' +
            '                          WELLS=2     WELSPECS      CPU=2      FIP=2                        /\n' +
            '\n' +
            '                          DATES \n' +
            '                          1  JAN   $Year  / \n' +
            '                          / \n' +
            '\n' +
            'Include Directive (#include) \n' +
            'The # include directive is used to import a local file at the location where the #include ' +
            'directive is encountered. The contents of the file are not parsed by the template engine, but just ' +
            'included, for example: \n' +
            '\n' +
            '                          #include ("WCONPROD.vm") \n' +
            '                          #include ("WCONINJE.vm") \n' +
            '\n' +
            'Parse Directive (#parse) \n' +
            'The #parse directive is similar to the #include directive, but rather than importing a static text ' +
            'file, the imported file is also parsed by the template engine, for example: \n' +
            '\n' +
            '                          #include ("SCHEDULE.vm") \n' +
            '\n' +
            'Will parse all the directives in the SCHEDULE.vm template \n' +
            '\n' +
            'Stop Directive (#stop) \n' +
            'The #stop directive will halt template processing by the template engine. This is useful for ' +
            'debugging during template design. \n' +
            '\n' +
            'Macro Directive (#macro) \n' +
            'The #macro directive provides an easy method of defining repeated segments in a template. Here is ' +
            'a simple example: \n' +
            '\n' +
            '                          #macro (datemacro) \n' +
            '                          This a Test Macro \n' +
            '                          #end \n' +
            'The call to macro is: \n' +
            '                          datemacro \n' +
            '                          datemacro \n' +
            '\n')
    #
    #  Print opmoptn dictionary if Requested
    #
    debug = False
    if debug:
        print_dict('opmoptn', opmoptn, option='debug')
    #
    # Get Keyword Templates
    #
    keyall   = []
    keyfiles = dict()
    keylist  = []
    keywords = dict()

    keyw_get_keywords(keywdir, 'HEADER'  , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'GLOBAL'  , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'RUNSPEC' , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'GRID'    , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'EDIT'    , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'PROPS'   , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'SOLUTION', keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'SUMMARY' , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'SCHEDULE', keywords, keylist, keyfiles)

    if debug:
        print_dict('keyfiles', keyfiles, option='debug')
    #
    # Make ALL Keyword List
    #
    keylist.sort()
    keywords['ALL'] = list(keylist)
    #
    # Get DATA, Models and USER Keyword List
    #
    keyw_get_keywords(keywdir, 'DATA'  , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'MODELS', keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'USER'  , keywords, keylist, keyfiles)
    if debug:
        print_dict('keyfiles', keyfiles, option='debug')
    #
    # Set Initial Keyword List to Display
    #
    keylist = 'GLOBAL'
    
    # ------------------------------------------------------------------------------------------------------------------
    # Define Display Window
    # ------------------------------------------------------------------------------------------------------------------
    menu  = [['File', ['&Open', '&Save', '&Properties', 'E&xit']],
             ['Edit', ['Cut', 'Copy', 'Paste', 'Select All','Undo'], ],
             ['Generate', ['RUNSPEC', 'GRID', 'EDIT', 'PROPS', 'SUMMARY', 'SOLUTION', 'SCHEDULE'],],
             ['Help', ['Keyword Help', 'Template Help']],]

    width = 10
    layout = [
        [sg.Menu(menu, tearoff=False, pad=(200,1))],
        [sg.Button('HEADER'  , size=(width, None), key='_header_'),
         sg.Button('GLOBAL'  , size=(width, None), key='_global_'),
         sg.Button('RUNSPEC' , size=(width, None), key='_runspec'),
         sg.Button('GRID'    , size=(width, None), key='_grid_'),
         sg.Button('EDIT'    , size=(width, None), key='_edit_'),
         sg.Button('PROPS'   , size=(width, None), key='_props_'),
         sg.Button('SOLUTION', size=(width, None), key='_solution_'),
         sg.Button('SUMMARY' , size=(width, None), key='_summary_'),
         sg.Button('SCHEDULE', size=(width, None), key='_schedule_'),
         sg.Button('ALL'     , size=(width, None), key='_all_')],

        [sg.Button('DATA'    , size=(width, None), key='_data_'),
         sg.Button('MODELS'  , size=(width, None), key='_models_'),
         sg.Button('USER'    , size=(width, None), key='_user_')],

        [sg.Text('')],

        [sg.Listbox(values=keywords[keylist], size=(18, 40), font=(opmoptn['output-font'], opmoptn['output-font-size']),
                    right_click_menu=['Template', ['Template', 'Template Help']],
                    enable_events=True, key='_keylist_'),
         sg.Multiline(size=(132, 42), font=(opmoptn['output-font'], opmoptn['output-font-size']), do_not_clear=True,
                      right_click_menu= ['', ['Cut', 'Copy',  'Delete', 'Paste', 'Redo', 'Select All', 'Undo']],
                      key='_deckinput_')],

        [sg.Text('')],

        [sg.Button('Clear', key='_clear_'),
         sg.Button('Copy' , tooltip='Copy to Clipboard', key='_copy_' ),
         sg.Button('Load' , tooltip='Load a DATA file', key='_load_' ),
         sg.Button('Help' , key='_help_' ),
         sg.Button('Save' , key='_save_' ),
         sg.Exit()]
    ]

    window1 = sg.Window('OPMRUN Keyword Generation Utility', no_titlebar=False, grab_anywhere=False,
                        layout=layout, finalize=True)
    # Clipboard Operations Setup
    mline:sg.Multiline = window1['_deckinput_']
    # Activate Undo Option Ctrl+Z
    deckinput = window1['_deckinput_'].Widget
    deckinput.configure(undo=True)

    # ------------------------------------------------------------------------------------------------------------------
    #   Define GUI Event Loop, Read Buttons, and Make Callbacks etc. Section
    # ------------------------------------------------------------------------------------------------------------------
    while True:
        #
        # Read the Window and Process
        #
        event, values = window1.read()
        window_debug(event, 'values', values, False)
        #
        # Pre-Process Menu Generate Section to Use Keywords Section
        #
        if event in ['RUNSPEC', 'GRID', 'EDIT', 'PROPS', 'SUMMARY', 'SOLUTION', 'SCHEDULE']:
            values['_keylist_'] = [event]
            event               = '_keylist_'
        #
        # Clear
        #
        if event == '_clear_':
            window1['_deckinput_'].update('')
            continue
        #
        # Copy
        #
        elif event == '_copy_':
            copy_to_clipboard(window1['_deckinput_'].get())
            sg.popup_timed('Deck Copied to Clipboard', no_titlebar=False, grab_anywhere=False, keep_on_top=True)
            continue
        #
        # Exit
        #
        elif event == 'Exit':
            text = sg.popup_yes_no('Exit Keyword Generation?', title='OPMRUN Keyword Generation Utility',
                                   no_titlebar=False, grab_anywhere=False, keep_on_top=True)
            if text == 'Yes':
                break
            else:
                continue
        elif event == sg.WIN_CLOSED:
            break
        #
        # File Name
        #
        elif event == '_deckfile_':
            continue
        #
        # Help
        #
        elif event in ['_help_', 'Keyword Help']:
            opm_popup('Keyword Generator Help', helptext, 22)
            continue
        #
        # Keywords
        #
        elif event == '_keylist_':
            if not values['_keylist_']:
                continue

            key = str(values['_keylist_'][0])
            tempdirc = Path(keyfiles[key]).parents[0]
            tempkey  = Path(keyfiles[key]).name
            if debug:
                sg.Print(key)
                sg.Print(keyfiles[key])
                sg.Print(tempdirc)
                sg.Print(tempkey)
            #
            # Keyword
            #
            templates = airspeed.CachingFileLoader(tempdirc)
            template  = templates.load_template(tempkey)
            #
            # Process Keyword Options
            #
            keyitems = keyw_get_items(key)
            (status, file) = keyw_get_file(key)
            if status == 'Cancel':
                continue

            if debug:
                print_dict('opmoptn', opmoptn, option='debug')

            date = datetime.now().strftime('%d-%b-%Y')
            time = datetime.now().strftime('%H:%M:%S')
            try:
                text= template.merge({'FileType' : filetype, 'Date'     : str(date),
                                                             'Time'     : str(time),
                                                             'Node'     : opmsys['node'],
                                                             'OSName'   : opmsys['system'],
                                                             'OSLevel'  : opmsys['version'],
                                                             'OSArch'   : opmsys['machine'],
                                                             'Ans'      : keyitems['ans'],
                                                             'Author1'  : opmoptn ['opm-author1'],
                                                             'Author2'  : opmoptn ['opm-author2'],
                                                             'Author3'  : opmoptn ['opm-author3'],
                                                             'Author4'  : opmoptn ['opm-author4'],
                                                             'Author5'  : opmoptn ['opm-author5'],
                                                             'Comment'  : keyitems['comment'    ],
                                                             'File'     : file,
                                                             'FileName' : keyitems['filename'   ],
                                                             'FilePath' : keyitems['filepath'   ],
                                                             'SumOpt01' : keyitems['sumopt01'   ],
                                                             'SumOpt02' : keyitems['sumopt02'   ],
                                                             'SumOpt03' : keyitems['sumopt03'   ],
                                                             'SumOpt04' : keyitems['sumopt04'   ],
                                                             'SumOpt05' : keyitems['sumopt05'   ],
                                                             'SumOpt06' : keyitems['sumopt06'   ],
                                                             'SumOpt07' : keyitems['sumopt07'   ],
                                                             'SumOpt08' : keyitems['sumopt08'   ],
                                                             'SumOpt09' : keyitems['sumopt09'   ],
                                                             'SumOpt10' : keyitems['sumopt10'   ],
                                                             'SumOpt11' : keyitems['sumopt11'   ],
                                                             'Option'   : keyitems['step'       ],
                                                             'Schedule' : keyitems['sch'        ],
                                                             'YearStart': keyitems['yearstr'    ],
                                                             'YearEnd'  : keyitems['yearend'    ]},
                                                             loader=templates)
                copy_to_clipboard(text)
                keyw_clipboard_operation('Paste', window1, mline)
            except Exception as error:
                sg.popup_error('Error Processing Keyword Template: ' + str(key) + '\n  \n' + str(error),
                              no_titlebar=False, grab_anywhere=False, keep_on_top=True)
            continue
        #
        # Keyword Template Filter Buttons
        #
        elif event in ['_header_'  , '_global_', '_runspec', '_grid_'  , '_edit_', '_props_', '_solution_', '_summary_',
                       '_schedule_', '_all_'   , '_data_'  , '_models_', '_user_']:
            templates = event.replace('_', '').upper()
            window1['_keylist_'].update(keywords[templates])
            continue
        #
        # Load OPM Flow Input File
        #
        if event in ['_load_', 'Open']:
            keyw_load_file(window1)
            continue
        #
        # Properties
        #
        elif event == 'Properties':
            print_dict('OPMOPTN', opmoptn, option='popup')
            continue
        #
        # Right Click Menu Event
        #
        if event in ['Cut', 'Copy', 'Delete', 'Paste', 'Redo', 'Select All', 'Undo']:
            keyw_clipboard_operation(event, window1, mline)
            continue
        #
        # Save
        #
        elif event in ['_save_', 'Save']:
            keyw_save_keywords(window1['_deckinput_'].get())
            continue
        #
        # Template
        #
        elif event == 'Template':
            key = None
            try:
                key = str(values['_keylist_'][0])
                tempname = Path(keyfiles[key])
                tempfile = open(tempname, "r")
                window1['_deckinput_'].update('')
                window1['_deckinput_'].update(tempfile.read())
                tempfile.close()
            except Exception as error:
                sg.popup_error('Error Displaying Velocity Template Source: ' + str(key) + '\n  \n' + str(error),
                              no_titlebar=False, grab_anywhere=False, keep_on_top=True)
                continue
            continue
        #
        # Template Help
        #
        #
        elif event == 'Template Help':
            opm_popup('Keyword Generator Template Help', helptemp, 22)
            continue
    #
    # Define Post Processing Section
    #
    ans = sg.popup_yes_no('Do You Wish to Save the Keyword to File?', no_titlebar=False, grab_anywhere=False,
                          keep_on_top=True)
    if ans == 'Yes':
        keyw_save_keywords(window1['_deckinput_'].get())

    window1.Close()
    sg.popup_ok('Keyword Generation Processing Complete', no_titlebar=False, grab_anywhere=False, keep_on_top=True)
Ejemplo n.º 4
0
def keyw_main(**opmoptn):
    """
    This is the main display GUI module for the OPM Keyword Generator program. The window object, window1, is the main
    global window object for other routines to access in this module.
    """
    keywdir = opmoptn['opm-keywdir']
    try:
        pathchk = Path(keywdir).joinpath('02_RUNSPEC')

    except Exception as error:
        patherr = True
        pass

    if pathchk.exists():
        patherr = False
    else:
        patherr = True

    if patherr:
        sg.PopupError('Error in "keyw_main" Module \n',
                      'Cannot Find Keyword Template Directory: \n \n' + str(keywdir) + '\n',
                      'Please Set Keyword Template Directory',
                      no_titlebar=True, grab_anywhere=True, keep_on_top=True)

        keywdir = sg.PopupGetFolder('Set Keyword Template Directory',  default_path=str(os.getcwd()),
                                    initial_folder=str(os.getcwd()),
                                    no_titlebar=True, grab_anywhere=True, keep_on_top=True)

        try:
            pathchk = Path(keywdir).joinpath('02_RUNSPEC')

        except Exception as error:
            patherr = True

        if pathchk.exists():
            patherr = False
        else:
            patherr = True

        if patherr:
            sg.PopupError('Error in "keyw_main" Module RUNSPEC Directory Missing: \n ',
                  str(pathchk) + '\n',
                  'Does Not Contain Template Directories - Process Stopped',
                  no_titlebar=True, grab_anywhere=True, keep_on_top=True)
            return()

    sg.PopupOK('Using Keyword Template Directory \n \n' + str(keywdir) + '\n ',
                           no_titlebar=True, grab_anywhere=True, keep_on_top=True)

    filetype = 'OPM FLOW SIMULATION FILE'
    helptext = (
                'OPM Flow Input Keyword Generation Utility is a Graphical User Interface ("GUI") program for the '
                'Open Porous Media ("OPM") Flow simulator \n' +
                '\n'
                'This module generates input decks based of the keywords available for the simulator and users the '  +
                'Apache Velocity Template Language ("VTL") for the templates. VTL is a common templating language '   +
                'used by many programming editors, and therefore the templates can also be used directly with an '    +
                'editor provided the editor supports VTL. The Python airspeed module is used to parse the templates ' +
                'and the key templates are comparable to the examples depicted in the OPM Flow Manual. \n'
                '\n'
                'The "Keyword Filter" button allows for the filtering of the various keywords in the selected '       +
                'section, including being able to list all the keywords available for all sections. Clicking on a '   +
                'keyword will result in the keyword being "pasted" into the Deck element. This element is editable '  +
                'by simply clicking anywhere in the element and making changes. \n'
                '\n'
                'The "Clear" button will will clear the Deck element of all text, and the "Copy" button will copy '   +
                'the text in the Deck element to the clipboard from which you can paste the text in your chosen  '    +
                'editor. The text can also be save saved to a file by selecting the "Save" button \n'                 +
                '\n'
                'See the OPM Flow manual for further information. \n')
    helptemp = (
                'Velocity Template Language \n' +
                '\n'
                'The Velocity Template Language (VTL) is used to embed dynamic elements within what would otherwise ' +
                'be static templates. By using VTL it is possible to interact with the user, calculate values, '      +
                'incorporate conditional logic, and much more. \n'                                                    +
                '\n'                                                                                                  +
                'Directives \n'                                                                                       +
                'Directives are script elements in the Velocity Template Language that can be used to manipulate '    +
                'the output generated by the Velocity engine.Brief summaries of the standard VTL directives are '     +
                'included below. For a more detailed description, refer to the Velocity User Guide on the Apache '    +
                'website. \n'                                                                                         +
                '\n'                                                                                                  +
                'Comment Directive \n'                                                                                +
                'Like most programming languages, VTL includes constructs for inserting descriptive text comments '   +
                'into a template.Both single-line and multi-line (block) comments are supported. A single - line '    +
                'comment starts with  ## and only lasts until the end of the line. The following are examples of '    +
                'single-line comments: \n'                                                                            +
                '\n'                                                                                                  +
                '                            This is not a comment.  ## This is a comment \n'                         +
                '                            ## This whole line is a comment \n'                                      +
                '\n'                                                                                                  +
                'Multi-line comments are indicated by a start (  # *) and end comment indicator (*#). '               +
                'For example: \n'                                                                                     +
                '\n'                                                                                                  +
                '                           This text is outside of the comment block.It will be processed by the \n' +
                '                           template engine \n'                                                       +
                '                           #* \n'                                                                    +
                '                              This text is inside the comment block \n'                              +
                '                              Therefore it will be ignored by the template engine \n'                +
                '                           *# \n'                                                                    +
                '                           Back outside the comment block.This text will be processed \n'            +
                '\n'                                                                                                  +
                'Set Directive (#set) \n'                                                                             +
                'One  of the most basic VTL directives is the  # set directive. It is used to assign a value to '     +
                'either a variable reference or a property reference. For example, the following are all valid  '     +
                '# set statements: \n'                                                                                +
                '\n' +
                '                          $set ($ANS = "Yes") \n'                                                    +
                '                          #srt ($YeareStart = 2020) \n'                                              +
                '\n'                                                                                                  +
                'Conditional Directives(#if/#elseif/#else) \n'                                                        +
                'Velocity allows for the optional inclusion of text through the use of the conditional  #if '         +
                'directive. The statement is considered true if it is passed; that is a boolean variable whose '      +
                'value is true, an expression which evaluates to true, and an object which is not null. The '         +
                'following code illustrates these three cases: \n'                                                    +
                '\n'                                                                                                  +
                '                          #set ( $test = "true" )                           ## boolean variable \n'  +
                '                          #if ( $test ) \n'                                                          +
                '                          This text is processed. \n'                                                +
                '                          #end \n'                                                                   +
                '\n'                                                                                                  +
                '                          #if ($Year < $YearEnd)                            ## boolean expression \n'+
                '                          $Year = $Year + 1 \n'                                                      +
                '                          #end \n'                                                                   +
                '\n'                                                                                                  +
                '                          #set ( $ANS = "Yes") \n'                                                   +
                '                          #if ( $Ans )                                       ## non-null object \n'  +
                '                          This text is processed. \n'                                                +
                '                          #end \n'                                                                   +
                '\n'                                                                                                  +
                'In addition, Velocty supports the logical AND ( & &), OR( | |) and NOT(!) operators, as well as '    +
                'standard relational operators  such as equivalence( ==), greater than( >) and less than( <). Refer ' +
                'to the Velocity User"s Guide for more information. \n'                                               +
                '\n'                                                                                                  +
                'Loop Directive (# foreach) \n'                                                                       +
                'The #foreach directive provides a way to loop over a template segment once for each object in a '    +
                'list of objects. For example, the following template code: \n'                                       +
                '\n'                                                                                                  +
                '                          #foreach ( $Year in [$YearStart .. $YearEnd] ) \n'                         +
                '                          RPTSCHED \n'                                                               +
                '                          WELLS=2     WELSPECS      CPU=2      FIP=2                        /\n'     +
                '\n'                                                                                                  +
                '                          DATES \n'                                                                  +
                '                          1  JAN   $Year  / \n'                                                      +
                '                          / \n'                                                                      +
                '\n'                                                                                                  +
                'Include Directive (#include) \n'                                                                     +
                'The # include directive is used to import a local file at the location where the #include '          +
                'directive is encountered. The contents of the file are not parsed by the template engine, but just ' +
                'included, for example: \n'                                                                           +
                '\n'                                                                                                  +
                '                          #include ("WCONPROD.vm") \n'                                               +
                '                          #include ("WCONINJE.vm") \n'                                               +
                '\n'                                                                                                  +
                'Parse Directive (#parse) \n'                                                                         +
                'The #parse directive is similar to the #include directive, but rather than importing a static text ' +
                'file, the imported file is also parsed by the template engine, for example: \n'                      +
                '\n'                                                                                                  +
                '                          #include ("SCHEDULE.vm") \n'                                               +
                '\n'                                                                                                  +
                'Will parse all the directives in the SCHEDULE.vm template \n'                                        +
                '\n'                                                                                                  +
                'Stop Directive (#stop) \n'                                                                           +
                'The #stop directive will halt template processing by the template engine. This is useful for '       +
                'debugging during template design. \n'                                                                +
                '\n'                                                                                                  +
                'Macro Directive (#macro) \n'                                                                         +
                'The #macro directive provides an easy method of defining repeated segments in a template. Here is '  +
                'a simple example: \n'                                                                                +
                '\n'                                                                                                  +
                '                          #macro (datemacro) \n'                                                     +
                '                          This a Test Macro \n'                                                      +
                '                          #end \n'                                                                   +
                'The call to macro is: \n'                                                                            +
                '                          datemacro \n'                                                              +
                '                          datemacro \n'                                                              +
                '\n'                                                                                                   )
    #
    #  Print opmoptn dictionary if Requested
    #
    debug    = False

    if debug:
        sg.Print('Dictionary Variable: opmoptn')
        for item in opmoptn:
            sg.Print("Key : {} , Value : {}".format(item, opmoptn[item]))
    #
    # Get Keyword Templates
    #
    keyall   = []
    keyfiles = dict()
    keylist  = []
    keywords = dict()

    keyw_get_keywords(keywdir, 'HEADER'  , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'GLOBAL'  , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'RUNSPEC' , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'GRID'    , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'EDIT'    , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'PROPS'   , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'SOLUTION', keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'SUMMARY' , keywords, keylist, keyfiles)
    keyw_get_keywords(keywdir, 'SCHEDULE', keywords, keylist, keyfiles)

    if debug:
        sg.Print('Dictionary Variable: keyfiles')
        for item in keyfiles:
            sg.Print("Key : {} , Value : {}".format(item, keyfiles[item]))
    #
    # Make ALL Keyword List
    #
    keylist.sort()
    keywords['ALL'] = list(keylist)
    #
    # Set Initial Keyword List to Display
    #
    keylist = 'GLOBAL'
    #
    # Define Display Window
    #
    mainwind = [
        [sg.Button('Keyword Filter', size=(15,None), key='_filter_'),
            sg.Radio('HEADER'  , 'optn01', key='_header_'  ),
            sg.Radio('GLOBAL'  , 'optn01', key='_global_'  , default=True),
            sg.Radio('RUNSPEC' , 'optn01', key='_runspec'  ),
            sg.Radio('GRID'    , 'optn01', key='_grid_'    ),
            sg.Radio('EDIT'    , 'optn01', key='_edit_'    ),
            sg.Radio('PROPS'   , 'optn01', key='_props_'   ),
            sg.Radio('SOLUTION', 'optn01', key='_solution_'),
            sg.Radio('SUMMARY' , 'optn01', key='_summary_' ),
            sg.Radio('SCHEDULE', 'optn01', key='_schedule_'),
            sg.Radio('ALL', 'optn01', key='_all_'     )],

        [sg.Listbox(values=keywords[keylist], size=(15, 40), font=('Courier', 9),
                    right_click_menu=['Template',  ['Template','Template Help']],
                    enable_events=True, key='_keylist_'),
            sg.Multiline(size=(132, 40), font=('Courier', 9), do_not_clear=True, key='_deckinput_')],

        [sg.Text('')],

        [sg.Button('Clear', key='_clear_'),
         sg.Button('Copy' , key='_copy_' ),
         sg.Button('Help' , key='_help_' ),
         sg.Button('Save' , key='_save_' ),
         sg.Button('Exit' , key='_exit_' )]
    ]

    window1 = sg.Window('OPMRUN Keyword Generation Utility',no_titlebar=False, grab_anywhere=True,
                        layout=mainwind, disable_close=False, finalize=True)
    #
    #   Define GUI Event Loop, Read Buttons, and Make Callbacks etc. Section
    #
    while True:
        #
        # Read the Window and Process
        #
        button, values = window1.Read()
        if debug:
            sg.Print('Buttons')
            sg.Print(button)
            sg.Print('Values')
            sg.Print(values)
        #
        # Get Main Window Location and Set Default Location for other Windows
        #
#        x = int((window0.Size[0] / 2) + window0.CurrentLocation()[0])
#        y = int((window0.Size[1] / 4) + window0.CurrentLocation()[1])
#        sg.SetOptions(window_location=(x, y))
        #
        # Clear
        #
        if button == '_clear_':
            window1.Element('_deckinput_').Update('')
            continue
        #
        # Copy
        #
        elif button == '_copy_':
            copy_to_clipboard(window1.Element('_deckinput_').Get())
            sg.PopupTimed('Deck Copied to Clipboard', no_titlebar=True, grab_anywhere=True, keep_on_top=True)
            continue
        #
        # File Name
        #
        elif button == '_deckfile_':
            continue
        #
        # Exit
        #
        elif button == '_exit_' or button is None:
            ans = sg.PopupYesNo('Exit Keyword Generation?',
                                no_titlebar=True, grab_anywhere=True, keep_on_top=True)
            if ans == 'Yes':
                break
        #
        # Help
        #
        elif button == '_help_':
            opm_popup(helptext, 22)
            continue
        #
        # Keywords
        #
        elif button == '_keylist_':
            key      = str(values['_keylist_'][0])
            tempdirc = Path(keyfiles[key]).parents[0]
            tempkey  = Path(keyfiles[key]).name
            if (debug):
                sg.Print(key)
                sg.Print(keyfiles[key])
                sg.Print(tempdirc)
                sg.Print(tempkey)
            #
            # Keyword
            #
            templates = airspeed.CachingFileLoader(tempdirc)
            template  = templates.load_template(tempkey)
            #
            # Process Keyword Options
            #
            keyitems       = keyw_get_items(key)
            (status, file) = keyw_get_file(key)
            if status == 'Cancel':
                continue

            if debug:
                sg.Print('Dictionary Variable: opmoptn')
                for item in opmoptn:
                    sg.Print("Key : {} , Value : {}".format(item, opmoptn[item]))

            date = datetime.now().strftime('%d-%b-%Y')
            time = datetime.now().strftime('%H:%M:%S')
            try:
                window1.Element('_deckinput_').Update(template.merge({'FileType' : filetype,
                                                                      'Date'     : str(date),
                                                                      'Time'     : str(time),
                                                                      'OSName'   : platform.system(),
                                                                      'OSLevel'  : platform.release(),
                                                                      'OSArch'   : platform.machine(),
                                                                      'Ans'      : keyitems['ans'],
                                                                      'Author1'  : opmoptn ['opm-author1'],
                                                                      'Author2'  : opmoptn ['opm-author2'],
                                                                      'Author3'  : opmoptn ['opm-author3'],
                                                                      'Author4'  : opmoptn ['opm-author4'],
                                                                      'Author5'  : opmoptn ['opm-author5'],
                                                                      'Comment'  : keyitems['comment'    ],
                                                                      'File'     : file,
                                                                      'FileName' : keyitems['filename'   ],
                                                                      'FilePath' : keyitems['filepath'   ],
                                                                      'Option'   : keyitems['step'       ],
                                                                      'Schedule' : keyitems['sch'        ],
                                                                      'YearStart': keyitems['yearstr'    ],
                                                                      'YearEnd'  : keyitems['yearend'    ]},
                                                                     loader = templates),
                                                          append=True, autoscroll=True)
            except Exception as error:
                sg.PopupError('Error Processing Keyword Template: ' + str(key) + '\n  \n' + str(error),
                              no_titlebar=True, grab_anywhere=True, keep_on_top=True)
            continue
        #
        # Keyword Filter
        #
        elif button == '_filter_':
            if values['_header_']:
                window1.Element('_keylist_').Update(keywords['HEADER'])

            if values['_global_']:
                window1.Element('_keylist_').Update(keywords['GLOBAL'])

            if values['_runspec']:
                window1.Element('_keylist_').Update(keywords['RUNSPEC'])

            if values['_grid_']:
                window1.Element('_keylist_').Update(keywords['GRID'])

            if values['_edit_']:
                window1.Element('_keylist_').Update(keywords['EDIT'])

            if values['_props_']:
                window1.Element('_keylist_').Update(keywords['PROPS'])

            if values['_solution_']:
                window1.Element('_keylist_').Update(keywords['SOLUTION'])

            if values['_summary_']:
                window1.Element('_keylist_').Update(keywords['SUMMARY'])

            if values['_schedule_']:
                window1.Element('_keylist_').Update(keywords['SCHEDULE'])

            if values['_all_']:
                window1.Element('_keylist_').Update(keywords['ALL'])
        #
        # Save
        #
        elif button == '_save_':
            keyw_save_keywords(window1.Element('_deckinput_').Get())
            continue
        #
        # Template
        #
        elif button == 'Template':
            try:
                key = str(values['_keylist_'][0])
                tempname = Path(keyfiles[key])
                tempfile = open(tempname, "r")
                window1.Element('_deckinput_').Update('')
                window1.Element('_deckinput_').Update(tempfile.read())
                tempfile.close()
            except Exception as error:
                sg.PopupError('Error Displaying Velocity Template Source: ' + str(key) + '\n  \n' + str(error),
                              no_titlebar=True, grab_anywhere=True, keep_on_top=True)
                continue
            continue
    #
    # Template Help
    #
    #
        elif button == 'Template Help':
            opm_popup(helptemp, 22)
            continue
    #
    # Define Post Processing Section
    #
    ans = sg.PopupYesNo('Do You Wish to Save the Keyword to File?',
                         no_titlebar=True, grab_anywhere=True, keep_on_top=True)
    if ans == 'Yes':
        keyw_save_keywords(window1.Element('_deckinput_').Get())

    window1.Close()
    sg.PopupOK('Keyword Generation Processing Complete',
               no_titlebar=True, grab_anywhere=True, keep_on_top=True)