mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-11-04 12:22:47 +00:00 
			
		
		
		
	Results import fixes and additions. Table creation rework.
This commit is contained in:
		@@ -0,0 +1,18 @@
 | 
			
		||||
from flask_wtf import FlaskForm
 | 
			
		||||
from werkzeug.utils import secure_filename
 | 
			
		||||
from wtforms import FileField, SubmitField, ValidationError
 | 
			
		||||
from wtforms.validators import DataRequired
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ImportResultsForm(FlaskForm):
 | 
			
		||||
    '''
 | 
			
		||||
    Form used to import one result json file.
 | 
			
		||||
    '''
 | 
			
		||||
    file = FileField('File', validators=[DataRequired()])
 | 
			
		||||
    submit = SubmitField()
 | 
			
		||||
 | 
			
		||||
    def validate_file(self, field):
 | 
			
		||||
        if not field.data.filename.lower().endswith('.json'):
 | 
			
		||||
            raise ValidationError('File does not have an approved extension: '
 | 
			
		||||
                                  '.json')
 | 
			
		||||
        field.data.filename = secure_filename(field.data.filename)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								web/app/results/tasks.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								web/app/results/tasks.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
from ..decorators import background
 | 
			
		||||
from ..models import Result
 | 
			
		||||
import os
 | 
			
		||||
import shutil
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@background
 | 
			
		||||
def delete_result(result_id, *args, **kwargs):
 | 
			
		||||
    app = kwargs['app']
 | 
			
		||||
    with app.app_context():
 | 
			
		||||
        result = Result.query.get(result_id)
 | 
			
		||||
        if result is None:
 | 
			
		||||
            return
 | 
			
		||||
        result_file_path = os.path.join(app.config['NOPAQUE_STORAGE'],
 | 
			
		||||
                                        result.file[0].dir)
 | 
			
		||||
        shutil.rmtree(result_file_path)
 | 
			
		||||
        result.delete()  # cascades down and also deletes ResultFile
 | 
			
		||||
@@ -1,12 +1,94 @@
 | 
			
		||||
from . import results
 | 
			
		||||
from ..models import Result
 | 
			
		||||
from flask import abort, render_template, current_app, request
 | 
			
		||||
from flask_login import current_user, login_required
 | 
			
		||||
from . import tasks
 | 
			
		||||
from .. import db
 | 
			
		||||
from ..corpora.forms import DisplayOptionsForm
 | 
			
		||||
from ..models import Result, ResultFile, User
 | 
			
		||||
from .forms import ImportResultsForm
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
from flask import (abort, render_template, current_app, request, redirect,
 | 
			
		||||
                   flash, url_for, make_response)
 | 
			
		||||
from flask_login import current_user, login_required
 | 
			
		||||
import json
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@results.route('/import_results', methods=['GET', 'POST'])
 | 
			
		||||
@login_required
 | 
			
		||||
def import_results():
 | 
			
		||||
    '''
 | 
			
		||||
    View to import one json result file. Uses the ImportReultFileForm.
 | 
			
		||||
    '''
 | 
			
		||||
    import_results_form = ImportResultsForm(prefix='add-result-file-form')
 | 
			
		||||
    if import_results_form.is_submitted():
 | 
			
		||||
        if not import_results_form.validate():
 | 
			
		||||
            return make_response(import_results_form.errors, 400)
 | 
			
		||||
        # Save the file
 | 
			
		||||
        # result creation only happens on file save to avoid creating a result
 | 
			
		||||
        # object in the db everytime by just visiting the import_results page
 | 
			
		||||
        result = Result(user_id=current_user.id)
 | 
			
		||||
        db.session.add(result)
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        if not (result.creator == current_user
 | 
			
		||||
                or current_user.is_administrator()):
 | 
			
		||||
            abort(403)
 | 
			
		||||
        dir = os.path.join(str(result.user_id),
 | 
			
		||||
                           'results',
 | 
			
		||||
                           'corpus_analysis_results',
 | 
			
		||||
                           str(result.id))
 | 
			
		||||
        abs_dir = os.path.join(current_app.config['NOPAQUE_STORAGE'], dir)
 | 
			
		||||
        abs_file_path = os.path.join(abs_dir,
 | 
			
		||||
                                     import_results_form.file.data.filename)
 | 
			
		||||
        os.makedirs(abs_dir)
 | 
			
		||||
        import_results_form.file.data.save(abs_file_path)
 | 
			
		||||
        # Saves all needed metadata entries in one json field
 | 
			
		||||
        with open(abs_file_path, 'r') as f:
 | 
			
		||||
            corpus_metadata = json.load(f)
 | 
			
		||||
        del corpus_metadata['matches']
 | 
			
		||||
        del corpus_metadata['cpos_lookup']
 | 
			
		||||
        result_file = ResultFile(
 | 
			
		||||
            result_id=result.id,
 | 
			
		||||
            dir=dir,
 | 
			
		||||
            filename=import_results_form.file.data.filename)
 | 
			
		||||
        result.corpus_metadata = corpus_metadata
 | 
			
		||||
        db.session.add(result_file)
 | 
			
		||||
        db.session.commit()
 | 
			
		||||
        flash('Result file added!', 'result')
 | 
			
		||||
        return make_response(
 | 
			
		||||
            {'redirect_url': url_for('results.results_overview')},
 | 
			
		||||
            201)
 | 
			
		||||
    return render_template('results/import_results.html.j2',
 | 
			
		||||
                           import_results_form=import_results_form,
 | 
			
		||||
                           title='Add corpus file')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@results.route('/')
 | 
			
		||||
@login_required
 | 
			
		||||
def results_overview():
 | 
			
		||||
    '''
 | 
			
		||||
    Shows an overview of imported results.
 | 
			
		||||
    '''
 | 
			
		||||
    # get all results of current user
 | 
			
		||||
    results = User.query.get(current_user.id).results
 | 
			
		||||
 | 
			
		||||
    def __p_time(time_str):
 | 
			
		||||
        # helper to convert the datetime into a nice readable string
 | 
			
		||||
        return datetime.strptime(time_str, '%Y-%m-%dT%H:%M:%S.%f')
 | 
			
		||||
    # convert results into a list of dicts to add the measier to list.js in
 | 
			
		||||
    # the template
 | 
			
		||||
    results = [dict(query=r.corpus_metadata['query'],
 | 
			
		||||
                    match_count=r.corpus_metadata['match_count'],
 | 
			
		||||
                    corpus_name=r.corpus_metadata['corpus_name'],
 | 
			
		||||
                    corpus_creation_date=__p_time(r.corpus_metadata['corpus_creation_date']),  # noqa
 | 
			
		||||
                    corpus_analysis_date=__p_time(r.corpus_metadata['corpus_analysis_date']),  # noqa
 | 
			
		||||
                    corpus_type=r.corpus_metadata['corpus_type'],
 | 
			
		||||
                    id=r.id)
 | 
			
		||||
               for r in results]
 | 
			
		||||
    return render_template('results/results.html.j2',
 | 
			
		||||
                           title='Imported Results',
 | 
			
		||||
                           # table=table,
 | 
			
		||||
                           results=results)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@results.route('/<int:result_id>/details')
 | 
			
		||||
@login_required
 | 
			
		||||
def result_details(result_id):
 | 
			
		||||
@@ -44,3 +126,17 @@ def result_inspect(result_id):
 | 
			
		||||
                           result=result,
 | 
			
		||||
                           result_json=result_json,
 | 
			
		||||
                           title='Result Insepct')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@results.route('/<int:result_id>/delete')
 | 
			
		||||
@login_required
 | 
			
		||||
def result_delete(result_id):
 | 
			
		||||
    result = Result.query.get_or_404(result_id)
 | 
			
		||||
    if not result.id == result_id:
 | 
			
		||||
        abort(404)
 | 
			
		||||
    if not (result.creator == current_user
 | 
			
		||||
            or current_user.is_administrator()):
 | 
			
		||||
        abort(403)
 | 
			
		||||
    tasks.delete_result(result_id)
 | 
			
		||||
    flash('Result deleted!')
 | 
			
		||||
    return redirect(url_for('results.results_overview'))
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user