diff --git a/app/main/forms.py b/app/main/forms.py index 23621bbb..64f1005e 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -25,6 +25,15 @@ class CreateCorpusForm(FlaskForm): title = StringField('Title', validators=[DataRequired(), Length(1, 32)]) +class EditCorpusFileForm(FlaskForm): + author = StringField('Author', validators=[DataRequired(), Length(1, 64)]) + corpus_file_id = IntegerField('', validators=[DataRequired()]) + publishing_year = IntegerField('Publishing year', + validators=[DataRequired()]) + submit = SubmitField() + title = StringField('Title', validators=[DataRequired(), Length(1, 64)]) + + class QueryForm(FlaskForm): query = TextAreaField('CQP Query', validators=[DataRequired(), (Length(1, 1024))]) diff --git a/app/main/views.py b/app/main/views.py index 29763e80..6d51008b 100644 --- a/app/main/views.py +++ b/app/main/views.py @@ -1,4 +1,4 @@ -from app.utils import background_delete_job, background_delete_corpus +from app.utils import background_delete_job from flask import (abort, current_app, flash, redirect, request, render_template, url_for, send_from_directory) from flask_login import current_user, login_required @@ -17,73 +17,42 @@ def index(): return render_template('main/index.html.j2', title='Opaque') -@main.route('/corpora/', methods=['GET', 'POST']) +@main.route('/corpora/new', methods=['POST']) +@login_required +def corpus_new(): + create_corpus_form = CreateCorpusForm() + if create_corpus_form.validate_on_submit(): + corpus = Corpus(creator=current_user, + description=create_corpus_form.description.data, + title=create_corpus_form.title.data) + db.session.add(corpus) + db.session.commit() + dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'], + str(corpus.user_id), + 'corpora', + str(corpus.id)) + try: + os.makedirs(dir) + except OSError: + flash('OSError!') + db.session.remove(corpus) + db.session.commit() + flash('Corpus created!') + return redirect(url_for('main.corpus', corpus_id=corpus.id)) + + +@main.route('/corpora/') @login_required def corpus(corpus_id): corpus = Corpus.query.get_or_404(corpus_id) - if not (corpus.creator == current_user - or current_user.is_administrator()): + if not (corpus.creator == current_user or current_user.is_administrator()): abort(403) - add_corpus_file_form = AddCorpusFileForm() - if add_corpus_file_form.validate_on_submit(): - filename = secure_filename(add_corpus_file_form.file.data.filename) - for corpus_file in corpus.files: - if filename == corpus_file.filename: - flash('File already registered to this corpus.') - return redirect(url_for('main.corpus', corpus_id=corpus_id)) - # Gather information to create new corpus file database entry - author = add_corpus_file_form.author.data - dir = os.path.join(str(corpus.user_id), 'corpora', str(corpus.id)) - file = add_corpus_file_form.file.data - publishing_year = add_corpus_file_form.publishing_year.data - title = add_corpus_file_form.title.data - # Save the file - file_dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'], - dir) - file.save(os.path.join(file_dir, filename)) - corpus_file = CorpusFile(author=author, - corpus=corpus, - dir=dir, - filename=filename, - publishing_year=publishing_year, - title=title) - db.session.add(corpus_file) - db.session.commit() - flash('Corpus file added!') - return redirect(url_for('main.corpus', corpus_id=corpus_id)) return render_template('main/corpora/corpus.html.j2', - add_corpus_file_form=add_corpus_file_form, + add_corpus_file_form=AddCorpusFileForm(), corpus=corpus, title='Corpus') -@main.route('/corpora//delete') -@login_required -def delete_corpus(corpus_id): - corpus = Corpus.query.filter_by(id=corpus_id).first() - delete_thread = threading.Thread(corpus.delete()) - delete_thread.start() - flash('Corpus has been deleted!') - return redirect(url_for('main.dashboard')) - - -@main.route('/corpora//download') -@login_required -def corpus_download(corpus_id): - corpus_file_id = request.args.get('corpus_file_id') - corpus_file = CorpusFile.query.get_or_404(corpus_file_id) - if not corpus_file.corpus_id == corpus_id: - abort(404) - if not (corpus_file.corpus.creator == current_user - or current_user.is_administrator()): - abort(403) - dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'], - corpus_file.dir) - return send_from_directory(as_attachment=True, - directory=dir, - filename=corpus_file.filename) - - @main.route('/corpora//analysis', methods=['GET', 'POST']) @login_required def corpus_analysis(corpus_id): @@ -119,6 +88,86 @@ def corpus_analysis(corpus_id): title='Corpus: ' + corpus.title) +@main.route('/corpora//delete') +@login_required +def corpus_delete(corpus_id): + corpus = Corpus.query.get_or_404(corpus_id) + if not (corpus.creator == current_user or current_user.is_administrator()): + abort(403) + delete_thread = threading.Thread(corpus.delete()) + delete_thread.start() + flash('Corpus has been deleted!') + return redirect(url_for('main.dashboard')) + + +@main.route('/corpora//files/new', methods=['POST']) +@login_required +def corpus_file_new(corpus_id): + corpus = Corpus.query.get_or_404(corpus_id) + if not (corpus.creator == current_user or current_user.is_administrator()): + abort(403) + add_corpus_file_form = AddCorpusFileForm() + if not add_corpus_file_form.validate_on_submit(): + abort(400) + file = add_corpus_file_form.file.data + filename = secure_filename(file.filename) + for corpus_file in corpus.files: + if filename == corpus_file.filename: + flash('File already registered to this corpus.') + return redirect(url_for('main.corpus', corpus_id=corpus_id)) + # Save the file + dir = os.path.join(str(corpus.user_id), 'corpora', str(corpus.id)) + file_path = os.path.join( + current_app.config['OPAQUE_STORAGE_DIRECTORY'], dir, filename + ) + file.save(file_path) + # Gather information to create new corpus file database entry + author = add_corpus_file_form.author.data + publishing_year = add_corpus_file_form.publishing_year.data + title = add_corpus_file_form.title.data + corpus_file = CorpusFile(author=author, + corpus=corpus, + dir=dir, + filename=filename, + publishing_year=publishing_year, + title=title) + db.session.add(corpus_file) + db.session.commit() + flash('Corpus file added!') + return redirect(url_for('main.corpus', corpus_id=corpus_id)) + + +@main.route('/corpora//files//delete') +@login_required +def corpus_file_delete(corpus_id, corpus_file_id): + corpus_file = CorpusFile.query.get_or_404(corpus_file_id) + if not corpus_file.corpus_id == corpus_id: + abort(404) + if not (corpus_file.corpus.creator == current_user + or current_user.is_administrator()): + abort(403) + delete_thread = threading.Thread(corpus_file.delete()) + delete_thread.start() + flash('Corpus file deleted!') + return redirect(url_for('main.corpus', corpus_id=corpus_id)) + + +@main.route('/corpora//files//download') +@login_required +def corpus_file_download(corpus_id, corpus_file_id): + corpus_file = CorpusFile.query.get_or_404(corpus_file_id) + if not corpus_file.corpus_id == corpus_id: + abort(404) + if not (corpus_file.corpus.creator == current_user + or current_user.is_administrator()): + abort(403) + dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'], + corpus_file.dir) + return send_from_directory(as_attachment=True, + directory=dir, + filename=corpus_file.filename) + + @main.route('/dashboard', methods=['GET', 'POST']) @login_required def dashboard(): @@ -155,29 +204,6 @@ def job(job_id): return render_template('main/jobs/job.html.j2', job=job, title='Job') -@main.route('/jobs//download') -@login_required -def job_download(job_id): - ressource_id = request.args.get('ressource_id') - ressource_type = request.args.get('ressource_type') - if ressource_type == 'input': - ressource = JobInput.query.get_or_404(ressource_id) - elif ressource_type == 'result': - ressource = JobResult.query.get_or_404(ressource_id) - else: - abort(400) - if not ressource.job_id == job_id: - abort(404) - if not (ressource.job.creator == current_user - or current_user.is_administrator()): - abort(403) - dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'], - ressource.dir) - return send_from_directory(as_attachment=True, - directory=dir, - filename=ressource.filename) - - @main.route('/jobs//delete') @login_required def delete_job(job_id): @@ -188,3 +214,35 @@ def delete_job(job_id): delete_thread.start() flash('Job has been deleted!') return redirect(url_for('main.dashboard')) + + +@main.route('/jobs//inputs//download') +@login_required +def job_input_download(job_id, job_input_id): + job_input = JobInput.query.get_or_404(job_input_id) + if not job_input.job_id == job_id: + abort(404) + if not (job_input.job.creator == current_user + or current_user.is_administrator()): + abort(403) + dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'], + job_input.dir) + return send_from_directory(as_attachment=True, + directory=dir, + filename=job_input.filename) + + +@main.route('/jobs//results//download') +@login_required +def job_result_download(job_id, job_result_id): + job_result = JobResult.query.get_or_404(job_result_id) + if not job_result.job_id == job_id: + abort(404) + if not (job_result.job.creator == current_user + or current_user.is_administrator()): + abort(403) + dir = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'], + job_result.dir) + return send_from_directory(as_attachment=True, + directory=dir, + filename=job_result.filename) diff --git a/app/models.py b/app/models.py index 962aee73..6322b2e0 100644 --- a/app/models.py +++ b/app/models.py @@ -468,9 +468,9 @@ class Corpus(db.Model): logger.warning('user_id: {}'.format(self.user_id)) logger.warning('id: {}'.format(self.id)) path = os.path.join(current_app.config['OPAQUE_STORAGE_DIRECTORY'], - self.user_id, + str(self.user_id), 'corpora', - self.id) + str(self.id)) logger.warning(path) try: logger.warning('Try to remove {}'.format(path)) diff --git a/app/templates/main/corpora/corpus.html.j2 b/app/templates/main/corpora/corpus.html.j2 index df302548..65491341 100644 --- a/app/templates/main/corpora/corpus.html.j2 +++ b/app/templates/main/corpora/corpus.html.j2 @@ -4,16 +4,17 @@

{{ corpus.title }}

{{ corpus.description }}

- - +