mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-12-25 19:04:18 +00:00
add all files for last commit
This commit is contained in:
parent
5864aa653e
commit
5491cb184a
@ -55,7 +55,6 @@ class CreateTesseractOCRPipelineModelForm(ContributionBaseForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def validate_tesseract_model_file(self, field):
|
def validate_tesseract_model_file(self, field):
|
||||||
current_app.logger.warning(field.data.filename)
|
|
||||||
if not field.data.filename.lower().endswith('.traineddata'):
|
if not field.data.filename.lower().endswith('.traineddata'):
|
||||||
raise ValidationError('traineddata files only!')
|
raise ValidationError('traineddata files only!')
|
||||||
|
|
||||||
@ -80,7 +79,6 @@ class CreateSpaCyNLPPipelineModelForm(ContributionBaseForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def validate_spacy_model_file(self, field):
|
def validate_spacy_model_file(self, field):
|
||||||
current_app.logger.warning(field.data.filename)
|
|
||||||
if not field.data.filename.lower().endswith('.tar.gz'):
|
if not field.data.filename.lower().endswith('.tar.gz'):
|
||||||
raise ValidationError('.tar.gz files only!')
|
raise ValidationError('.tar.gz files only!')
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ def create_tesseract_ocr_pipeline_model():
|
|||||||
publisher_url=form.publisher_url.data,
|
publisher_url=form.publisher_url.data,
|
||||||
publishing_url=form.publishing_url.data,
|
publishing_url=form.publishing_url.data,
|
||||||
publishing_year=form.publishing_year.data,
|
publishing_year=form.publishing_year.data,
|
||||||
shared=False,
|
is_public=False,
|
||||||
title=form.title.data,
|
title=form.title.data,
|
||||||
version=form.version.data,
|
version=form.version.data,
|
||||||
user=current_user
|
user=current_user
|
||||||
@ -131,7 +131,7 @@ def toggle_tesseract_ocr_pipeline_model_public_status(tesseract_ocr_pipeline_mod
|
|||||||
tesseract_ocr_pipeline_model = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
|
tesseract_ocr_pipeline_model = TesseractOCRPipelineModel.query.get_or_404(tesseract_ocr_pipeline_model_id)
|
||||||
if not (tesseract_ocr_pipeline_model.user == current_user or current_user.is_administrator()):
|
if not (tesseract_ocr_pipeline_model.user == current_user or current_user.is_administrator()):
|
||||||
abort(403)
|
abort(403)
|
||||||
tesseract_ocr_pipeline_model.shared = not tesseract_ocr_pipeline_model.shared
|
tesseract_ocr_pipeline_model.is_public = not tesseract_ocr_pipeline_model.is_public
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return {}, 201
|
return {}, 201
|
||||||
|
|
||||||
@ -201,7 +201,7 @@ def create_spacy_nlp_pipeline_model():
|
|||||||
publisher_url=form.publisher_url.data,
|
publisher_url=form.publisher_url.data,
|
||||||
publishing_url=form.publishing_url.data,
|
publishing_url=form.publishing_url.data,
|
||||||
publishing_year=form.publishing_year.data,
|
publishing_year=form.publishing_year.data,
|
||||||
shared=False,
|
is_public=False,
|
||||||
title=form.title.data,
|
title=form.title.data,
|
||||||
version=form.version.data,
|
version=form.version.data,
|
||||||
user=current_user
|
user=current_user
|
||||||
@ -228,6 +228,6 @@ def toggle_spacy_nlp_pipeline_model_public_status(spacy_nlp_pipeline_model_id):
|
|||||||
spacy_nlp_pipeline_model = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
|
spacy_nlp_pipeline_model = SpaCyNLPPipelineModel.query.get_or_404(spacy_nlp_pipeline_model_id)
|
||||||
if not (spacy_nlp_pipeline_model.user == current_user or current_user.is_administrator()):
|
if not (spacy_nlp_pipeline_model.user == current_user or current_user.is_administrator()):
|
||||||
abort(403)
|
abort(403)
|
||||||
spacy_nlp_pipeline_model.shared = not spacy_nlp_pipeline_model.shared
|
spacy_nlp_pipeline_model.is_public = not spacy_nlp_pipeline_model.is_public
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return {}, 201
|
return {}, 201
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_wtf.file import FileField, FileRequired
|
from flask_wtf.file import FileField, FileRequired
|
||||||
from wtforms import StringField, SubmitField, ValidationError, IntegerField
|
from wtforms import (
|
||||||
|
StringField,
|
||||||
|
SubmitField,
|
||||||
|
TextAreaField,
|
||||||
|
ValidationError,
|
||||||
|
IntegerField
|
||||||
|
)
|
||||||
from wtforms.validators import InputRequired, Length
|
from wtforms.validators import InputRequired, Length
|
||||||
|
|
||||||
|
|
||||||
class CreateCorpusForm(FlaskForm):
|
class CorpusBaseForm(FlaskForm):
|
||||||
description = StringField(
|
description = TextAreaField(
|
||||||
'Description',
|
'Description',
|
||||||
validators=[InputRequired(), Length(max=255)]
|
validators=[InputRequired(), Length(max=255)]
|
||||||
)
|
)
|
||||||
@ -13,6 +19,20 @@ class CreateCorpusForm(FlaskForm):
|
|||||||
submit = SubmitField()
|
submit = SubmitField()
|
||||||
|
|
||||||
|
|
||||||
|
class CreateCorpusForm(CorpusBaseForm):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
if 'prefix' not in kwargs:
|
||||||
|
kwargs['prefix'] = 'create-corpus-form'
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateCorpusForm(CorpusBaseForm):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
if 'prefix' not in kwargs:
|
||||||
|
kwargs['prefix'] = 'update-corpus-form'
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class CorpusFileBaseForm(FlaskForm):
|
class CorpusFileBaseForm(FlaskForm):
|
||||||
author = StringField(
|
author = StringField(
|
||||||
'Author',
|
'Author',
|
||||||
@ -41,13 +61,21 @@ class CorpusFileBaseForm(FlaskForm):
|
|||||||
class CreateCorpusFileForm(CorpusFileBaseForm):
|
class CreateCorpusFileForm(CorpusFileBaseForm):
|
||||||
vrt = FileField('File', validators=[FileRequired()])
|
vrt = FileField('File', validators=[FileRequired()])
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
if 'prefix' not in kwargs:
|
||||||
|
kwargs['prefix'] = 'create-corpus-file-form'
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def validate_vrt(self, field):
|
def validate_vrt(self, field):
|
||||||
if not field.data.filename.lower().endswith('.vrt'):
|
if not field.data.filename.lower().endswith('.vrt'):
|
||||||
raise ValidationError('VRT files only!')
|
raise ValidationError('VRT files only!')
|
||||||
|
|
||||||
|
|
||||||
class EditCorpusFileForm(CorpusFileBaseForm):
|
class UpdateCorpusFileForm(CorpusFileBaseForm):
|
||||||
pass
|
def __init__(self, *args, **kwargs):
|
||||||
|
if 'prefix' not in kwargs:
|
||||||
|
kwargs['prefix'] = 'update-corpus-file-form'
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class ImportCorpusForm(FlaskForm):
|
class ImportCorpusForm(FlaskForm):
|
||||||
|
@ -13,7 +13,26 @@ import os
|
|||||||
from app import db
|
from app import db
|
||||||
from app.models import Corpus, CorpusFile, CorpusStatus
|
from app.models import Corpus, CorpusFile, CorpusStatus
|
||||||
from . import bp
|
from . import bp
|
||||||
from .forms import CreateCorpusFileForm, CreateCorpusForm, EditCorpusFileForm
|
from .forms import CreateCorpusFileForm, CreateCorpusForm, UpdateCorpusFileForm
|
||||||
|
|
||||||
|
|
||||||
|
def user_can_read_corpus(user, corpus):
|
||||||
|
return corpus.user == user or user.is_administrator() or corpus.is_public
|
||||||
|
|
||||||
|
|
||||||
|
def user_can_update_corpus(user, corpus):
|
||||||
|
return corpus.user == user or user.is_administrator()
|
||||||
|
|
||||||
|
|
||||||
|
def user_can_delete_corpus(user, corpus):
|
||||||
|
return user_can_update_corpus(user, corpus)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('')
|
||||||
|
@login_required
|
||||||
|
def corpora():
|
||||||
|
corpora = Corpus.query.filter(Corpus.user_id == current_user.id | Corpus.is_public == True).all()
|
||||||
|
return render_template('corpora/corpora.html', corpora=corpora)
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/create', methods=['GET', 'POST'])
|
@bp.route('/create', methods=['GET', 'POST'])
|
||||||
@ -46,7 +65,7 @@ def create_corpus():
|
|||||||
@login_required
|
@login_required
|
||||||
def corpus(corpus_id):
|
def corpus(corpus_id):
|
||||||
corpus = Corpus.query.get_or_404(corpus_id)
|
corpus = Corpus.query.get_or_404(corpus_id)
|
||||||
if not (corpus.user == current_user or current_user.is_administrator()):
|
if not user_can_read_corpus(current_user, corpus):
|
||||||
abort(403)
|
abort(403)
|
||||||
return render_template(
|
return render_template(
|
||||||
'corpora/corpus.html.j2',
|
'corpora/corpus.html.j2',
|
||||||
@ -55,6 +74,19 @@ def corpus(corpus_id):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# @bp.route('/<hashid:corpus_id>/update')
|
||||||
|
# @login_required
|
||||||
|
# def update_corpus(corpus_id):
|
||||||
|
# corpus = Corpus.query.get_or_404(corpus_id)
|
||||||
|
# if not user_can_update_corpus(current_user, corpus):
|
||||||
|
# abort(403)
|
||||||
|
# return render_template(
|
||||||
|
# 'corpora/update_corpus.html.j2',
|
||||||
|
# corpus=corpus,
|
||||||
|
# title='Corpus'
|
||||||
|
# )
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/<hashid:corpus_id>', methods=['DELETE'])
|
@bp.route('/<hashid:corpus_id>', methods=['DELETE'])
|
||||||
@login_required
|
@login_required
|
||||||
def delete_corpus(corpus_id):
|
def delete_corpus(corpus_id):
|
||||||
@ -65,7 +97,7 @@ def delete_corpus(corpus_id):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
corpus = Corpus.query.get_or_404(corpus_id)
|
corpus = Corpus.query.get_or_404(corpus_id)
|
||||||
if not (corpus.user == current_user or current_user.is_administrator()):
|
if not user_can_delete_corpus(current_user, corpus):
|
||||||
abort(403)
|
abort(403)
|
||||||
thread = Thread(
|
thread = Thread(
|
||||||
target=_delete_corpus,
|
target=_delete_corpus,
|
||||||
@ -79,6 +111,8 @@ def delete_corpus(corpus_id):
|
|||||||
@login_required
|
@login_required
|
||||||
def analyse_corpus(corpus_id):
|
def analyse_corpus(corpus_id):
|
||||||
corpus = Corpus.query.get_or_404(corpus_id)
|
corpus = Corpus.query.get_or_404(corpus_id)
|
||||||
|
if not user_can_read_corpus(current_user, corpus):
|
||||||
|
abort(403)
|
||||||
return render_template(
|
return render_template(
|
||||||
'corpora/analyse_corpus.html.j2',
|
'corpora/analyse_corpus.html.j2',
|
||||||
corpus=corpus,
|
corpus=corpus,
|
||||||
@ -96,7 +130,7 @@ def build_corpus(corpus_id):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
corpus = Corpus.query.get_or_404(corpus_id)
|
corpus = Corpus.query.get_or_404(corpus_id)
|
||||||
if not (corpus.user == current_user or current_user.is_administrator()):
|
if not user_can_update_corpus(current_user, corpus):
|
||||||
abort(403)
|
abort(403)
|
||||||
# Check if the corpus has corpus files
|
# Check if the corpus has corpus files
|
||||||
if not corpus.files.all():
|
if not corpus.files.all():
|
||||||
@ -114,7 +148,7 @@ def build_corpus(corpus_id):
|
|||||||
@login_required
|
@login_required
|
||||||
def create_corpus_file(corpus_id):
|
def create_corpus_file(corpus_id):
|
||||||
corpus = Corpus.query.get_or_404(corpus_id)
|
corpus = Corpus.query.get_or_404(corpus_id)
|
||||||
if not (corpus.user == current_user or current_user.is_administrator()):
|
if not user_can_update_corpus(current_user, corpus):
|
||||||
abort(403)
|
abort(403)
|
||||||
form = CreateCorpusFileForm(prefix='create-corpus-file-form')
|
form = CreateCorpusFileForm(prefix='create-corpus-file-form')
|
||||||
if form.is_submitted():
|
if form.is_submitted():
|
||||||
@ -157,16 +191,13 @@ def create_corpus_file(corpus_id):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/<hashid:corpus_id>/files/<hashid:corpus_file_id>',
|
@bp.route('/<hashid:corpus_id>/files/<hashid:corpus_file_id>', methods=['GET', 'POST'])
|
||||||
methods=['GET', 'POST'])
|
|
||||||
@login_required
|
@login_required
|
||||||
def corpus_file(corpus_id, corpus_file_id):
|
def corpus_file(corpus_id, corpus_file_id):
|
||||||
corpus_file = CorpusFile.query.get_or_404(corpus_file_id)
|
corpus_file = CorpusFile.query.filter_by(corpus_id = corpus_id, id=corpus_file_id).first_or_404()
|
||||||
if corpus_file.corpus.id != corpus_id:
|
|
||||||
abort(404)
|
|
||||||
if not (corpus_file.corpus.user == current_user or current_user.is_administrator()):
|
if not (corpus_file.corpus.user == current_user or current_user.is_administrator()):
|
||||||
abort(403)
|
abort(403)
|
||||||
form = EditCorpusFileForm(
|
form = UpdateCorpusFileForm(
|
||||||
data=corpus_file.to_json_serializeable(),
|
data=corpus_file.to_json_serializeable(),
|
||||||
prefix='edit-corpus-file-form'
|
prefix='edit-corpus-file-form'
|
||||||
)
|
)
|
||||||
@ -196,9 +227,7 @@ def delete_corpus_file(corpus_id, corpus_file_id):
|
|||||||
corpus_file.delete()
|
corpus_file.delete()
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
corpus_file = CorpusFile.query.get_or_404(corpus_file_id)
|
corpus_file = CorpusFile.query.filter_by(corpus_id = corpus_id, id=corpus_file_id).first_or_404()
|
||||||
if corpus_file.corpus.id != corpus_id:
|
|
||||||
abort(404)
|
|
||||||
if not (corpus_file.corpus.user == current_user or current_user.is_administrator()):
|
if not (corpus_file.corpus.user == current_user or current_user.is_administrator()):
|
||||||
abort(403)
|
abort(403)
|
||||||
thread = Thread(
|
thread = Thread(
|
||||||
@ -212,9 +241,7 @@ def delete_corpus_file(corpus_id, corpus_file_id):
|
|||||||
@bp.route('/<hashid:corpus_id>/files/<hashid:corpus_file_id>/download')
|
@bp.route('/<hashid:corpus_id>/files/<hashid:corpus_file_id>/download')
|
||||||
@login_required
|
@login_required
|
||||||
def download_corpus_file(corpus_id, corpus_file_id):
|
def download_corpus_file(corpus_id, corpus_file_id):
|
||||||
corpus_file = CorpusFile.query.get_or_404(corpus_file_id)
|
corpus_file = CorpusFile.query.filter_by(corpus_id = corpus_id, id=corpus_file_id).first_or_404()
|
||||||
if corpus_file.corpus.id != corpus_id:
|
|
||||||
abort(404)
|
|
||||||
if not (corpus_file.corpus.user == current_user or current_user.is_administrator()):
|
if not (corpus_file.corpus.user == current_user or current_user.is_administrator()):
|
||||||
abort(403)
|
abort(403)
|
||||||
return send_from_directory(
|
return send_from_directory(
|
||||||
|
@ -46,13 +46,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the data-length attribute on inputs with the maxlength attribute
|
// Set the data-length attribute on inputs with the maxlength attribute
|
||||||
for (let inputElement of document.querySelectorAll('input[maxlength]')) {
|
for (let inputElement of document.querySelectorAll('input[maxlength], textarea[maxlength]')) {
|
||||||
inputElement.dataset.length = inputElement.getAttribute('maxlength');
|
inputElement.dataset.length = inputElement.getAttribute('maxlength');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize components
|
// Initialize components
|
||||||
M.AutoInit();
|
M.AutoInit();
|
||||||
M.CharacterCounter.init(document.querySelectorAll('input[data-length][type="text"], input[data-length][type="email"], input[data-length][type="search"], input[data-length][type="password"], input[data-length][type="tel"], input[data-length][type="url"]'));
|
M.CharacterCounter.init(document.querySelectorAll('input[data-length][type="text"], input[data-length][type="email"], input[data-length][type="search"], input[data-length][type="password"], input[data-length][type="tel"], input[data-length][type="url"], textarea[data-length]'));
|
||||||
M.Dropdown.init(
|
M.Dropdown.init(
|
||||||
document.querySelectorAll('#nav-more-dropdown-trigger'),
|
document.querySelectorAll('#nav-more-dropdown-trigger'),
|
||||||
{alignment: 'right', constrainWidth: false, coverTrigger: false}
|
{alignment: 'right', constrainWidth: false, coverTrigger: false}
|
||||||
|
@ -9,28 +9,19 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col s12">
|
<div class="col s12">
|
||||||
<h1 id="title">{{ title }}</h1>
|
<h1 id="title">{{ title }}</h1>
|
||||||
|
<p>Here you can create a new corpus, just choose a title and a description which will help to identify it later. After the corpus has been created, annotated texts in <i>verticalized text format</i> can be added to it on the corpus overview page.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col s12 m4">
|
<div class="col s12">
|
||||||
<p>Fill out the following form to add a corpus to your corpora.</p>
|
|
||||||
<a class="waves-effect waves-light btn" href="{{ url_for('main.dashboard') }}"><i class="material-icons left">arrow_back</i>Back to dashboard</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col s12 m8">
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
{{ form.hidden_tag() }}
|
{{ form.hidden_tag() }}
|
||||||
<div class="row">
|
{{ wtf.render_field(form.title, material_icon='title') }}
|
||||||
<div class="col s12 m4">
|
{{ wtf.render_field(form.description, material_icon='description') }}
|
||||||
{{ wtf.render_field(form.title, material_icon='title') }}
|
|
||||||
</div>
|
|
||||||
<div class="col s12 m8">
|
|
||||||
{{ wtf.render_field(form.description, material_icon='description') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-action right-align">
|
<div class="card-action right-align">
|
||||||
|
<a class="waves-effect waves-light btn red" href="{{ url_for('main.dashboard', _anchor='corpora') }}"><i class="material-icons left">close</i>Cancel</a>
|
||||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-action right-align">
|
<div class="card-action right-align">
|
||||||
|
<a class="waves-effect waves-light btn red" href="{{ url_for('.corpus', corpus_id=corpus.id) }}"><i class="material-icons left">close</i>Cancel</a>
|
||||||
{{ wtf.render_field(form.submit, material_icon='send') }}
|
{{ wtf.render_field(form.submit, material_icon='send') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
41
migrations/versions/f2656133df2f_.py
Normal file
41
migrations/versions/f2656133df2f_.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
"""empty message
|
||||||
|
|
||||||
|
Revision ID: f2656133df2f
|
||||||
|
Revises: 31b9c0259e6b
|
||||||
|
Create Date: 2022-11-29 14:17:16.845501
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'f2656133df2f'
|
||||||
|
down_revision = '31b9c0259e6b'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.add_column(
|
||||||
|
'corpus_files',
|
||||||
|
sa.Column('description', sa.String(length=255), nullable=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
op.alter_column(
|
||||||
|
'spacy_nlp_pipeline_models',
|
||||||
|
'shared',
|
||||||
|
new_column_name='is_public'
|
||||||
|
)
|
||||||
|
op.alter_column(
|
||||||
|
'tesseract_ocr_pipeline_models',
|
||||||
|
'shared',
|
||||||
|
new_column_name='is_public'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.alter_column('tesseract_ocr_pipeline_models', 'is_public', new_column_name='shared')
|
||||||
|
op.alter_column('spacy_nlp_pipeline_models', 'is_public', new_column_name='shared')
|
||||||
|
|
||||||
|
op.drop_column('corpus_files', 'description')
|
Loading…
Reference in New Issue
Block a user