SpaCy NLP Pipeline Models
Here you can see and edit the models that you have created. You can also create new models.
diff --git a/app/templates/contributions/create_spacy_nlp_pipeline_model.html.j2 b/app/templates/contributions/spacy_nlp_pipeline_models/create_spacy_nlp_pipeline_model.html.j2
similarity index 97%
rename from app/templates/contributions/create_spacy_nlp_pipeline_model.html.j2
rename to app/templates/contributions/spacy_nlp_pipeline_models/create_spacy_nlp_pipeline_model.html.j2
index e17ac9e5..091c61ad 100644
--- a/app/templates/contributions/create_spacy_nlp_pipeline_model.html.j2
+++ b/app/templates/contributions/spacy_nlp_pipeline_models/create_spacy_nlp_pipeline_model.html.j2
@@ -1,6 +1,5 @@
{% extends "base.html.j2" %}
{% import "materialize/wtf.html.j2" as wtf %}
-{% from "contributions/_breadcrumbs.html.j2" import breadcrumbs with context %}
{% block main_attribs %} class="service-scheme" data-service="spacy-nlp-pipeline"{% endblock main_attribs %}
diff --git a/app/templates/contributions/spacy_nlp_pipeline_model.html.j2 b/app/templates/contributions/spacy_nlp_pipeline_models/spacy_nlp_pipeline_model.html.j2
similarity index 96%
rename from app/templates/contributions/spacy_nlp_pipeline_model.html.j2
rename to app/templates/contributions/spacy_nlp_pipeline_models/spacy_nlp_pipeline_model.html.j2
index 32f27303..467effc9 100644
--- a/app/templates/contributions/spacy_nlp_pipeline_model.html.j2
+++ b/app/templates/contributions/spacy_nlp_pipeline_models/spacy_nlp_pipeline_model.html.j2
@@ -1,6 +1,5 @@
{% extends "base.html.j2" %}
{% import "materialize/wtf.html.j2" as wtf %}
-{% from "contributions/_breadcrumbs.html.j2" import breadcrumbs with context %}
{% block main_attribs %} class="service-scheme" data-service="spacy-nlp-pipeline"{% endblock main_attribs %}
diff --git a/app/templates/contributions/spacy_nlp_pipeline_models.html.j2 b/app/templates/contributions/spacy_nlp_pipeline_models/spacy_nlp_pipeline_models.html.j2
similarity index 91%
rename from app/templates/contributions/spacy_nlp_pipeline_models.html.j2
rename to app/templates/contributions/spacy_nlp_pipeline_models/spacy_nlp_pipeline_models.html.j2
index f3c7a40e..b57507be 100644
--- a/app/templates/contributions/spacy_nlp_pipeline_models.html.j2
+++ b/app/templates/contributions/spacy_nlp_pipeline_models/spacy_nlp_pipeline_models.html.j2
@@ -1,6 +1,5 @@
{% extends "base.html.j2" %}
{% import "materialize/wtf.html.j2" as wtf %}
-{% from "contributions/_breadcrumbs.html.j2" import breadcrumbs with context %}
{% block page_content %}
diff --git a/app/templates/contributions/create_tesseract_ocr_pipeline_model.html.j2 b/app/templates/contributions/tesseract_ocr_pipeline_models/create_tesseract_ocr_pipeline_model.html.j2
similarity index 98%
rename from app/templates/contributions/create_tesseract_ocr_pipeline_model.html.j2
rename to app/templates/contributions/tesseract_ocr_pipeline_models/create_tesseract_ocr_pipeline_model.html.j2
index ecede20a..43ad0a13 100644
--- a/app/templates/contributions/create_tesseract_ocr_pipeline_model.html.j2
+++ b/app/templates/contributions/tesseract_ocr_pipeline_models/create_tesseract_ocr_pipeline_model.html.j2
@@ -1,6 +1,5 @@
{% extends "base.html.j2" %}
{% import "materialize/wtf.html.j2" as wtf %}
-{% from "contributions/_breadcrumbs.html.j2" import breadcrumbs with context %}
{% block main_attribs %} class="service-scheme" data-service="tesseract-ocr-pipeline"{% endblock main_attribs %}
diff --git a/app/templates/contributions/tesseract_ocr_pipeline_model.html.j2 b/app/templates/contributions/tesseract_ocr_pipeline_models/tesseract_ocr_pipeline_model.html.j2
similarity index 95%
rename from app/templates/contributions/tesseract_ocr_pipeline_model.html.j2
rename to app/templates/contributions/tesseract_ocr_pipeline_models/tesseract_ocr_pipeline_model.html.j2
index 02322d8a..c7cc2d5c 100644
--- a/app/templates/contributions/tesseract_ocr_pipeline_model.html.j2
+++ b/app/templates/contributions/tesseract_ocr_pipeline_models/tesseract_ocr_pipeline_model.html.j2
@@ -1,6 +1,5 @@
{% extends "base.html.j2" %}
{% import "materialize/wtf.html.j2" as wtf %}
-{% from "contributions/_breadcrumbs.html.j2" import breadcrumbs with context %}
{% block main_attribs %} class="service-scheme" data-service="tesseract-ocr-pipeline"{% endblock main_attribs %}
diff --git a/app/templates/contributions/tesseract_ocr_pipeline_models.html.j2 b/app/templates/contributions/tesseract_ocr_pipeline_models/tesseract_ocr_pipeline_models.html.j2
similarity index 91%
rename from app/templates/contributions/tesseract_ocr_pipeline_models.html.j2
rename to app/templates/contributions/tesseract_ocr_pipeline_models/tesseract_ocr_pipeline_models.html.j2
index 3d43d727..a2f18c2a 100644
--- a/app/templates/contributions/tesseract_ocr_pipeline_models.html.j2
+++ b/app/templates/contributions/tesseract_ocr_pipeline_models/tesseract_ocr_pipeline_models.html.j2
@@ -1,6 +1,5 @@
{% extends "base.html.j2" %}
{% import "materialize/wtf.html.j2" as wtf %}
-{% from "contributions/_breadcrumbs.html.j2" import breadcrumbs with context %}
{% block page_content %}
From fdad10991ce0ae58ed3c3cd7d3f252d5723bb24c Mon Sep 17 00:00:00 2001
From: Patrick Jentsch
Date: Thu, 9 Mar 2023 12:07:16 +0100
Subject: [PATCH 11/11] More restructuring
---
app/corpora/routes.py | 326 +++++++++++-------
app/static/js/Requests/Contributions.js | 51 ---
app/static/js/Requests/Corpora.js | 0
.../Requests/contributions/contributions.js | 5 +
.../spacy_nlp_pipeline_models.js | 26 ++
.../tesseract_ocr_pipeline_models.js | 26 ++
app/static/js/Requests/corpora/corpora.js | 78 +++++
.../SpacyNLPPipelineModelList.js | 34 +-
.../TesseractOCRPipelineModelList.js | 34 +-
app/templates/_scripts.html.j2 | 5 +-
.../contributions/contributions.html.j2 | 2 +-
app/templates/corpora/corpus.html.j2 | 23 +-
12 files changed, 417 insertions(+), 193 deletions(-)
delete mode 100644 app/static/js/Requests/Contributions.js
create mode 100644 app/static/js/Requests/Corpora.js
create mode 100644 app/static/js/Requests/contributions/contributions.js
create mode 100644 app/static/js/Requests/contributions/spacy_nlp_pipeline_models.js
create mode 100644 app/static/js/Requests/contributions/tesseract_ocr_pipeline_models.js
create mode 100644 app/static/js/Requests/corpora/corpora.js
diff --git a/app/corpora/routes.py b/app/corpora/routes.py
index 5d1b1a41..8a3e5e66 100644
--- a/app/corpora/routes.py
+++ b/app/corpora/routes.py
@@ -16,6 +16,7 @@ from threading import Thread
import os
from .decorators import corpus_follower_permission_required, corpus_owner_or_admin_required
from app import db, hashids
+from app.decorators import content_negotiation
from app.models import (
Corpus,
CorpusFile,
@@ -32,93 +33,6 @@ from .forms import (
)
-@bp.route('//is_public', methods=['POST'])
-@login_required
-@corpus_owner_or_admin_required
-def update_corpus_is_public(corpus_id):
- is_public = request.json
- if not isinstance(is_public, bool):
- response = jsonify('The request body must be a boolean')
- response.status_code = 400
- abort(response)
- corpus = Corpus.query.get_or_404(corpus_id)
- corpus.is_public = is_public
- db.session.commit()
- return '', 204
-
-
-@bp.route('//followers/add', methods=['POST'])
-@login_required
-@corpus_owner_or_admin_required
-def add_corpus_followers(corpus_id):
- usernames = request.json
- if not (isinstance(usernames, list) or all(isinstance(u, str) for u in usernames)):
- response = jsonify('The request body must be a list of strings')
- response.status_code = 400
- abort(response)
- corpus = Corpus.query.get_or_404(corpus_id)
- for username in usernames:
- user = User.query.filter_by(username=username, is_public=True).first_or_404()
- user.follow_corpus(corpus)
- db.session.commit()
- return '', 204
-
-
-@bp.route('//follow/')
-@login_required
-def follow_corpus(corpus_id, token):
- corpus = Corpus.query.get_or_404(corpus_id)
- if current_user.follow_corpus_by_token(token):
- db.session.commit()
- flash(f'You are following {corpus.title} now', category='corpus')
- return redirect(url_for('corpora.corpus', corpus_id=corpus_id))
- abort(403)
-
-
-@bp.route('//followers//unfollow', methods=['POST'])
-@login_required
-def unfollow_corpus(corpus_id, follower_id):
- corpus = Corpus.query.get_or_404(corpus_id)
- follower = User.query.get_or_404(follower_id)
- if not (corpus.user == current_user or follower == current_user or current_user.is_administrator()):
- abort(403)
- if not follower.is_following_corpus(corpus):
- abort(409) # 'User is not following the corpus'
- follower.unfollow_corpus(corpus)
- db.session.commit()
- flash(f'{follower.username} is not following {corpus.title} anymore', category='corpus')
- return '', 204
-
-
-@bp.route('//followers//role', methods=['POST'])
-@corpus_follower_permission_required('UPDATE_FOLLOWER')
-def add_permission(corpus_id, follower_id):
- corpus_follower_association = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=follower_id).first_or_404()
- if not (corpus_follower_association.corpus.user == current_user or current_user.is_administrator()):
- abort(403)
- role_name = request.json.get('role')
- if role_name is None:
- abort(400)
- corpus_follower_role = CorpusFollowerRole.query.filter_by(name=role_name).first_or_404()
- corpus_follower_association.role = corpus_follower_role
- db.session.commit()
- return '', 204
-
-
-@bp.route('/public')
-@login_required
-def public_corpora():
- corpora = [
- c.to_json_serializeable()
- for c in Corpus.query.filter(Corpus.is_public == True).all()
- ]
- return render_template(
- 'corpora/public_corpora.html.j2',
- corpora=corpora,
- title='Corpora'
- )
-
-
@bp.route('/create', methods=['GET', 'POST'])
@login_required
def create_corpus():
@@ -145,6 +59,24 @@ def create_corpus():
)
+@bp.route('/public')
+@login_required
+def public_corpora():
+ corpora = [
+ c.to_json_serializeable()
+ for c in Corpus.query.filter(Corpus.is_public == True).all()
+ ]
+ return render_template(
+ 'corpora/public_corpora.html.j2',
+ corpora=corpora,
+ title='Corpora'
+ )
+
+
+##############################################################################
+# Corpus #
+##############################################################################
+#region corpus
@bp.route('/')
@login_required
def corpus(corpus_id):
@@ -172,6 +104,18 @@ def corpus(corpus_id):
abort(403)
+@bp.route('//analyse')
+@login_required
+@corpus_follower_permission_required('VIEW')
+def analyse_corpus(corpus_id):
+ corpus = Corpus.query.get_or_404(corpus_id)
+ return render_template(
+ 'corpora/analyse_corpus.html.j2',
+ corpus=corpus,
+ title=f'Analyse Corpus {corpus.title}'
+ )
+
+
@bp.route('//generate-corpus-share-link', methods=['GET', 'POST'])
@login_required
@corpus_follower_permission_required('GENERATE_SHARE_LINK')
@@ -186,9 +130,34 @@ def generate_corpus_share_link(corpus_id):
return link
+@bp.route('//follow/')
+@login_required
+def follow_corpus(corpus_id, token):
+ corpus = Corpus.query.get_or_404(corpus_id)
+ if current_user.follow_corpus_by_token(token):
+ db.session.commit()
+ flash(f'You are following {corpus.title} now', category='corpus')
+ return redirect(url_for('corpora.corpus', corpus_id=corpus_id))
+ abort(403)
+
+
+@bp.route('/import', methods=['GET', 'POST'])
+@login_required
+def import_corpus():
+ abort(503)
+
+
+@bp.route('//export')
+@login_required
+def export_corpus(corpus_id):
+ abort(503)
+
+
+#region json-routes
@bp.route('/', methods=['DELETE'])
@login_required
@corpus_owner_or_admin_required
+@content_negotiation(produces='application/json')
def delete_corpus(corpus_id):
def _delete_corpus(app, corpus_id):
with app.app_context():
@@ -199,27 +168,22 @@ def delete_corpus(corpus_id):
corpus = Corpus.query.get_or_404(corpus_id)
thread = Thread(
target=_delete_corpus,
- args=(current_app._get_current_object(), corpus_id)
+ args=(current_app._get_current_object(), corpus.id)
)
thread.start()
- return {}, 202
-
-
-@bp.route('//analyse')
-@login_required
-@corpus_follower_permission_required('VIEW')
-def analyse_corpus(corpus_id):
- corpus = Corpus.query.get_or_404(corpus_id)
- return render_template(
- 'corpora/analyse_corpus.html.j2',
- corpus=corpus,
- title=f'Analyse Corpus {corpus.title}'
- )
+ response_data = {
+ 'message': f'Corpus "{corpus.title}" marked for deletion',
+ 'category': 'corpus'
+ }
+ response = jsonify(response_data)
+ response.status_code = 200
+ return response
@bp.route('//build', methods=['POST'])
@login_required
@corpus_owner_or_admin_required
+@content_negotiation(produces='application/json')
def build_corpus(corpus_id):
def _build_corpus(app, corpus_id):
with app.app_context():
@@ -230,18 +194,51 @@ def build_corpus(corpus_id):
corpus = Corpus.query.get_or_404(corpus_id)
if not (corpus.user == current_user or current_user.is_administrator()):
abort(403)
- # Check if the corpus has corpus files
- if not corpus.files.all():
- response = {'errors': {'message': 'Corpus file(s) required'}}
- return response, 409
+ if len(corpus.files.all()) == 0:
+ abort(409)
thread = Thread(
target=_build_corpus,
args=(current_app._get_current_object(), corpus_id)
)
thread.start()
- return {}, 202
+ response_data = {
+ 'message': f'Corpus "{corpus.title}" marked for building',
+ 'category': 'corpus'
+ }
+ response = jsonify(response_data)
+ response.status_code = 202
+ return response
+@bp.route('//is_public', methods=['PUT'])
+@login_required
+@corpus_owner_or_admin_required
+@content_negotiation(consumes='application/json', produces='application/json')
+def update_corpus_is_public(corpus_id):
+ is_public = request.json
+ if not isinstance(is_public, bool):
+ abort(400)
+ corpus = Corpus.query.get_or_404(corpus_id)
+ corpus.is_public = is_public
+ db.session.commit()
+ response_data = {
+ 'message': (
+ f'Corpus "{corpus.title}" is now'
+ f' {"public" if is_public else "private"}'
+ ),
+ 'category': 'corpus'
+ }
+ response = jsonify(response_data)
+ response.status_code = 200
+ return response
+#endregion json-routes
+#endregion corpus
+
+
+##############################################################################
+# Corpus/Files #
+##############################################################################
+#region files
@bp.route('//files/create', methods=['GET', 'POST'])
@login_required
@corpus_follower_permission_required('ADD_CORPUS_FILE')
@@ -292,7 +289,7 @@ def create_corpus_file(corpus_id):
@bp.route('//files/', methods=['GET', 'POST'])
@login_required
-@corpus_follower_permission_required('ADD_CORPUS_FILE', 'UPDATE_CORPUS_FILE', 'REMOVE_CORPUS_FILE')
+@corpus_follower_permission_required('UPDATE_CORPUS_FILE')
def corpus_file(corpus_id, corpus_file_id):
corpus_file = CorpusFile.query.filter_by(corpus_id = corpus_id, id=corpus_file_id).first_or_404()
form = UpdateCorpusFileForm(data=corpus_file.to_json_serializeable())
@@ -313,27 +310,6 @@ def corpus_file(corpus_id, corpus_file_id):
)
-@bp.route('//files/', methods=['DELETE'])
-@login_required
-@corpus_follower_permission_required('REMOVE_CORPUS_FILE')
-def delete_corpus_file(corpus_id, corpus_file_id):
- def _delete_corpus_file(app, corpus_file_id):
- with app.app_context():
- corpus_file = CorpusFile.query.get(corpus_file_id)
- corpus_file.delete()
- db.session.commit()
-
- corpus_file = CorpusFile.query.filter_by(corpus_id = corpus_id, id=corpus_file_id).first_or_404()
- if not (corpus_file.corpus.user == current_user or current_user.is_administrator()):
- abort(403)
- thread = Thread(
- target=_delete_corpus_file,
- args=(current_app._get_current_object(), corpus_file_id)
- )
- thread.start()
- return {}, 202
-
-
@bp.route('//files//download')
@login_required
@corpus_follower_permission_required('VIEW')
@@ -350,13 +326,95 @@ def download_corpus_file(corpus_id, corpus_file_id):
)
-@bp.route('/import', methods=['GET', 'POST'])
+#region json-routes
+@bp.route('//files/', methods=['DELETE'])
@login_required
-def import_corpus():
- abort(503)
+@corpus_follower_permission_required('REMOVE_CORPUS_FILE')
+@content_negotiation(produces='application/json')
+def delete_corpus_file(corpus_id, corpus_file_id):
+ def _delete_corpus_file(app, corpus_file_id):
+ with app.app_context():
+ corpus_file = CorpusFile.query.get(corpus_file_id)
+ corpus_file.delete()
+ db.session.commit()
+
+ corpus_file = CorpusFile.query.filter_by(corpus_id=corpus_id, id=corpus_file_id).first_or_404()
+ thread = Thread(
+ target=_delete_corpus_file,
+ args=(current_app._get_current_object(), corpus_file.id)
+ )
+ thread.start()
+ return {}, 202
+#endregion json-routes
+#endregion files
+
+##############################################################################
+# Corpus/Followers #
+##############################################################################
+#region followers
+#region json-routes
+@bp.route('//followers', methods=['POST'])
+@login_required
+@corpus_owner_or_admin_required
+@content_negotiation(consumes='application/json', produces='application/json')
+def add_corpus_followers(corpus_id):
+ usernames = request.json
+ if not (isinstance(usernames, list) or all(isinstance(u, str) for u in usernames)):
+ abort(400)
+ corpus = Corpus.query.get_or_404(corpus_id)
+ for username in usernames:
+ user = User.query.filter_by(username=username, is_public=True).first_or_404()
+ user.follow_corpus(corpus)
+ db.session.commit()
+ resonse_data = {
+ 'message': f'Users are now following "{corpus.title}"',
+ 'category': 'corpus'
+ }
+ response = jsonify(resonse_data)
+ response.status_code = 200
+ return response
-@bp.route('//export')
+@bp.route('//followers/', methods=['DELETE'])
@login_required
-def export_corpus(corpus_id):
- abort(503)
+@content_negotiation(produces='application/json')
+def unfollow_corpus(corpus_id, follower_id):
+ corpus = Corpus.query.get_or_404(corpus_id)
+ follower = User.query.get_or_404(follower_id)
+ if not (corpus.user == current_user or follower == current_user or current_user.is_administrator()):
+ abort(403)
+ if not follower.is_following_corpus(corpus):
+ abort(409) # 'User is not following the corpus'
+ follower.unfollow_corpus(corpus)
+ db.session.commit()
+ response_data = {
+ 'message': \
+ f'"{follower.username}" is not following "{corpus.title}" anymore',
+ 'category': 'corpus'
+ }
+ response = jsonify(response_data)
+ response.status_code = 200
+ return response
+
+
+@bp.route('//followers//role', methods=['PUT'])
+@login_required
+@corpus_owner_or_admin_required
+@content_negotiation(consumes='application/json', produces='application/json')
+def add_permission(corpus_id, follower_id):
+ role_name = request.json
+ if not isinstance(role_name, str):
+ abort(400)
+ cfr = CorpusFollowerRole.query.filter_by(name=role_name).first_or_404()
+ cfa = CorpusFollowerAssociation.query.filter_by(corpus_id=corpus_id, follower_id=follower_id).first_or_404()
+ cfa.role = cfr
+ db.session.commit()
+ resonse_data = {
+ 'message': f'User "{cfa.follower.username}" is now {cfa.role.name}',
+ 'category': 'corpus'
+ }
+ response = jsonify(resonse_data)
+ response.status_code = 200
+ return response
+#endregion json-routes
+#endregion followers
diff --git a/app/static/js/Requests/Contributions.js b/app/static/js/Requests/Contributions.js
deleted file mode 100644
index 30605135..00000000
--- a/app/static/js/Requests/Contributions.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/*****************************************************************************
-* Contributions *
-* Fetch requests for /contributions routes *
-*****************************************************************************/
-Requests.contributions = {};
-
-Requests.contributions.spacy_nlp_pipeline_models = {};
-
-Requests.contributions.spacy_nlp_pipeline_models.ent = {};
-
-Requests.contributions.spacy_nlp_pipeline_models.ent.delete = (spacyNlpPipelineModelId) => {
- let input = `/contributions/spacy-nlp-pipeline-models/${spacyNlpPipelineModelId}`;
- let init = {
- method: 'DELETE'
- };
- return Requests.JSONfetch(input, init);
-};
-
-Requests.contributions.spacy_nlp_pipeline_models.ent.isPublic = {};
-
-Requests.contributions.spacy_nlp_pipeline_models.ent.isPublic.update = (spacyNlpPipelineModelId, value) => {
- let input = `/contributions/spacy-nlp-pipeline-models/${spacyNlpPipelineModelId}/is_public`;
- let init = {
- method: 'PUT',
- body: JSON.stringify(value)
- };
- return Requests.JSONfetch(input, init);
-};
-
-Requests.contributions.tesseract_ocr_pipeline_models = {};
-
-Requests.contributions.tesseract_ocr_pipeline_models.ent = {};
-
-Requests.contributions.tesseract_ocr_pipeline_models.ent.delete = (tesseractOcrPipelineModelId) => {
- let input = `/contributions/tesseract-ocr-pipeline-models/${tesseractOcrPipelineModelId}`;
- let init = {
- method: 'DELETE'
- };
- return Requests.JSONfetch(input, init);
-};
-
-Requests.contributions.tesseract_ocr_pipeline_models.ent.isPublic = {};
-
-Requests.contributions.tesseract_ocr_pipeline_models.ent.isPublic.update = (tesseractOcrPipelineModelId, value) => {
- let input = `/contributions/tesseract-ocr-pipeline-models/${tesseractOcrPipelineModelId}/is_public`;
- let init = {
- method: 'PUT',
- body: JSON.stringify(value)
- };
- return Requests.JSONfetch(input, init);
-};
diff --git a/app/static/js/Requests/Corpora.js b/app/static/js/Requests/Corpora.js
new file mode 100644
index 00000000..e69de29b
diff --git a/app/static/js/Requests/contributions/contributions.js b/app/static/js/Requests/contributions/contributions.js
new file mode 100644
index 00000000..2d9cf26a
--- /dev/null
+++ b/app/static/js/Requests/contributions/contributions.js
@@ -0,0 +1,5 @@
+/*****************************************************************************
+* Contributions *
+* Fetch requests for /contributions routes *
+*****************************************************************************/
+Requests.contributions = {};
diff --git a/app/static/js/Requests/contributions/spacy_nlp_pipeline_models.js b/app/static/js/Requests/contributions/spacy_nlp_pipeline_models.js
new file mode 100644
index 00000000..e1422c1e
--- /dev/null
+++ b/app/static/js/Requests/contributions/spacy_nlp_pipeline_models.js
@@ -0,0 +1,26 @@
+/*****************************************************************************
+* SpaCy NLP Pipeline Models *
+* Fetch requests for /contributions/spacy-nlp-pipeline-models routes *
+*****************************************************************************/
+Requests.contributions.spacy_nlp_pipeline_models = {};
+
+Requests.contributions.spacy_nlp_pipeline_models.entity = {};
+
+Requests.contributions.spacy_nlp_pipeline_models.entity.delete = (spacyNlpPipelineModelId) => {
+ let input = `/contributions/spacy-nlp-pipeline-models/${spacyNlpPipelineModelId}`;
+ let init = {
+ method: 'DELETE'
+ };
+ return Requests.JSONfetch(input, init);
+};
+
+Requests.contributions.spacy_nlp_pipeline_models.entity.isPublic = {};
+
+Requests.contributions.spacy_nlp_pipeline_models.entity.isPublic.update = (spacyNlpPipelineModelId, value) => {
+ let input = `/contributions/spacy-nlp-pipeline-models/${spacyNlpPipelineModelId}/is_public`;
+ let init = {
+ method: 'PUT',
+ body: JSON.stringify(value)
+ };
+ return Requests.JSONfetch(input, init);
+};
diff --git a/app/static/js/Requests/contributions/tesseract_ocr_pipeline_models.js b/app/static/js/Requests/contributions/tesseract_ocr_pipeline_models.js
new file mode 100644
index 00000000..13feb42a
--- /dev/null
+++ b/app/static/js/Requests/contributions/tesseract_ocr_pipeline_models.js
@@ -0,0 +1,26 @@
+/*****************************************************************************
+* Tesseract OCR Pipeline Models *
+* Fetch requests for /contributions/tesseract-ocr-pipeline-models routes *
+*****************************************************************************/
+Requests.contributions.tesseract_ocr_pipeline_models = {};
+
+Requests.contributions.tesseract_ocr_pipeline_models.entity = {};
+
+Requests.contributions.tesseract_ocr_pipeline_models.entity.delete = (tesseractOcrPipelineModelId) => {
+ let input = `/contributions/tesseract-ocr-pipeline-models/${tesseractOcrPipelineModelId}`;
+ let init = {
+ method: 'DELETE'
+ };
+ return Requests.JSONfetch(input, init);
+};
+
+Requests.contributions.tesseract_ocr_pipeline_models.entity.isPublic = {};
+
+Requests.contributions.tesseract_ocr_pipeline_models.entity.isPublic.update = (tesseractOcrPipelineModelId, value) => {
+ let input = `/contributions/tesseract-ocr-pipeline-models/${tesseractOcrPipelineModelId}/is_public`;
+ let init = {
+ method: 'PUT',
+ body: JSON.stringify(value)
+ };
+ return Requests.JSONfetch(input, init);
+};
diff --git a/app/static/js/Requests/corpora/corpora.js b/app/static/js/Requests/corpora/corpora.js
new file mode 100644
index 00000000..051fb07f
--- /dev/null
+++ b/app/static/js/Requests/corpora/corpora.js
@@ -0,0 +1,78 @@
+/*****************************************************************************
+* Corpora *
+* Fetch requests for /corpora routes *
+*****************************************************************************/
+Requests.corpora = {};
+
+Requests.corpora.ent = {};
+
+Requests.corpora.ent.delete = (corpusId) => {
+ let input = `/corpora/${corpusId}`;
+ let init = {
+ method: 'DELETE'
+ };
+ return Requests.JSONfetch(input, init);
+};
+
+Requests.corpora.ent.build = (corpusId) => {
+ let input = `/corpora/${corpusId}/build`;
+ let init = {
+ method: 'POST',
+ };
+ return Requests.JSONfetch(input, init);
+};
+
+Requests.corpora.ent.isPublic = {};
+
+Requests.corpora.ent.isPublic.update = (corpusId, value) => {
+ let input = `/corpora/${corpusId}/is_public`;
+ let init = {
+ method: 'PUT',
+ body: JSON.stringify(value)
+ };
+ return Requests.JSONfetch(input, init);
+};
+
+Requests.corpora.ent.files = {};
+
+Requests.corpora.ent.files.ent = {};
+
+Requests.corpora.ent.files.ent.delete = (corpusId, corpusFileId) => {
+ let input = `/corpora/${corpusId}/files/${corpusFileId}`;
+ let init = {
+ method: 'DELETE',
+ };
+ return Requests.JSONfetch(input, init);
+};
+
+Requests.corpora.ent.followers = {};
+
+Requests.corpora.ent.followers.add = (corpusId, usernames) => {
+ let input = `/corpora/${corpusId}/followers`;
+ let init = {
+ method: 'POST',
+ body: JSON.stringify(usernames)
+ };
+ return Requests.JSONfetch(input, init);
+};
+
+Requests.corpora.ent.followers.ent = {};
+
+Requests.corpora.ent.followers.ent.delete = (corpusId, followerId) => {
+ let input = `/corpora/${corpusId}/followers/${followerId}`;
+ let init = {
+ method: 'DELETE',
+ };
+ return Requests.JSONfetch(input, init);
+};
+
+Requests.corpora.ent.followers.ent.role = {};
+
+Requests.corpora.ent.followers.ent.role.update = (corpusId, followerId, value) => {
+ let input = `/corpora/${corpusId}/followers/${followerId}/role`;
+ let init = {
+ method: 'PUT',
+ body: JSON.stringify(value)
+ };
+ return Requests.JSONfetch(input, init);
+};
diff --git a/app/static/js/ResourceLists/SpacyNLPPipelineModelList.js b/app/static/js/ResourceLists/SpacyNLPPipelineModelList.js
index 5997fb0c..46d3739d 100644
--- a/app/static/js/ResourceLists/SpacyNLPPipelineModelList.js
+++ b/app/static/js/ResourceLists/SpacyNLPPipelineModelList.js
@@ -120,7 +120,7 @@ class SpaCyNLPPipelineModelList extends ResourceList {
switch (listAction) {
case 'toggle-is-public': {
let newIsPublicValue = listActionElement.checked;
- Requests.contributions.spacy_nlp_pipeline_models.ent.isPublic.update(itemId, newIsPublicValue)
+ Requests.contributions.spacy_nlp_pipeline_models.entity.isPublic.update(itemId, newIsPublicValue)
.catch((response) => {
listActionElement.checked = !newIsPublicValue;
});
@@ -141,7 +141,37 @@ class SpaCyNLPPipelineModelList extends ResourceList {
let listAction = listActionElement === null ? 'view' : listActionElement.dataset.listAction;
switch (listAction) {
case 'delete-request': {
- Requests.contributions.spacy_nlp_pipeline_models.ent.delete(itemId);
+ let values = this.listjs.get('id', itemId)[0].values();
+ let modalElement = Utils.HTMLToElement(
+ `
+
+
+
Confirm SpaCy NLP Pipeline Model deletion
+
Do you really want to delete the SpaCy NLP Pipeline Model ${values.title}? All files will be permanently deleted!
+
+
+
+ `
+ );
+ document.querySelector('#modals').appendChild(modalElement);
+ let modal = M.Modal.init(
+ modalElement,
+ {
+ dismissible: false,
+ onCloseEnd: () => {
+ modal.destroy();
+ modalElement.remove();
+ }
+ }
+ );
+ let confirmElement = modalElement.querySelector('.action-button[data-action="confirm"]');
+ confirmElement.addEventListener('click', (event) => {
+ Requests.contributions.spacy_nlp_pipeline_models.entity.delete(itemId);
+ });
+ modal.open();
break;
}
case 'view': {
diff --git a/app/static/js/ResourceLists/TesseractOCRPipelineModelList.js b/app/static/js/ResourceLists/TesseractOCRPipelineModelList.js
index 29d48dbb..9d632b29 100644
--- a/app/static/js/ResourceLists/TesseractOCRPipelineModelList.js
+++ b/app/static/js/ResourceLists/TesseractOCRPipelineModelList.js
@@ -129,7 +129,7 @@ class TesseractOCRPipelineModelList extends ResourceList {
switch (listAction) {
case 'toggle-is-public': {
let newIsPublicValue = listActionElement.checked;
- Requests.contributions.tesseract_ocr_pipeline_models.ent.isPublic.update(itemId, newIsPublicValue)
+ Requests.contributions.tesseract_ocr_pipeline_models.entity.isPublic.update(itemId, newIsPublicValue)
.catch((response) => {
listActionElement.checked = !newIsPublicValue;
});
@@ -155,7 +155,37 @@ class TesseractOCRPipelineModelList extends ResourceList {
let listAction = listActionElement === null ? 'view' : listActionElement.dataset.listAction;
switch (listAction) {
case 'delete-request': {
- Requests.contributions.tesseract_ocr_pipeline_models.ent.delete(itemId);
+ let values = this.listjs.get('id', itemId)[0].values();
+ let modalElement = Utils.HTMLToElement(
+ `
+
+
+
Confirm Tesseract OCR Pipeline Model deletion
+
Do you really want to delete the Tesseract OCR Pipeline Model ${values.title}? All files will be permanently deleted!
+
+
+
+ `
+ );
+ document.querySelector('#modals').appendChild(modalElement);
+ let modal = M.Modal.init(
+ modalElement,
+ {
+ dismissible: false,
+ onCloseEnd: () => {
+ modal.destroy();
+ modalElement.remove();
+ }
+ }
+ );
+ let confirmElement = modalElement.querySelector('.action-button[data-action="confirm"]');
+ confirmElement.addEventListener('click', (event) => {
+ Requests.contributions.tesseract_ocr_pipeline_models.entity.delete(itemId);
+ });
+ modal.open();
break;
}
case 'view': {
diff --git a/app/templates/_scripts.html.j2 b/app/templates/_scripts.html.j2
index a97f1d97..6fef8d1a 100644
--- a/app/templates/_scripts.html.j2
+++ b/app/templates/_scripts.html.j2
@@ -58,7 +58,10 @@
filters='rjsmin',
output='gen/Requests.%(version)s.js',
'js/Requests/Requests.js',
- 'js/Requests/Contributions.js'
+ 'js/Requests/contributions/contributions.js',
+ 'js/Requests/contributions/spacy_nlp_pipeline_models.js',
+ 'js/Requests/contributions/tesseract_ocr_pipeline_models.js',
+ 'js/Requests/Corpora.js'
%}
{%- endassets %}
diff --git a/app/templates/contributions/contributions.html.j2 b/app/templates/contributions/contributions.html.j2
index 99147b56..efefcbbb 100644
--- a/app/templates/contributions/contributions.html.j2
+++ b/app/templates/contributions/contributions.html.j2
@@ -20,7 +20,7 @@
-
+
SpaCy NLP Pipeline Models
Here you can see and edit the models that you have created. You can also create new models.
diff --git a/app/templates/corpora/corpus.html.j2 b/app/templates/corpora/corpus.html.j2
index 172dac90..3174713f 100644
--- a/app/templates/corpora/corpus.html.j2
+++ b/app/templates/corpora/corpus.html.j2
@@ -68,7 +68,7 @@
publishPublishing
Social
@@ -131,6 +131,17 @@
+
+
+
Confirm Corpus deletion
+
Do you really want to delete the Corpus {{ corpus.title }}? All files will be permanently deleted!
+
+
+
+
Invite a nopaque user by username
@@ -215,13 +226,21 @@
let publishingModalIsPublicSwitchElement = document.querySelector('#publishing-modal-is-public-switch');
publishingModalIsPublicSwitchElement.addEventListener('change', (event) => {
let newIsPublic = publishingModalIsPublicSwitchElement.checked;
- Utils.updateCorpusIsPublicRequest(corpusId, newIsPublic)
+ Requests.corpora.corpus.isPublic.update(corpusId, newIsPublic)
.catch((response) => {
publishingModalIsPublicSwitchElement.checked = !newIsPublic;
});
});
// #endregion publishing_modal_js
+ // #region delete_modal_js
+ let deleteModalDeleteButtonElement = document.querySelector('#delete-modal-delete-button');
+ deleteModalDeleteButtonElement.addEventListener('click', (event) => {
+ Requests.corpora.corpus.delete(corpusId)
+ .then((response) => {window.location.href = '/dashboard';});
+ });
+ // #endregion delete_modal_js
+
// #region invite_user_modal_js
let inviteUserModalElement = document.querySelector('#invite-user-modal');
let inviteUserModalSearchElement = document.querySelector('#invite-user-modal-search');