From 5095bc8404081e8ad29d396d3629fc4a8107fb38 Mon Sep 17 00:00:00 2001 From: lkrsnik Date: Mon, 22 Jan 2024 14:56:12 +0100 Subject: [PATCH] Multiple fixes listed in 2024-01-03 changelog --- app.py | 62 ++++---- static/css/style.css | 16 +- static/js/init.js | 71 +++++++-- templates/about.html | 84 +---------- templates/index.html | 333 +++++++++++++++++------------------------- templates/result.html | 82 ++--------- 6 files changed, 254 insertions(+), 394 deletions(-) diff --git a/app.py b/app.py index 0d32fbb..4b1bc84 100755 --- a/app.py +++ b/app.py @@ -14,6 +14,18 @@ from stark import run UPLOAD_FOLDER = 'uploads' ALLOWED_EXTENSIONS = {'conllu'} DAYS_BEFORE_DELETION = 1 +TABLE_COLUMNS2DISPLAYED_TABLE_COLUMNS = { + 'Tree': 'Tree', + 'Absolute frequency': 'Frequency', + 'Number of nodes': 'Number of nodes', + 'Head node': 'Head node', + 'Grew-match URL': 'Grew-match URL', + 'Order': 'Order', + 'MI': 'MI', + 'logDice': 'logDice', + 't-score': 't-score' +} +DISPLAYED_TABLE_COLUMNS2TABLE_COLUMNS = {v: k for k, v in TABLE_COLUMNS2DISPLAYED_TABLE_COLUMNS.items()} def create_app(): @@ -73,17 +85,10 @@ def create_app(): f.save(secure_filename(f.filename)) return 'file uploaded successfully' - @app.route('/about', methods=['GET']) def about(): return render_template('about.html') - - # @app.route('/result//download', methods=['GET']) - # def download_result(result_id): - # return - - @app.route('/result/', methods=['GET', 'POST']) def result(result_id): @@ -99,15 +104,16 @@ def create_app(): # TODO TEST VARYING SIZES OF TEXT IN TABLE return send_file(os.path.join('media', result_id), as_attachment=True, download_name='results.tsv') - order_by = request.args.get('order_by') + order_by_display = request.args.get('order_by') + order_by = DISPLAYED_TABLE_COLUMNS2TABLE_COLUMNS[order_by_display[:-1]] if order_by_display is not None else None order_type = request.args.get('order_type') with open(os.path.join('media', result_id), 'r') as rf: content = list(csv.reader(rf, delimiter='\t')) head = content[0] content_dict = {h: [] for h in head} - if order_by is not None and order_by[:-1] in head: - sort_id = head.index(order_by[:-1]) + if order_by is not None and order_by in head: + sort_id = head.index(order_by) if order_type == 'asc': # check if a number can be converted to float or int ordered_content = sorted(content[1:], key=lambda x: -1 * float(x[sort_id]) if x[sort_id].isnumeric() or re.match(r'^-?\d+(?:\.\d+)$', x[sort_id]) is not None else x[sort_id], reverse=True) @@ -120,11 +126,12 @@ def create_app(): for j, v in enumerate(row): content_dict[head[j]].append(v) - # content.sort(key=lambda x: x[1]) - a = request - print(result_id) - return render_template('result.html', head_row=head, content=content_dict) - + displayed_head = [TABLE_COLUMNS2DISPLAYED_TABLE_COLUMNS[col] for col in head if col in TABLE_COLUMNS2DISPLAYED_TABLE_COLUMNS] + displayed_content_dict = {} + for column, v in content_dict.items(): + if column in TABLE_COLUMNS2DISPLAYED_TABLE_COLUMNS: + displayed_content_dict[TABLE_COLUMNS2DISPLAYED_TABLE_COLUMNS[column]] = v + return render_template('result.html', head_row=displayed_head, content=displayed_content_dict) @app.route('/', methods=['GET', 'POST']) def index(): @@ -188,7 +195,7 @@ def create_app(): # TODO EXPAND NODE TYPE node_type_options = {'upos', 'form', 'lemma', 'upos', 'xpos', 'feats', 'deprel'} if len(node_type) == 0: - validation['node_type'] = 'Please provide information about node type.' + validation['node_type'] = 'Please select at least one node type.' return False for el in node_type: @@ -219,6 +226,7 @@ def create_app(): configs['complete_tree_type'] = True configs['dependency_type'] = 'labeled_trees' in form and form['labeled_trees'] == 'on' configs['node_order'] = 'fixed_order' in form and form['fixed_order'] == 'on' + configs['association_measures'] = 'association_measures' in form and form['association_measures'] == 'on' configs['label_whitelist'] = [] configs['root_whitelist'] = [] @@ -240,23 +248,19 @@ def create_app(): if configs['compare'] is not None: configs['other_input_path'] = configs['compare'] - ######################################## - #config = configparser.ConfigParser() - #config.read('config.ini') - - # configs = read_configs(config, args) - - configs['association_measures'] = False - configs['grew_match'] = 'grewmatch_patterns' in form and form['grewmatch_patterns'] == 'on' + configs['grew_match'] = True configs['depsearch'] = False name = ''.join(random.choices(string.ascii_uppercase + string.digits, k=60)) configs['output'] = os.path.join('media', name) - - run(configs) - # TODO DELETE STORED FILE AFTER PROCESSING + if len(validation) > 0: + return render_template('index.html', validation=validation) + try: + run(configs) + except Exception as e: + validation['general'] = 'Processing failed! Please recheck your settings.' + if len(validation) > 0: + return render_template('index.html', validation=validation) return redirect(url_for('result', result_id=name)) - # return send_file(configs['output'], as_attachment=True) - # return render_template('index.html') return render_template('index.html') return app diff --git a/static/css/style.css b/static/css/style.css index 258dd8f..b6090a7 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -74,4 +74,18 @@ td { text-align: center; border-right: solid 1px #bbbbbb; border-left: solid 1px #bbbbbb; -} \ No newline at end of file +} + +.validation-error { + display: block; + color: #F44336; + position: relative; + min-height: 18px; + font-size: 12px; +} + +@media only screen and (min-width: 993px) { + .container { + width: 60%; + } +} diff --git a/static/js/init.js b/static/js/init.js index 3d53689..dfa8df0 100644 --- a/static/js/init.js +++ b/static/js/init.js @@ -1,4 +1,55 @@ +// Global array to store input names +var globalInputList = ['tree_size_min', 'tree_size_max', 'file', 'association_measures', 'labeled_trees', 'node_type_upos', 'fixed_order', 'input_url', 'node_type_lemma', 'root_restriction', 'node_type_form']; + +// Function to store values to local storage +function storeValuesToLocalstorage() { + globalInputList.forEach(function(inputName) { + var inputElement = $('[name="' + inputName + '"]'); + + if (inputElement.length > 0) { + var inputType = inputElement.attr('type'); + if (inputType === 'text' | inputType === 'hidden') { + localStorage.setItem(inputName, inputElement.val()); + } else if (inputType === 'checkbox') { + localStorage.setItem(inputName, inputElement.prop('checked')); + } + } + }); +} + +// Function to read values from local storage +function readValuesFromLocalstorage() { + globalInputList.forEach(function(inputName) { + var inputElement = $('[name="' + inputName + '"]'); + + if (inputElement.length > 0) { + var inputType = inputElement.attr('type'); + if (inputType === 'text') { + var text_val = localStorage.getItem(inputName); + if (text_val !== '' & text_val !== null) { + // set label to active + $("label[for='" + inputElement.attr('id') + "']").addClass('active'); + } + inputElement.val(text_val); + + } else if (inputType === 'checkbox') { + var check_value = localStorage.getItem(inputName); + if (check_value !== null) { + inputElement.prop('checked', check_value === 'true'); + } + } + } + + }); + var tree_size_min = localStorage.getItem('tree_size_min') !== null ? localStorage.getItem('tree_size_min') : 2; + var tree_size_max = localStorage.getItem('tree_size_max') !== null ? localStorage.getItem('tree_size_max') : 3; + return [tree_size_min, tree_size_max] +} + + document.addEventListener("DOMContentLoaded", function(event) { + tree_size = readValuesFromLocalstorage() + var valuesForSlider = [2,3,4,5]; var format = { @@ -11,7 +62,7 @@ document.addEventListener("DOMContentLoaded", function(event) { }; var slider = document.getElementById('slider'); noUiSlider.create(slider, { - start: [2, 3], + start: [tree_size[0], tree_size[1]], connect: true, tooltips: true, step: 1, @@ -30,11 +81,15 @@ document.addEventListener("DOMContentLoaded", function(event) { }); // end of document ready $(document).ready(function(){ - $('#advanced-tree').hide(); - $('.input-field span.helper-text').hide(); - $('.input-field').bind('mouseenter', function(e) { - $(this).find('span.helper-text').show('fast') + $('.input-field input[type="checkbox"]').on('change', function() { + var isChecked = $('.input-field input[type="checkbox"]:checked').length > 0; + $('#node-type-error').hide(); }); + $('#submit-form input').on('change', function() { + $('#unknown-error').hide(); + }); + + $('#advanced-tree').hide(); var advancedTreeExpanded = false; $('#advanced-tree-expand').bind('click', function(e) { if (!advancedTreeExpanded){ @@ -46,10 +101,6 @@ document.addEventListener("DOMContentLoaded", function(event) { $('#advanced-tree').hide('fast'); $('#advanced-tree-expand i').text('add'); } - $(this).find('span.helper-text').show('fast') - }); - $('.input-field').bind('mouseleave', function(e) { - $(this).find('span.helper-text').hide('fast') }); }); @@ -66,6 +117,8 @@ document.addEventListener("DOMContentLoaded", function(event) { .attr("name", "tree_size_max") .attr("value", tree_size_max) .appendTo("#submit-form"); + + storeValuesToLocalstorage(); return true; }); })(jQuery); // end of jQuery name space diff --git a/templates/about.html b/templates/about.html index 8ddd673..3ea2d7d 100644 --- a/templates/about.html +++ b/templates/about.html @@ -3,7 +3,7 @@ - Starter Template - Materialize + STARK @@ -13,72 +13,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

@@ -95,27 +35,7 @@
Credits

Add some logos here?

- -
- - - - - - - - - - - - - - - - - -