nopaque/web/app/results/views.py

143 lines
5.6 KiB
Python

from . import results
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):
'''
View to show metadate and details about on imported result file.
'''
result = Result.query.get_or_404(result_id)
if not (result.creator == current_user or current_user.is_administrator()):
abort(403)
return render_template('results/result_details.html.j2',
result=result,
title='Result Details')
@results.route('/<int:result_id>/inspect')
@login_required
def result_inspect(result_id):
'''
View to inspect one importe result file in a corpus analysis like interface
'''
display_options_form = DisplayOptionsForm(
prefix='display-options-form',
result_context=request.args.get('context', 20),
results_per_page=request.args.get('results_per_page', 30))
result = Result.query.get_or_404(result_id)
result_file_path = os.path.join(current_app.config['NOPAQUE_STORAGE'],
result.file[0].dir,
result.file[0].filename)
with open(result_file_path, 'r') as result_json:
result_json = json.load(result_json)
if not (result.creator == current_user or current_user.is_administrator()):
abort(403)
return render_template('results/result_inspect.html.j2',
display_options_form=display_options_form,
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'))