post/reporter/reporter_check_job_inputs.js

/* Contain the entire script within a function because REPORTER only has a single JavaScript realm
 * for the entire session. */
check_job_inputs();

/**
 * #AAW REPORTER check job inputs
 *
 * Performs the check of user inputs. REPORTER variables for KEYWORD_FILE and
 * DEFAULT_DIR/DEFAULT_JOB might already be defined if:
 * 1. They have been hardwired (possibly)
 * 2. They have been passed through as arguments in batch
 * 3. The template is being re-run.
 *
 * The template only needs one of KEYWORD_FILE or (DEFAULT_DIR and DEFAULT_JOB) to proceed.
 * By default, RESULTS_DIR and OUTPUT_DIR can be inferred from the keyword file location.
 * However, the user may wish to specify different locations for RESULTS_DIR and OUTPUT_DIR,
 * in which case these are configured by the subsequent `#AAW PRIMER job control GUI` item.
 * Depending on the user's preference, this script activates/deactivates that item.
 */
function check_job_inputs() {
    let template = Template.GetCurrent();

    /* Delete AAW_job_control_variables.csv in case it has data from previous runs */
    let reporter_temp = template.GetVariableValue(`REPORTER_TEMP`);
    if (reporter_temp == null || (reporter_temp != null && !File.IsDirectory(reporter_temp))) {
        LogError(`Could not find REPORTER_TEMP directory.`);
        Exit();
    }
    let f_csv_name = `${reporter_temp}/AAW_job_control_variables.csv`;
    if (File.Exists(f_csv_name)) {
        let success = File.Delete(f_csv_name);
        if (!success) {
            LogError(`Unable to delete existing variables file: ${f_csv_name}`);
            Exit();
        }
    }
    /* Replace it with an empty file so that `#AAW REPORTER read variables from PRIMER job control`
     * item always has something to read. */
    let f_csv = new File(f_csv_name, File.WRITE);
    f_csv.Close();

    /* By default, show PRIMER job control GUI */
    let show_job_control_gui = true;

    /* If we are running in batch, always skip job control GUI. Otherwise we check for inputs. */
    if (Batch()) {
        show_job_control_gui = false;
    } else {
        /* First check to see if we can find a keyword file. If we can't find an input model,
         * we'll definitely need to launch the job control GUI.
         * We check KEYWORD_FILE first, and then DEFAULT_DIR and DEFAULT_JOB.
         * We make sure they're updated to be consistent with each other.
         */
        let found_key_file = false;
        let keyword_file = template.GetVariableValue(`KEYWORD_FILE`);
        let default_dir;
        let default_job;
        if (keyword_file != null && File.Exists(keyword_file)) {
            found_key_file = true;
            /* Got a file, so set %KEYWORD_FILE%, %DEFAULT_DIR% and %DEFAULT_JOB% */
            let path_index = Math.max(keyword_file.lastIndexOf("/"), keyword_file.lastIndexOf("\\"));
            default_dir = keyword_file.substring(0, path_index);
            let filename = keyword_file.substring(path_index + 1);
            default_job = filename.substring(0, filename.lastIndexOf("."));

            /* Assign to REPORTER variables. Constructor will overwrite existing variable. */
            let default_dir_var = new Variable(
                template,
                `DEFAULT_DIR`,
                `Reporter default directory`,
                default_dir,
                `Directory`,
                false,
                false
            );
            let default_job_var = new Variable(
                template,
                `DEFAULT_JOB`,
                `Reporter default jobname`,
                default_job,
                `File(basename)`,
                false,
                false
            );
        } else {
            /* If KEYWORD_FILE doesn't exist, check DEFAULT_DIR and DEFAULT_JOB. */
            default_dir = template.GetVariableValue(`DEFAULT_DIR`);
            default_job = template.GetVariableValue(`DEFAULT_JOB`);

            if (default_dir != null && File.IsDirectory(default_dir) && default_job != null) {
                let possible_extensions = [
                    `k`,
                    `key`,
                    `kby`,
                    `k.gz`,
                    `key.gz`,
                    `kby.gz`,
                    `k.zip`,
                    `key.zip`,
                    `kby.zip`
                ];
                for (let ext of possible_extensions) {
                    keyword_file = `${default_dir}/${default_job}.${ext}`;
                    if (File.Exists(keyword_file)) {
                        found_key_file = true;

                        /* Assign to REPORTER variables. Constructor will overwrite existing variable. */
                        let keyword_file_var = new Variable(
                            template,
                            `KEYWORD_FILE`,
                            `Keyword file`,
                            keyword_file,
                            `File(absolute)`,
                            false,
                            true
                        );
                        break;
                    }
                }
            }
        }

        /* If we found the keyword file, check whether we should use defaults for RESULTS_DIR and
         * OUTPUT_DIR. Default OUTPUT_DIR is in subdirectory matching name of template. */

        let output_dir_name = template.filename.substring(0, template.filename.lastIndexOf(`.`));

        if (found_key_file) {
            let ans = Window.Question(
                `Automotive Assessments`,
                `By default, REPORTER will search for results in the same directory as the keyword file, ` +
                    `and write images and other files to a subdirectory named "${output_dir_name}".\n\n` +
                    `Proceed with these defaults (Yes)? Or configure directories in PRIMER (No).`
            );
            if (ans == Window.YES) {
                /* Default OUTPUT_DIR in subdirectory */
                let output_dir = `${default_dir}/${output_dir_name}`;

                /* If it doesn't already exist, check that we can create the output_dir */
                let output_dir_exists = true;
                if (!File.IsDirectory(output_dir)) {
                    let success = File.Mkdir(output_dir);
                    if (!success) {
                        output_dir_exists = false;
                        Window.Warning(
                            `Automotive Assessments`,
                            `Unable to create output directory. Please configure directories in PRIMER.`
                        );
                    }
                }

                if (output_dir_exists) {
                    show_job_control_gui = false;

                    /* Set default values for RESULTS_DIR and OUTPUT_DIR
                     * (constructor will overwrite existing variables). */
                    let results_dir_var = new Variable(
                        template,
                        `RESULTS_DIR`,
                        `Directory containing LS-DYNA results`,
                        `%DEFAULT_DIR%`,
                        `Directory`,
                        false,
                        true
                    );
                    let output_dir_var = new Variable(
                        template,
                        `OUTPUT_DIR`,
                        `Directory where images and other output files will be written`,
                        `%DEFAULT_DIR%/${output_dir_name}`,
                        `Directory`,
                        false,
                        true
                    );

                    /* Find T/HIS results files in RESULTS_DIR and set RESULTS_FILE_THIS */
                    let results_dir = default_dir;
                    let results_file_this = find_lsdyna_files(results_dir, default_job, `T/HIS`);
                    if (results_file_this == null) {
                        LogError(`Could not find T/HIS results files in results directory: ${results_dir}`);
                        results_file_this = ``;
                    }
                    let results_file_this_var = new Variable(
                        template,
                        `RESULTS_FILE_THIS`,
                        `Results file for T/HIS`,
                        results_file_this,
                        `Directory`,
                        false,
                        true
                    );
                }
            } else {
                /* If we are configuring directories using the PRIMER job control GUI, it's helpful
                 * to have a starting directory for RESULTS_DIR and OUTPUT_DIR. However, we only
                 * define them here if they don't exist at all, in case they have been manually
                 * defined on purpose. */
                let results_dir = template.GetVariableValue(`RESULTS_DIR`);
                if (results_dir == null) {
                    let results_dir_var = new Variable(
                        template,
                        `RESULTS_DIR`,
                        `Directory containing LS-DYNA results`,
                        `%DEFAULT_DIR%`,
                        `Directory`,
                        false,
                        true
                    );
                }
                let output_dir = template.GetVariableValue(`OUTPUT_DIR`);
                if (output_dir == null) {
                    let output_dir_var = new Variable(
                        template,
                        `OUTPUT_DIR`,
                        `Directory where images and other output files will be written`,
                        `%DEFAULT_DIR%/${output_dir_name}`,
                        `Directory`,
                        false,
                        true
                    );
                }
            }
        }
    }

    /* Activate or deactivate `#AAW PRIMER job control GUI` item depending on whether or not we
     * want to show it. Always deactivate `#AAW PRIMER user data GUI`, which will be optionally
     * generated by `#AAW REPORTER run PRIMER rerun T/HIS` item. */

    /* We will search for items with names beginning with an identifiable string. */
    let aaw_job_control_gui_str = `#AAW PRIMER job control GUI`;
    let aaw_user_data_gui_str = `#AAW PRIMER user data GUI`;

    /* Loop through all pages in the template, searching for relevant items. Break out of loop as
     * soon as we have found both items. */
    let pages = template.GetAllPages();
    let job_control_match = false;
    let user_data_match = false;
    for (let page of pages) {
        let items = page.GetAllItems();
        for (let item of items) {
            /* Acitvate or deactivate job control GUI */
            if (item.name.substring(0, aaw_job_control_gui_str.length) == aaw_job_control_gui_str) {
                item.active = show_job_control_gui;
                job_control_match = true;
            }
            /* Acitvate or deactivate job control GUI */
            if (item.name.substring(0, aaw_user_data_gui_str.length) == aaw_user_data_gui_str) {
                item.active = false;
                user_data_match = true;
            }
            if (job_control_match && user_data_match) break;
        }
        if (job_control_match && user_data_match) break;
    }
    if (!job_control_match) {
        LogError(`Could not find item "${aaw_job_control_gui_str}" to (de)activate it.`);
    }
    if (!user_data_match) {
        LogError(`Could not find item "${aaw_user_data_gui_str}" to deactivate it.`);
    }

    /* Regardless of whether we are showing the PRIMER job control GUI, set JOB_CONTROL to `Check`
     * in preparation for `#AAW T/HIS check and do assessment` item. This will be overridden by
     * the PRIMER job control GUI if it is shown and the user clicks `Cancel` (which would cause
     * an abort). */
    let job_control_var = new Variable(
        template,
        `JOB_CONTROL`,
        `Controls "Check", "Run", or "Skip" for various items, or "Abort" template generation entirely.`,
        `Check`,
        `String`,
        false,
        true
    );
}

/**
 * Searches a directory for filenames matching either Arup or LSTC filename conventions.
 * Searches for files in directory <dir> of type <file_type>, possibly containing
   <job_name>, and returns the first match in the priority lists below.
   @param {string} dir Directory to search
   @param {string} job_name Root filename to search for
   @param {string} file_type File type to search for (can be "PRIMER", "D3PLOT", "T/HIS", "OTF")
   @returns {?string}
   @example
   let absolute_filename = find_lsdyna_files("C:/my/results/directory", "job_001", "D3PLOT");
 */
function find_lsdyna_files(dir, job_name, file_type) {
    let filters = [];
    let filename;

    switch (file_type) {
        case "PRIMER":
            filters = [
                new RegExp("^" + job_name + ".key$"),
                new RegExp("^" + job_name + ".k$"),
                new RegExp("^" + job_name + ".*.key$"),
                new RegExp("^" + job_name + ".*.k$"),
                new RegExp(".*.key$"),
                new RegExp(".*.k$")
            ];

            break;

        case "D3PLOT":
            filters = [
                new RegExp("^" + job_name + ".ptf$"),
                new RegExp("^" + job_name + ".d3plot$"),
                new RegExp("^d3plot$"),
                new RegExp("^" + job_name + ".*.ptf$"),
                new RegExp("^" + job_name + ".*.d3plot$"),
                new RegExp(".*.ptf$"),
                new RegExp(".*.d3plot$")
            ];
            break;

        case "T/HIS":
            filters = [
                new RegExp("^" + job_name + ".thf$"),
                new RegExp("^" + job_name + ".d3thdt$"),
                new RegExp("^d3thdt$"),
                new RegExp("^" + job_name + ".*.thf$"),
                new RegExp("^" + job_name + ".*.d3thdt$"),
                new RegExp(".*.thf$"),
                new RegExp(".*.d3thdt$"),
                new RegExp("^" + job_name + ".binout.*$"),
                new RegExp("^binout.*$"),
                new RegExp("^" + job_name + ".*.binout.*$"),
                new RegExp(".*.binout.*$")
            ];
            break;

        case "OTF":
            filters = [
                new RegExp("^" + job_name + ".otf$"),
                new RegExp("^" + job_name + ".d3hsp$"),
                new RegExp("^d3hsp$"),
                new RegExp("^" + job_name + ".*.otf$"),
                new RegExp("^" + job_name + ".*.d3hsp$"),
                new RegExp(".*.otf$"),
                new RegExp(".*.d3hsp$")
            ];
            break;

        default:
            LogError(`Unexpected <file_type = "${file_type}" in function find_lsdyna_files.`);
            Exit();
            break;
    }

    let filestore = [];
    for (let filter of filters) {
        let filelist = File.FindFiles(dir, `*`, false);
        for (let file of filelist) {
            if (filter.test(file) == true) {
                filestore.push(file);
            }
        }
        if (filestore.length > 0) {
            filestore.sort();
            /* Pick first matching file and strip off rest of path */
            filename = filestore[0].substring(
                Math.max(filestore[0].lastIndexOf("/"), filestore[0].lastIndexOf("\\")) + 1
            );
            break;
        }
    }

    if (filestore.length == 0) return null;

    let absolute_filename = dir + "/" + filename;

    return absolute_filename;
}