Some fixes and improve jinja2 template performance by reducing include statements

This commit is contained in:
Patrick Jentsch 2024-11-19 15:28:43 +01:00
parent 54c4295bf7
commit 99d7a8bdfc
23 changed files with 654 additions and 630 deletions

View File

@ -1,25 +1,3 @@
/* #region sidenav-fixed */
/*
* The sidenav-fixed class is used which causes the sidenav to be fixed and open
* on large screens and hides to the regular functionality on smaller screens.
* In order to prevent the sidenav to overlap the content, the content (header, main and footer)
* gets an offset equal to the width of the sidenav.
*
* Read more: https://materializecss.com/sidenav.html#variations
*/
@media only screen and (min-width: 993px) {
body[data-sidenav-fixed="true" i] header,
body[data-sidenav-fixed="true" i] main,
body[data-sidenav-fixed="true" i] footer {
padding-left: 300px;
}
body[data-sidenav-fixed="true" i] .navbar-fixed > nav {
width: calc(100% - 300px);
}
}
/* #endregion sidenav-fixed */
/* #region sticky-footer */
/*
* Sticky Footer:
@ -32,13 +10,13 @@
*
* Read more: https://materializecss.com/footer.html#sticky-footer
*/
body[data-sticky-footer="true" i] {
body {
display: flex;
min-height: 100vh;
flex-direction: column;
}
body[data-sticky-footer="true" i] main {
main {
flex: 1 0 auto;
}
/* #endregion sticky-footer */

View File

@ -159,19 +159,21 @@ nopaque.App = class App {
// Header navigation processes and services Dropdown.
M.Dropdown.init(
document.querySelector('#nav-processes-and-services-dropdown-trigger'),
document.querySelector('#navbar-data-processing-and-analysis-dropdown-trigger'),
{
constrainWidth: false,
container: document.querySelector('#dropdowns'),
coverTrigger: false
}
);
// Header navigation account Dropdown.
M.Dropdown.init(
document.querySelector('#nav-account-dropdown-trigger'),
document.querySelector('#navbar-account-dropdown-trigger'),
{
alignment: 'right',
constrainWidth: false,
container: document.querySelector('#dropdowns'),
coverTrigger: false
}
);

View File

@ -1,52 +0,0 @@
<div id="data-processing-and-analysis-modal" class="modal">
<div class="modal-content">
<div class="card-panel primary-color white-text">
<h4 class="m-3"><i class="material-icons left" style="font-size: inherit; line-height: inherit;">miscellaneous_services</i>Data Processing & Analysis</h4>
</div>
<br>
<div class="row">
<div class="col s12 m6 l3 center-align hoverable" style="position: relative;">
<a href="{{ url_for('services.file_setup_pipeline') }}" style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;"></a>
<i class="large nopaque-icons service-icons service-color-text text-darken" data-service="file-setup-pipeline"></i>
<br>
<b class="service-color-text text-darken" data-service="file-setup-pipeline">File Setup</b>
<p class="light">Digital copies of text based research data (books, letters, etc.) often comprise various files and formats. nopaque converts and merges those files to facilitate further processing and the application of other services.</p>
</div>
<div class="col s12 m6 l3 center-align center-align hoverable" style="position: relative;">
<a href="{{ url_for('services.tesseract_ocr_pipeline') }}" style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;"></a>
<i class="large nopaque-icons service-icons service-color-text text-darken" data-service="tesseract-ocr-pipeline"></i>
<br>
<b class="service-color-text text-darken" data-service="tesseract-ocr-pipeline">Optical Character Recognition</b>
<p class="light">nopaque converts your image data like photos or scans into text data through OCR making it machine readable. This step enables you to proceed with further computational analysis of your documents.</p>
</div>
{% if config.NOPAQUE_TRANSKRIBUS_ENABLED %}
<div class="col s12 m6 l3 center-align center-align hoverable" style="position: relative;">
<a href="{{ url_for('services.transkribus_htr_pipeline') }}" style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;"></a>
<i class="large nopaque-icons service-icons service-color-text text-darken" data-service="transkribus-htr-pipeline"></i>
<br>
<b class="service-color-text text-darken" data-service="transkribus-htr-pipeline">Transkribus HTR Pipeline</b>
<p class="light">nopaque converts your image data like photos or scans into text data through HTR making it machine readable. This step enables you to proceed with further computational analysis of your documents.</p>
</div>
{% endif %}
<div class="col s12 m6 l3 center-align center-align hoverable" style="position: relative;">
<a href="{{ url_for('services.spacy_nlp_pipeline') }}" style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;"></a>
<i class="large nopaque-icons service-icons service-color-text text-darken" data-service="spacy-nlp-pipeline"></i>
<br>
<b class="service-color-text text-darken" data-service="spacy-nlp-pipeline">Natural Language Processing</b>
<p class="light">By means of computational linguistic data processing (tokenization, lemmatization, part-of-speech tagging and named-entity recognition) nopaque extracts additional information from your text.</p>
</div>
<div class="col s12 m6 l3 center-align center-align hoverable" style="position: relative;">
<a href="{{ url_for('services.corpus_analysis') }}" style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;"></a>
<i class="large nopaque-icons service-icons service-color-text text-darken" data-service="corpus-analysis"></i>
<br>
<b class="service-color-text text-darken" data-service="corpus-analysis">Corpus analysis</b>
<p class="light">nopaque lets you create and upload as many text corpora as you want. It makes use of CQP Query Language, which allows for complex search requests with the aid of metadata and NLP tags.</p>
</div>
</div>
</div>
<div class="modal-footer">
<a class="btn-flat modal-close">Close</a>
</div>
</div>

View File

@ -1,32 +0,0 @@
<div id="terms-of-use-modal" class="modal modal-fixed-footer">
<div class="modal-content">
<div class="container">
<div class="row">
<div class="col s12">
<h1 id="title">Terms of use</h1>
</div>
<div class="col s12">
<div class="switch">
<label>
DE
<input type="checkbox" id="terms-of-use-modal-switch">
<span class="lever"></span>
EN
</label>
</div>
<br>
</div>
<div class="terms-of-use-modal-content hide">
{% include "main/terms_of_use_en.html.j2" %}
</div>
<div class="terms-of-use-modal-content">
{% include "main/terms_of_use_de.html.j2" %}
</div>
</div>
</div>
</div>
<div class="modal-footer">
<span style="margin-right:20px;">I have taken note of the new GTC and agree to their validity in the context of my further use.</span>
<a href="#!" class="modal-close waves-effect waves-green btn">Yes</a>
</div>
</div>

View File

@ -1,9 +0,0 @@
{% if current_user.is_authenticated %}
<ul class="dropdown-content" id="nav-account-dropdown-content">
<li><a href="#!">Logged in as {{ current_user.username }}<br>&lt;{{ current_user.email }}&gt;</a></li>
<li class="divider" tabindex="-1"></li>
<li><a href="{{ url_for('users.user', user_id=current_user.id) }}"><i class="material-icons">person</i>Your profile</a></li>
<li><a href="{{ url_for('settings.settings') }}"><i class="material-icons left">settings</i>Settings</a></li>
<li><a href="{{ url_for('auth.logout') }}"><i class="material-icons left">logout</i>Log out</a></li>
</ul>
{% endif %}

View File

@ -1,40 +0,0 @@
<div class="container">
<div class="row">
<div class="col s6 m3">
<a href="https://www.dfg.de/">
<img class="responsive-img" src="{{ url_for('static', filename='images/logo_-_dfg.gif') }}">
</a>
</div>
<div class="col s6 m3 offset-m1 center-align">
<a href="https://www.uni-bielefeld.de/sfb1288/">
<img class="responsive-img" src="{{ url_for('static', filename='images/logo_-_sfb_1288.png') }}">
</a>
</div>
<div class="col s12 m3 offset-m1">
<h5 class="white-text">Legal Notice</h5>
<ul>
<li><a class="grey-text text-lighten-3" href="https://www.uni-bielefeld.de/(en)/impressum/">Legal Notice</a></li>
<li><a class="grey-text text-lighten-3" href="{{ url_for('main.privacy_policy') }}">Privacy statement (GDPR)</a></li>
<li><a class="grey-text text-lighten-3" href="{{ url_for('main.terms_of_use') }}">Terms of use</a></li>
<li></li>
</ul>
</div>
</div>
</div>
<div class="footer-copyright">
<div class="container">
<div class="row" style="margin-bottom: 0;">
<div class="col s12 m3">
<span>© 2020 Bielefeld University</span>
</div>
<div class="col s12 m2">
<span class="right"><b>Version {{ config.NOPAQUE_VERSION }}</b></span>
</div>
<div class="col s12 m7 right-align">
<a class="btn-small waves-effect waves-light" href="{{ url_for('main.faq') }}"><i class="left material-icons">info_outline</i>Frequently Asked Questions</a>
<a class="btn-small waves-effect waves-light" href="mailto:{{ config.NOPAQUE_SERVICE_DESK }}"><i class="left material-icons">mail</i>Report an issue</a>
<a class="btn-small waves-effect waves-light" href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque" target="_blank"><i class="left material-icons">code</i>GitLab</a>
</div>
</div>
</div>
</div>

View File

@ -1,2 +0,0 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

View File

@ -1,5 +0,0 @@
{% if current_user.is_authenticated and not current_user.terms_of_use_accepted %}
{% include "_base/_modals/terms_of_use.html.j2" %}
{% endif %}
{% include "_base/_modals/data-processing-and-analysis.html.j2" %}

View File

@ -1,95 +0,0 @@
{% if current_user.is_authenticated %}
{# menu icon #}
{# shown for small/medium devices #}
<a href="#!" class="sidenav-trigger" data-target="sidenav"><i class="material-icons">menu</i></a>
{# nopaque logo #}
{# shown for large devices #}
<a href="{{ url_for('main.index') }}" class="brand-logo hide-on-med-and-down" style="height: 100%;">
<img src="{{ url_for('static', filename='images/nopaque_-_logo.png') }}" alt="" class="mx-3 py-3" style="height: 100%;">
</a>
{# left aligned navigation items #}
{# shown for large devices #}
<ul class="hide-on-med-and-down" style="margin-left: calc(57px + 1.5rem);">
{# dashboard #}
<li {% if request.path == url_for('main.dashboard') %}class="active"{% endif %}>
<a href="{{ url_for('main.dashboard') }}">
<i class="material-icons left">dashboard</i>
Dashboard
</a>
</li>
{# processes & services #}
<li>
<a href="#data-processing-and-analysis-modal" class="modal-trigger">
<i class="material-icons left">miscellaneous_services</i>
Data Processing & Analysis
</a>
</li>
{# contributions #}
<li {% if request.path == url_for('contributions.index') %}class="active"{% endif %}>
<a href="{{ url_for('contributions.index') }}">
<i class="material-icons left">new_label</i>
Contributions
</a>
</li>
{# social #}
<li {% if request.path == url_for('main.social') %}class="active"{% endif %}>
<a href="{{ url_for('main.social') }}">
<i class="material-icons left">groups</i>
Social
</a>
</li>
</ul>
{% else %}
{# nopaque logo+wordmark+slogan #}
{# shown for large devices #}
<a href="{{ url_for('main.index') }}" class="brand-logo hide-on-med-and-down" style="height: 100%;">
<img src="{{ url_for('static', filename='images/nopaque_-_logo+wordmark+slogan.png') }}" alt="" class="mx-3 py-3" style="height: 100%;">
</a>
{% endif %}
{# nopaque logo+wordmark #}
{# small/medium devices #}
<a href="{{ url_for('main.index') }}" class="brand-logo center hide-on-large-only" style="height: 100%;">
<img src="{{ url_for('static', filename='images/nopaque_-_logo+wordmark.png') }}" alt="" class="py-3" style="height: 100%;">
</a>
{# right aligned navigation items #}
{# large devices #}
<ul class="right hide-on-med-and-down" style="height: 64px;">
{# manual #}
<li class="tooltipped {% if request.path == url_for('main.manual') %}active{% endif %}" data-position="bottom" data-tooltip="Manual">
<a href="{{ url_for('main.manual') }}">
<i class="material-icons">help_outline</i>
</a>
</li>
{# news #}
<li class="tooltipped {% if request.path == url_for('main.news') %}active{% endif %}" data-position="bottom" data-tooltip="News">
<a href="{{ url_for('main.news') }}">
<i class="material-icons">email</i>
</a>
</li>
{% if current_user.is_authenticated %}
{# avatar #}
<li style="height: 100%;">
<a href="#!" class="dropdown-trigger no-autoinit" data-target="nav-account-dropdown-content" id="nav-account-dropdown-trigger" style="height: 100%;">
<img src="{{ url_for('users.user_avatar', user_id=current_user.id) }}" alt="" class="circle py-3" style="height: 100%;">
</a>
</li>
{% else %}
{# log in #}
<li {% if request.path == url_for('auth.login') %}class="active"{% endif %}>
<a href="{{ url_for('auth.login') }}">Log in</a>
</li>
{# register #}
<li {% if request.path == url_for('auth.register') %}class="active"{% endif %}>
<a href="{{ url_for('auth.register') }}" class="waves-effect waves-light btn primary-color lighten">Register</a>
</li>
{% endif %}
</ul>

View File

@ -1,113 +0,0 @@
<script src="{{ url_for('static', filename='external/materialize/js/materialize.min.js') }}"></script>
<script src="{{ url_for('static', filename='external/JSON-Patch/js/fast-json-patch.min.js') }}"></script>
<script src="{{ url_for('static', filename='external/list.js/js/list.min.js') }}"></script>
<script src="{{ url_for('static', filename='external/pako/js/pako_inflate.min.js') }}"></script>
<script src="{{ url_for('static', filename='external/plotly.js/js/plotly.min.js') }}"></script>
<script src="{{ url_for('static', filename='external/socket.io/js/socket.io.min.js') }}"></script>
{% assets
filters='rjsmin',
output='gen/nopaque.%(version)s.js',
'js/index.js',
'js/app.js',
'js/utils.js',
'js/forms/index.js',
'js/forms/base-form.js',
'js/forms/create-contribution-form.js',
'js/forms/create-corpus-file-form.js',
'js/forms/create-job-form.js',
'js/resource-displays/index.js',
'js/resource-displays/resource-display.js',
'js/resource-displays/corpus-display.js',
'js/resource-displays/job-display.js',
'js/resource-lists/index.js',
'js/resource-lists/resource-list.js',
'js/resource-lists/admin-user-list.js',
'js/resource-lists/corpus-file-list.js',
'js/resource-lists/corpus-follower-list.js',
'js/resource-lists/corpus-list.js',
'js/resource-lists/corpus-text-info-list.js',
'js/resource-lists/corpus-token-list.js',
'js/resource-lists/detailed-public-corpus-list.js',
'js/resource-lists/job-input-list.js',
'js/resource-lists/job-list.js',
'js/resource-lists/job-result-list.js',
'js/resource-lists/public-corpus-list.js',
'js/resource-lists/public-user-list.js',
'js/resource-lists/spacy-nlp-pipeline-model-list.js',
'js/resource-lists/tesseract-ocr-pipeline-model-list.js',
'js/requests/index.js',
'js/requests/admin.js',
'js/requests/contributions.js',
'js/requests/corpora.js',
'js/requests/jobs.js',
'js/requests/users.js',
'js/corpus-analysis/index.js',
'js/corpus-analysis/cqi/index.js',
'js/corpus-analysis/cqi/constants.js',
'js/corpus-analysis/cqi/errors.js',
'js/corpus-analysis/cqi/status.js',
'js/corpus-analysis/cqi/api/index.js',
'js/corpus-analysis/cqi/api/client.js',
'js/corpus-analysis/cqi/models/index.js',
'js/corpus-analysis/cqi/models/resource.js',
'js/corpus-analysis/cqi/models/attributes.js',
'js/corpus-analysis/cqi/models/subcorpora.js',
'js/corpus-analysis/cqi/models/corpora.js',
'js/corpus-analysis/cqi/client.js',
'js/corpus-analysis/query-builder/index.js',
'js/corpus-analysis/query-builder/element-references.js',
'js/corpus-analysis/query-builder/query-builder.js',
'js/corpus-analysis/query-builder/structural-attribute-builder-functions.js',
'js/corpus-analysis/query-builder/token-attribute-builder-functions.js',
'js/corpus-analysis/app.js',
'js/corpus-analysis/concordance-extension.js',
'js/corpus-analysis/reader-extension.js',
'js/corpus-analysis/static-visualization-extension.js'
-%}
<script src="{{ ASSET_URL }}"></script>
{% endassets -%}
<script>
// TODO: Implement an app.run method and use this for all of the following
const app = new nopaque.App();
app.init();
{% if current_user.is_authenticated -%}
// TODO: Set this as a property of the app object
const currentUserId = {{ current_user.hashid|tojson }};
// Subscribe to the current user's data events
app.subscribeUser(currentUserId)
.catch((error) => {throw JSON.stringify(error);});
// Get the current user's data
app.getUser(currentUserId, true, true)
.catch((error) => {throw JSON.stringify(error);});
{% if not current_user.terms_of_use_accepted -%}
M.Modal.getInstance(document.querySelector('#terms-of-use-modal')).open();
{% endif -%}
{% endif -%}
// Display flashed messages
for (let [category, message] of {{ get_flashed_messages(with_categories=True)|tojson }}) {
app.flash(message, message);
}
</script>
<script>
let languageModalSwitch = document.querySelector('#terms-of-use-modal-switch');
let termsOfUseModalContent = document.querySelectorAll('.terms-of-use-modal-content');
if (languageModalSwitch) {
languageModalSwitch.addEventListener('change', function() {
termsOfUseModalContent.forEach(content => {
content.classList.toggle('hide');
});
});
}
</script>

View File

@ -1,77 +0,0 @@
<ul class="sidenav {{ 'sidenav-fixed' if sidenav_fixed else '' }}" id="sidenav">
{# user view #}
<li>
<div class="user-view">
<div class="background primary-color"></div>
<a><img class="circle" src="{{ url_for('users.user_avatar', user_id=current_user.id) }}" alt=""></a>
<a><span class="white-text name">{{ current_user.username }}</span></a>
<a><span class="white-text email">{{ current_user.email }}</span></a>
</div>
</li>
{# general items #}
<li {% if request.path == url_for('main.news') %}class="active"{% endif %}>
<a class="waves-effect" href="{{ url_for('main.news') }}"><i class="material-icons">email</i>News</a>
</li>
<li {% if request.path == url_for('main.dashboard') %}class="active"{% endif %}>
<a class="waves-effect" href="{{ url_for('main.dashboard') }}"><i class="material-icons">dashboard</i>Dashboard</a>
</li>
<li {% if request.path == url_for('contributions.index') %}class="active"{% endif %}>
<a href="{{ url_for('contributions.index') }}">
<i class="material-icons left">new_label</i>
Contributions
</a>
</li>
<li {% if request.path == url_for('main.social') %}class="active"{% endif %}>
<a class="waves-effect" href="{{ url_for('main.social') }}"><i class="material-icons">groups</i>Social</a>
</li>
<li {% if request.path == url_for('main.manual') %}class="active"{% endif %}>
<a class="waves-effect" href="{{ url_for('main.manual') }}"><i class="material-icons">help_outline</i>Manual</a>
</li>
{# processes & services items #}
<li><div class="divider"></div></li>
<li><a class="subheader">Data Processing & Analysis</a></li>
<li class="service-color service-color-border border-darken" data-service="file-setup-pipeline" style="border-left: 10px solid;">
<a class="waves-effect" href="{{ url_for('services.file_setup_pipeline') }}"><i class="nopaque-icons service-icons" data-service="file-setup-pipeline"></i>File setup</a>
</li>
<li class="service-color service-color-border border-darken mt-1" data-service="tesseract-ocr-pipeline" style="border-left: 10px solid;">
<a class="waves-effect" href="{{ url_for('services.tesseract_ocr_pipeline') }}"><i class="nopaque-icons service-icons" data-service="tesseract-ocr-pipeline"></i>OCR</a>
</li>
{% if config.NOPAQUE_TRANSKRIBUS_ENABLED %}
<li class="service-color service-color-border border-darken mt-1" data-service="transkribus-htr-pipeline" style="border-left: 10px solid;">
<a class="waves-effect" href="{{ url_for('services.transkribus_htr_pipeline') }}"><i class="nopaque-icons service-icons" data-service="transkribus-htr-pipeline"></i>HTR</a>
</li>
{% endif %}
<li class="service-color service-color-border border-darken mt-1" data-service="spacy-nlp-pipeline" style="border-left: 10px solid;">
<a class="waves-effect" href="{{ url_for('services.spacy_nlp_pipeline') }}"><i class="nopaque-icons service-icons" data-service="spacy-nlp-pipeline"></i>NLP</a>
</li>
<li class="service-color service-color-border border-darken mt-1" data-service="corpus-analysis" style="border-left: 10px solid;">
<a class="waves-effect" href="{{ url_for('services.corpus_analysis') }}"><i class="nopaque-icons service-icons" data-service="corpus-analysis"></i>Corpus Analysis</a>
</li>
{# account items #}
<li class="hide-on-large-only"><div class="divider"></div></li>
<li class="hide-on-large-only"><a class="subheader">Account</a></li>
<li>
<a href="{{ url_for('users.user', user_id=current_user.id) }}"><i class="material-icons">person</i>My Profile</a>
</li>
<li class="hide-on-large-only">
<a class="waves-effect" href="{{ url_for('settings.settings') }}"><i class="material-icons">settings</i>Settings</a>
</li>
<li class="hide-on-large-only">
<a class="waves-effect" href="{{ url_for('auth.logout') }}"><i class="material-icons">logout</i>Log out</a>
</li>
{# administration items #}
{% if current_user.can('ADMINISTRATE') %}
<li><div class="divider"></div></li>
<li><a class="subheader">Administration</a></li>
<li>
<a class="waves-effect" href="{{ url_for('admin.corpora') }}"><i class="nopaque-icons">I</i>Corpora</a>
</li>
<li>
<a class="waves-effect" href="{{ url_for('admin.users') }}"><i class="material-icons">manage_accounts</i>Users</a>
</li>
{% endif %}
</ul>

View File

@ -1,21 +0,0 @@
<link href="{{ url_for('static', filename='external/material-design-icons/css/material-icons.css') }}" rel="stylesheet">
{% assets
output='gen/nopaque.%(version)s.css',
'css/materialize.css',
'css/materialize.override.css',
'css/nopaque-icons.css',
'css/theme-colors.css',
'css/corpus-status-colors.css',
'css/corpus-status-text.css',
'css/job-status-colors.css',
'css/job-status-text.css',
'css/service-colors.css',
'css/pagination.css',
'css/service-icons.css',
'css/s-attr-colors.css',
'css/spacing.css',
'css/status-spinner.css',
'css/utils.css'
-%}
<link href="{{ ASSET_URL }}" rel="stylesheet">
{% endassets -%}

View File

@ -30,6 +30,7 @@
{{ wtf.render_field(form.submit, class_='width-100', material_icon='send') }}
</div>
</form>
</div>
</div>
</div>
{% endblock page_content %}

View File

@ -1,106 +1,544 @@
{% if title is not defined %}
{% set title = 'nopaque' %}
{% endif %}
{% if sidenav_fixed is not defined %}
{% set sidenav_fixed = false %}
{% endif %}
{% if sticky_footer is not defined %}
{% set sticky_footer = true %}
{% endif %}
{% if navbar_fixed is not defined %}
{% set navbar_fixed = true %}
{% endif %}
{% if navbar_extended is not defined %}
{% set navbar_extended = false %}
{% endif %}
{% block doc %}
<!DOCTYPE html>
<html {% block html_attribs %}lang="en"{% endblock html_attribs %}>
{% block html %}
<html lang="en">
<head>
{% block head %}
{% block metas %}
{% include "_base/metas.html.j2" %}
{% endblock metas %}
<!-- #region meta -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- #endregion meta -->
<title {% block title_attribs %}{% endblock title_attribs %}>
{%- block title %}{{ title }}{% endblock title -%}
</title>
<title>{{ title if title is defined else 'nopaque' }}</title>
<link href="{{ url_for('static', filename='images/nopaque_-_favicon.png') }}" rel="icon">
<!-- #region stylesheets -->
{% block stylesheets %}
{% include "_base/stylesheets.html.j2" %}
<link href="{{ url_for('static', filename='external/material-design-icons/css/material-icons.css') }}" rel="stylesheet">
{% assets
output='gen/nopaque.%(version)s.css',
'css/materialize.css',
'css/materialize.override.css',
'css/nopaque-icons.css',
'css/theme-colors.css',
'css/corpus-status-colors.css',
'css/corpus-status-text.css',
'css/job-status-colors.css',
'css/job-status-text.css',
'css/service-colors.css',
'css/pagination.css',
'css/service-icons.css',
'css/s-attr-colors.css',
'css/spacing.css',
'css/status-spinner.css',
'css/utils.css'
-%}
<link href="{{ ASSET_URL }}" rel="stylesheet">
{% endassets -%}
{% endblock stylesheets %}
{% endblock head %}
<!-- #endregion stylesheets -->
</head>
<body {% block body_attribs %}data-sidenav-fixed="{{ sidenav_fixed }}" data-sticky-footer="{{ sticky_footer }}"{% endblock body_attribs %}>
{% block body %}
<header {% block header_attribs %}{% endblock header_attribs %}>
{% block header %}
{% if navbar_fixed %}
<body>
<header>
<div class="navbar-fixed">
{% endif %}
<nav {% block navbar_attribs %}{% if navbar_extended %}class="nav-extended"{% endif %}{% endblock navbar_attribs %}>
{% block navbar %}
<div {% block navbar_primary_content_attribs %}class="nav-wrapper"{% endblock navbar_primary_content_attribs %}>
{% block navbar_primary_content %}
{% include "_base/navbar_primary_content.html.j2" %}
{% endblock navbar_primary_content %}
<nav>
<div class="nav-wrapper">
{# menu icon #}
{# small/medium devices #}
<a href="#!" class="sidenav-trigger" data-target="sidenav"><i class="material-icons">menu</i></a>
{% if current_user.is_authenticated %}
{# nopaque logo #}
{# large devices #}
<a href="{{ url_for('main.index') }}" class="brand-logo hide-on-med-and-down" style="height: 100%;">
<img src="{{ url_for('static', filename='images/nopaque_-_logo.png') }}" alt="" class="mx-3 py-3" style="height: 100%;">
</a>
{# left aligned navigation items #}
{# large devices #}
<ul class="hide-on-med-and-down" style="margin-left: calc(57px + 1.5rem);">
{# dashboard #}
<li {% if request.path == url_for('main.dashboard') %}class="active"{% endif %}>
<a href="{{ url_for('main.dashboard') }}">
<i class="material-icons left">dashboard</i>
Dashboard
</a>
</li>
{# data processing & analysis #}
<li>
<a href="#!" class="dropdown-trigger no-autoinit" data-target="navbar-data-processing-and-analysis-dropdown-content" id="navbar-data-processing-and-analysis-dropdown-trigger">
<i class="material-icons left">miscellaneous_services</i>
Data Processing & Analysis
</a>
</li>
{# contributions #}
<li {% if request.path == url_for('contributions.index') %}class="active"{% endif %}>
<a href="{{ url_for('contributions.index') }}">
<i class="material-icons left">new_label</i>
Contributions
</a>
</li>
{# social #}
<li {% if request.path == url_for('main.social') %}class="active"{% endif %}>
<a href="{{ url_for('main.social') }}">
<i class="material-icons left">groups</i>
Social
</a>
</li>
</ul>
{% else %}
{# nopaque logo+wordmark+slogan #}
{# large devices #}
<a href="{{ url_for('main.index') }}" class="brand-logo hide-on-med-and-down" style="height: 100%;">
<img src="{{ url_for('static', filename='images/nopaque_-_logo+wordmark+slogan.png') }}" alt="" class="mx-3 py-3" style="height: 100%;">
</a>
{% endif %}
{# nopaque logo+wordmark #}
{# small/medium devices #}
<a href="{{ url_for('main.index') }}" class="brand-logo center hide-on-large-only" style="height: 100%;">
<img src="{{ url_for('static', filename='images/nopaque_-_logo+wordmark.png') }}" alt="" class="py-3" style="height: 100%;">
</a>
{# right aligned navigation items #}
{# large devices #}
<ul class="right hide-on-med-and-down" style="height: 64px;">
{# manual #}
<li class="tooltipped {% if request.path == url_for('main.manual') %}active{% endif %}" data-position="bottom" data-tooltip="Manual">
<a href="{{ url_for('main.manual') }}">
<i class="material-icons">help_outline</i>
</a>
</li>
{# news #}
<li class="tooltipped {% if request.path == url_for('main.news') %}active{% endif %}" data-position="bottom" data-tooltip="News">
<a href="{{ url_for('main.news') }}">
<i class="material-icons">newspaper</i>
</a>
</li>
{% if current_user.is_authenticated %}
{# avatar #}
<li style="height: 100%;">
<a href="#!" class="dropdown-trigger no-autoinit" data-target="navbar-account-dropdown-content" id="navbar-account-dropdown-trigger" style="height: 100%;">
<span class="mr-3">{{ current_user.username }}</span>
<img src="{{ url_for('users.user_avatar', user_id=current_user.id) }}" alt="" class="circle py-3 right" style="height: 100%;">
</a>
</li>
{% else %}
{# log in #}
<li {% if request.path == url_for('auth.login') %}class="active"{% endif %}>
<a href="{{ url_for('auth.login') }}">Log in</a>
</li>
{# register #}
<li {% if request.path == url_for('auth.register') %}class="active"{% endif %}>
<a href="{{ url_for('auth.register') }}" class="btn waves-effect waves-light primary-color lighten">Register</a>
</li>
{% endif %}
</ul>
</div>
{% if navbar_extended %}
<div {% block navbar_secondary_content_attribs %}class="nav-content"{% endblock navbar_secondary_content_attribs %}>
{% block navbar_secondary_content %}
{% endblock navbar_secondary_content %}
</div>
{% endif %}
{% endblock navbar %}
</nav>
{% if navbar_fixed %}
</div>
{% endif %}
{% block sidenav %}
{% if current_user.is_authenticated %}
{% include "_base/sidenav.html.j2" %}
{% endif %}
{% endblock sidenav %}
{% endblock header %}
<ul class="sidenav" id="sidenav">
{% if current_user.is_authenticated %}
{# user view #}
<li>
<div class="user-view">
<div class="background primary-color"></div>
<a><img class="circle" src="{{ url_for('users.user_avatar', user_id=current_user.id) }}" alt=""></a>
<a><span class="white-text name">{{ current_user.username }}</span></a>
<a><span class="white-text email">{{ current_user.email }}</span></a>
</div>
</li>
{% endif %}
{% if current_user.is_authenticated %}
{# dashboard #}
<li {% if request.path == url_for('main.dashboard') %}class="active"{% endif %}>
<a class="waves-effect" href="{{ url_for('main.dashboard') }}"><i class="material-icons">dashboard</i>Dashboard</a>
</li>
{# contributions #}
<li {% if request.path == url_for('contributions.index') %}class="active"{% endif %}>
<a href="{{ url_for('contributions.index') }}">
<i class="material-icons left">new_label</i>
Contributions
</a>
</li>
{# social #}
<li {% if request.path == url_for('main.social') %}class="active"{% endif %}>
<a class="waves-effect" href="{{ url_for('main.social') }}"><i class="material-icons">groups</i>Social</a>
</li>
{% endif %}
{# news #}
<li {% if request.path == url_for('main.news') %}class="active"{% endif %}>
<a class="waves-effect" href="{{ url_for('main.news') }}"><i class="material-icons">newspaper</i>News</a>
</li>
{# manual #}
<li {% if request.path == url_for('main.manual') %}class="active"{% endif %}>
<a class="waves-effect" href="{{ url_for('main.manual') }}"><i class="material-icons">help_outline</i>Manual</a>
</li>
{% if current_user.is_authenticated %}
{# data processing & analysis section #}
<li><div class="divider"></div></li>
<li><a class="subheader">Data Processing & Analysis</a></li>
{# file setup pipeline #}
<li class="service-color service-color-border border-darken" data-service="file-setup-pipeline" style="border-left: 10px solid;">
<a class="waves-effect" href="{{ url_for('services.file_setup_pipeline') }}"><i class="nopaque-icons service-icons" data-service="file-setup-pipeline"></i>File setup</a>
</li>
{# tesseract ocr pipeline #}
<li class="service-color service-color-border border-darken mt-1" data-service="tesseract-ocr-pipeline" style="border-left: 10px solid;">
<a class="waves-effect" href="{{ url_for('services.tesseract_ocr_pipeline') }}"><i class="nopaque-icons service-icons" data-service="tesseract-ocr-pipeline"></i>OCR</a>
</li>
{% if config.NOPAQUE_TRANSKRIBUS_ENABLED %}
{# transkribus htr pipeline #}
<li class="service-color service-color-border border-darken mt-1" data-service="transkribus-htr-pipeline" style="border-left: 10px solid;">
<a class="waves-effect" href="{{ url_for('services.transkribus_htr_pipeline') }}"><i class="nopaque-icons service-icons" data-service="transkribus-htr-pipeline"></i>HTR</a>
</li>
{% endif %}
{# spacy nlp pipeline #}
<li class="service-color service-color-border border-darken mt-1" data-service="spacy-nlp-pipeline" style="border-left: 10px solid;">
<a class="waves-effect" href="{{ url_for('services.spacy_nlp_pipeline') }}"><i class="nopaque-icons service-icons" data-service="spacy-nlp-pipeline"></i>NLP</a>
</li>
{# corpus analysis #}
<li class="service-color service-color-border border-darken mt-1" data-service="corpus-analysis" style="border-left: 10px solid;">
<a class="waves-effect" href="{{ url_for('services.corpus_analysis') }}"><i class="nopaque-icons service-icons" data-service="corpus-analysis"></i>Corpus Analysis</a>
</li>
{% endif %}
{# account section #}
<li><div class="divider"></div></li>
<li><a class="subheader">Account</a></li>
{% if current_user.is_authenticated %}
{# my profile #}
<li {% if request.path == url_for('users.user', user_id=current_user.id) %}class="active"{% endif %}>
<a href="{{ url_for('users.user', user_id=current_user.id) }}"><i class="material-icons">person</i>My Profile</a>
</li>
{# settings #}
<li {% if request.path == url_for('settings.settings') %}class="active"{% endif %}>
<a class="waves-effect" href="{{ url_for('settings.settings') }}"><i class="material-icons">settings</i>Settings</a>
</li>
{# log out #}
<li>
<a class="waves-effect" href="{{ url_for('auth.logout') }}"><i class="material-icons">logout</i>Log out</a>
</li>
{% else %}
{# log in #}
<li {% if request.path == url_for('auth.login') %}class="active"{% endif %}>
<a href="{{ url_for('auth.login') }}">Log in</a>
</li>
{# register #}
<li {% if request.path == url_for('auth.register') %}class="active"{% endif %}>
<a href="{{ url_for('auth.register') }}" class="btn waves-effect waves-light">Register</a>
</li>
{% endif %}
{% if current_user.is_authenticated and current_user.can('ADMINISTRATE') %}
{# administration section #}
<li><div class="divider"></div></li>
<li><a class="subheader">Administration</a></li>
{# corpora #}
<li>
<a class="waves-effect" href="{{ url_for('admin.corpora') }}"><i class="nopaque-icons">I</i>Corpora</a>
</li>
{# users #}
<li>
<a class="waves-effect" href="{{ url_for('admin.users') }}"><i class="material-icons">manage_accounts</i>Users</a>
</li>
{% endif %}
</ul>
</header>
<main {% block main_attribs %}{% endblock main_attribs %}>
{% block main %}
{% block page_content %}{% endblock page_content %}
{% endblock main %}
<div id="dropdowns">
{% block dropdowns %}
{% include "_base/dropdowns.html.j2" %}
{% endblock dropdowns %}
</div>
<div id="modals">
{% block modals %}
{% include "_base/modals.html.j2" %}
{% endblock modals %}
</div>
</main>
<footer {% block footer_attribs %}class="page-footer"{% endblock footer_attribs %}>
{% block footer %}
{% include "_base/footer.html.j2" %}
{% endblock footer %}
<footer class="page-footer">
<div class="container">
<div class="row">
<div class="col s12 l3">
<h5 class="white-text">Legal Notice</h5>
<ul>
<li><a class="grey-text text-lighten-3" href="https://www.uni-bielefeld.de/(en)/impressum/">Legal Notice</a></li>
<li><a class="grey-text text-lighten-3" href="{{ url_for('main.privacy_policy') }}">Privacy statement (GDPR)</a></li>
<li><a class="grey-text text-lighten-3" href="{{ url_for('main.terms_of_use') }}">Terms of use</a></li>
</ul>
</div>
<div class="col s12 l3">
<h5 class="white-text">More Resources</h5>
<ul>
<li><a class="grey-text text-lighten-3" href="{{ url_for('main.faq') }}">Frequently asked questions</a></li>
<li><a class="grey-text text-lighten-3" href="mailto:{{ config.NOPAQUE_SERVICE_DESK }}">Report an issue</a></li>
<li><a class="grey-text text-lighten-3" href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque">GitLab (source code)</a></li>
</ul>
</div>
<div class="col s12 l4">
<h5 class="white-text">Who made this?</h5>
<p class="grey-text text-lighten-4">
This software is developed by the SFB 1288 INF project at Bielefeld University.
Thanks to all the people who made nopaque possible.
<span class="red-text">&hearts;</span>
</p>
</div>
<div class="col s12 l2">
<br class="hide-on-med-and-down">
<br class="hide-on-med-and-down">
<a href="https://www.dfg.de/">
<img class="responsive-img" src="{{ url_for('static', filename='images/logo_-_dfg.gif') }}">
</a>
</div>
</div>
</div>
<div class="footer-copyright">
<div class="container">
© 2024 Bielefeld University
<a class="grey-text text-lighten-4 right" href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque/-/releases/{{ config.NOPAQUE_VERSION }}">Version {{ config.NOPAQUE_VERSION }}</a>
</div>
</div>
</footer>
<div id="dropdowns">
{% block dropdowns %}
{% if current_user.is_authenticated %}
<ul class="dropdown-content" id="navbar-data-processing-and-analysis-dropdown-content">
<li {% if request.path == url_for('services.file_setup_pipeline') %}class="active"{% endif %}>
<a href="{{ url_for('services.file_setup_pipeline') }}">
<i class="nopaque-icons service-icons service-color-text text-darken" data-service="file-setup-pipeline"></i>
File Setup Pipeline
</a>
</li>
<li {% if request.path == url_for('services.tesseract_ocr_pipeline') %}class="active"{% endif %}>
<a href="{{ url_for('services.tesseract_ocr_pipeline') }}">
<i class="nopaque-icons service-icons service-color-text text-darken" data-service="tesseract-ocr-pipeline"></i>
Tesseract OCR Pipeline
</a>
</li>
{% if config.NOPAQUE_TRANSKRIBUS_ENABLED %}
<li {% if request.path == url_for('services.transkribus_htr_pipeline') %}class="active"{% endif %}>
<a href="{{ url_for('services.transkribus_htr_pipeline') }}">
<i class="nopaque-icons service-icons service-color-text text-darken" data-service="transkribus-htr-pipeline"></i>
Transkribus HTR Pipeline
</a>
</li>
{% endif %}
<li {% if request.path == url_for('services.spacy_nlp_pipeline') %}class="active"{% endif %}>
<a href="{{ url_for('services.spacy_nlp_pipeline') }}">
<i class="nopaque-icons service-icons service-color-text text-darken" data-service="spacy-nlp-pipeline"></i>
SpaCy NLP Pipeline
</a>
</li>
<li class="divider" tabindex="-1"></li>
<li {% if request.path == url_for('services.corpus_analysis') %}class="active"{% endif %}>
<a href="{{ url_for('services.corpus_analysis') }}">
<i class="nopaque-icons service-icons service-color-text text-darken" data-service="corpus-analysis"></i>
Corpus Analyis
</a>
</li>
</ul>
{% endif %}
{% if current_user.is_authenticated %}
<ul class="dropdown-content" id="navbar-account-dropdown-content">
<li {% if request.path == url_for('users.user', user_id=current_user.id) %}class="active"{% endif %}>
<a href="{{ url_for('users.user', user_id=current_user.id) }}">
<i class="material-icons">person</i>
Your profile
</a>
</li>
<li {% if request.path == url_for('settings.settings') %}class="active"{% endif %}>
<a href="{{ url_for('settings.settings') }}">
<i class="material-icons">settings</i>
Settings
</a>
</li>
<li>
<a href="{{ url_for('auth.logout') }}">
<i class="material-icons">logout</i>
Log out
</a>
</li>
</ul>
{% endif %}
{% endblock dropdowns %}
</div>
<div id="modals">
{% block modals %}
{% if current_user.is_authenticated and not current_user.terms_of_use_accepted %}
<div id="terms-of-use-modal" class="modal modal-fixed-footer">
<div class="modal-content">
<div class="container">
<div class="row">
<div class="col s12">
<h1 id="title">Terms of use</h1>
</div>
<div class="col s12">
<div class="switch">
<label>
DE
<input type="checkbox" id="terms-of-use-modal-switch">
<span class="lever"></span>
EN
</label>
</div>
<br>
</div>
<div class="terms-of-use-modal-content hide">
{% include "main/terms_of_use_en.html.j2" %}
</div>
<div class="terms-of-use-modal-content">
{% include "main/terms_of_use_de.html.j2" %}
</div>
</div>
</div>
</div>
<div class="modal-footer">
<span style="margin-right:20px;">I have taken note of the new GTC and agree to their validity in the context of my further use.</span>
<a href="#!" class="modal-close waves-effect waves-green btn">Yes</a>
</div>
</div>
{% endif %}
{% endblock modals %}
</div>
<!-- #region scripts -->
{% block scripts %}
{% include "_base/scripts.html.j2" %}
<script src="{{ url_for('static', filename='external/materialize/js/materialize.min.js') }}"></script>
<script src="{{ url_for('static', filename='external/JSON-Patch/js/fast-json-patch.min.js') }}"></script>
<script src="{{ url_for('static', filename='external/list.js/js/list.min.js') }}"></script>
<script src="{{ url_for('static', filename='external/pako/js/pako_inflate.min.js') }}"></script>
<script src="{{ url_for('static', filename='external/plotly.js/js/plotly.min.js') }}"></script>
<script src="{{ url_for('static', filename='external/socket.io/js/socket.io.min.js') }}"></script>
{% assets
filters='rjsmin',
output='gen/nopaque.%(version)s.js',
'js/index.js',
'js/app.js',
'js/utils.js',
'js/forms/index.js',
'js/forms/base-form.js',
'js/forms/create-contribution-form.js',
'js/forms/create-corpus-file-form.js',
'js/forms/create-job-form.js',
'js/resource-displays/index.js',
'js/resource-displays/resource-display.js',
'js/resource-displays/corpus-display.js',
'js/resource-displays/job-display.js',
'js/resource-lists/index.js',
'js/resource-lists/resource-list.js',
'js/resource-lists/admin-user-list.js',
'js/resource-lists/corpus-file-list.js',
'js/resource-lists/corpus-follower-list.js',
'js/resource-lists/corpus-list.js',
'js/resource-lists/corpus-text-info-list.js',
'js/resource-lists/corpus-token-list.js',
'js/resource-lists/detailed-public-corpus-list.js',
'js/resource-lists/job-input-list.js',
'js/resource-lists/job-list.js',
'js/resource-lists/job-result-list.js',
'js/resource-lists/public-corpus-list.js',
'js/resource-lists/public-user-list.js',
'js/resource-lists/spacy-nlp-pipeline-model-list.js',
'js/resource-lists/tesseract-ocr-pipeline-model-list.js',
'js/requests/index.js',
'js/requests/admin.js',
'js/requests/contributions.js',
'js/requests/corpora.js',
'js/requests/jobs.js',
'js/requests/users.js',
'js/corpus-analysis/index.js',
'js/corpus-analysis/cqi/index.js',
'js/corpus-analysis/cqi/constants.js',
'js/corpus-analysis/cqi/errors.js',
'js/corpus-analysis/cqi/status.js',
'js/corpus-analysis/cqi/api/index.js',
'js/corpus-analysis/cqi/api/client.js',
'js/corpus-analysis/cqi/models/index.js',
'js/corpus-analysis/cqi/models/resource.js',
'js/corpus-analysis/cqi/models/attributes.js',
'js/corpus-analysis/cqi/models/subcorpora.js',
'js/corpus-analysis/cqi/models/corpora.js',
'js/corpus-analysis/cqi/client.js',
'js/corpus-analysis/query-builder/index.js',
'js/corpus-analysis/query-builder/element-references.js',
'js/corpus-analysis/query-builder/query-builder.js',
'js/corpus-analysis/query-builder/structural-attribute-builder-functions.js',
'js/corpus-analysis/query-builder/token-attribute-builder-functions.js',
'js/corpus-analysis/app.js',
'js/corpus-analysis/concordance-extension.js',
'js/corpus-analysis/reader-extension.js',
'js/corpus-analysis/static-visualization-extension.js'
-%}
<script src="{{ ASSET_URL }}"></script>
{% endassets -%}
<script>
// TODO: Implement an app.run method and use this for all of the following
const app = new nopaque.App();
app.init();
{% if current_user.is_authenticated -%}
// TODO: Set this as a property of the app object
const currentUserId = {{ current_user.hashid|tojson }};
// Subscribe to the current user's data events
app.subscribeUser(currentUserId)
.catch((error) => {throw JSON.stringify(error);});
// Get the current user's data
app.getUser(currentUserId, true, true)
.catch((error) => {throw JSON.stringify(error);});
{% if not current_user.terms_of_use_accepted -%}
M.Modal.getInstance(document.querySelector('#terms-of-use-modal')).open();
{% endif -%}
{% endif -%}
// Display flashed messages
for (let [category, message] of {{ get_flashed_messages(with_categories=True)|tojson }}) {
app.flash(message, message);
}
</script>
<script>
let languageModalSwitch = document.querySelector('#terms-of-use-modal-switch');
let termsOfUseModalContent = document.querySelectorAll('.terms-of-use-modal-content');
if (languageModalSwitch) {
languageModalSwitch.addEventListener('change', function() {
termsOfUseModalContent.forEach(content => {
content.classList.toggle('hide');
});
});
}
</script>
{% endblock scripts %}
{% endblock body %}
<!-- #endregion scripts -->
</body>
{% endblock html %}
</html>
{% endblock doc %}

View File

@ -72,6 +72,9 @@
{{ super() }}
<div class="modal no-autoinit" id="corpus-analysis-init-modal">
<div class="modal-content">
<div class="card-panel service-color darken white-text" data-service="corpus-analysis">
<h4 class="m-3"><i class="material-icons left" style="font-size: inherit; line-height: inherit;">hourglass_empty</i>We are preparing your analysis session</h4>
</div>
<h4>We are preparing your analysis session</h4>
<p>
Our server works as hard as it can to prepare your analysis session. Please be patient and give it some time.<br>

View File

@ -46,7 +46,7 @@
</div>
</div>
</div>
{% if cfr.has_permission('VIEW') %}
<div class="col s12 l5">
<div class="card">
@ -151,9 +151,9 @@
<div class="modal-content">
<h4>Invite a nopaque user by username</h4>
<p>
Add other nopaque users as followers to your corpus. You can also add multiple
users at the same time. Added users get the role of "viewer"
by default, so they are only allowed to analyze files within nopaque, but not
Add other nopaque users as followers to your corpus. You can also add multiple
users at the same time. Added users get the role of "viewer"
by default, so they are only allowed to analyze files within nopaque, but not
to download or edit them. You can customize the roles later below.
</p>
<p><b>Please make sure that the invited users are legally allowed to view the included corpus files.</b></p>
@ -176,8 +176,8 @@
<div class="modal-content">
<h4>Create a link to share your corpus</h4>
<p>
With the link other users follow your corpus directly, if it has not expired.
You can set different roles via the link, you can also edit them later in the menu below.
With the link other users follow your corpus directly, if it has not expired.
You can set different roles via the link, you can also edit them later in the menu below.
It is recommended not to set the expiration date of the link too far.
</p>
<p><b>Please make sure that the invited users are legally allowed to view the included corpus files.</b></p>
@ -367,7 +367,7 @@ shareLinkModalOutputCopyButtonElement.addEventListener('click', (event) => {
() => {app.flash('Copied!');},
() => {app.flash('Could not copy to clipboard. Please copy manually.', 'error');}
);
});
// #endregion Share link
{% endif %}

View File

@ -85,7 +85,7 @@
</div>
</div>
</div>
{% endif %}
{% endif %}
<div class="col s12">
<div class="card">
@ -161,9 +161,9 @@
<div class="modal-content">
<h4>Invite a nopaque user by username</h4>
<p>
Add other nopaque users as followers to your corpus. You can also add multiple
users at the same time. Added users get the role of "viewer"
by default, so they are only allowed to analyze files within nopaque, but not
Add other nopaque users as followers to your corpus. You can also add multiple
users at the same time. Added users get the role of "viewer"
by default, so they are only allowed to analyze files within nopaque, but not
to download or edit them. You can customize the roles later below.
</p>
<p><b>Please make sure that the invited users are legally allowed to view the included corpus files.</b></p>
@ -186,8 +186,8 @@
<div class="modal-content">
<h4>Create a link to share your corpus</h4>
<p>
With the link other users follow your corpus directly, if it has not expired.
You can set different roles via the link, you can also edit them later in the menu below.
With the link other users follow your corpus directly, if it has not expired.
You can set different roles via the link, you can also edit them later in the menu below.
It is recommended not to set the expiration date of the link too far.
</p>
<p><b>Please make sure that the invited users are legally allowed to view the included corpus files.</b></p>
@ -399,7 +399,7 @@ shareLinkModalOutputCopyButtonElement.addEventListener('click', (event) => {
() => {app.flash('Copied!');},
() => {app.flash('Could not copy to clipboard. Please copy manually.', 'error');}
);
});
// #endregion Share link
{% endif %}

View File

@ -41,10 +41,58 @@
<div class="job-list" data-user-id="{{ current_user.hashid }}"></div>
</div>
<div class="card-action right-align">
<p><a href="#data-processing-and-analysis-modal" class="btn modal-trigger waves-effect waves-light">Create job<i class="material-icons right">add</i></a></p>
<p><a data-target="dashboard-create-job-dropdown-content" class="btn waves-effect waves-light dropdown-trigger no-autoinit" id="dashboard-create-job-dropdown-trigger">Create job<i class="material-icons right">add</i></a></p>
</div>
</div>
</div>
</div>
</div>
{% endblock page_content %}
{% block dropdowns %}
{{ super() }}
<ul class="dropdown-content" id="dashboard-create-job-dropdown-content">
<li>
<a href="{{ url_for('services.file_setup_pipeline') }}">
<i class="nopaque-icons service-icons service-color-text text-darken" data-service="file-setup-pipeline"></i>
File Setup Pipeline
</a>
</li>
<li>
<a href="{{ url_for('services.tesseract_ocr_pipeline') }}">
<i class="nopaque-icons service-icons service-color-text text-darken" data-service="tesseract-ocr-pipeline"></i>
Tesseract OCR Pipeline
</a>
</li>
{% if config.NOPAQUE_TRANSKRIBUS_ENABLED %}
<li>
<a href="{{ url_for('services.transkribus_htr_pipeline') }}">
<i class="nopaque-icons service-icons service-color-text text-darken" data-service="transkribus-htr-pipeline"></i>
Transkribus HTR Pipeline
</a>
</li>
{% endif %}
<li>
<a href="{{ url_for('services.spacy_nlp_pipeline') }}">
<i class="nopaque-icons service-icons service-color-text text-darken" data-service="spacy-nlp-pipeline"></i>
SpaCy NLP Pipeline
</a>
</li>
</ul>
{% endblock dropdowns %}
{% block scripts %}
{{ super() }}
<script>
M.Dropdown.init(
document.querySelector('#dashboard-create-job-dropdown-trigger'),
{
constrainWidth: false,
container: document.querySelector('#dropdowns'),
coverTrigger: false
}
);
</script>
{% endblock scripts %}

View File

@ -20,8 +20,8 @@
<h6 style="font-weight: 300;">Changes to the Query Builder</h6>
<p>
The Query Builder has undergone changes to make it more intuitive to use and is now the standard option for creating queries.
Individual elements of a query can now be easily modified and edited by clicking on them.
An input marker shows your position in the inquiry and where new elements will be added. This and all other elements can be moved around via drag and drop.
Individual elements of a query can now be easily modified and edited by clicking on them.
An input marker shows your position in the inquiry and where new elements will be added. This and all other elements can be moved around via drag and drop.
A new toggle button enables users to easily switch between the Query Builder and Expert Mode if they prefer to work with the plain Corpus Query Language (CQL) instead. This can be done in the middle of an existing query existing chips will be “translated” into CQL.
This also works the other way around if you want to switch back, your query in CQL wll be parsed into chips.
More details and instructions on how to use the new Query Builder can be found in the manual.
@ -29,9 +29,9 @@
<br>
<h6 style="font-weight: 300;">Community Update</h6>
<p>
The most extensive changes to nopaque have taken place in the Social Area. We want nopaque to be a platform where researchers can connect with each other, so weve added some more features to make this possible.
The most extensive changes to nopaque have taken place in the Social Area. We want nopaque to be a platform where researchers can connect with each other, so weve added some more features to make this possible.
Users can now update their personal profiles to be publicly visible to others on nopaque, including a short “About me” section and options to share your website, organization, location, and add an avatar that others can see.
It is also possible to share corpora with other researchers via share links, access invitations, or by setting corpus visibility to Public. Other users can only see the meta data of public corpora further access can be granted upon request.
It is also possible to share corpora with other researchers via share links, access invitations, or by setting corpus visibility to Public. Other users can only see the meta data of public corpora further access can be granted upon request.
The extent of access to these shared corpora is managed by assigning the roles of Viewer, Contributor, and Administrator. Viewers may only download the files. Contributors can download and edit files and their metadata as well as analyze and build the corpus. Administrators can manage users, followers and visibility, in addition to all of the above.
</p>
<br>
@ -47,21 +47,21 @@
<br>
<p>Hey users,</p>
<p>
we wanted to give you some news on updates were making to nopaque.
Since we want to make it easier for users to grasp and work with different elements of their data,
weve been working on adding some visualization features into the Corpus Analysis service. Currently, the two main modules,
we wanted to give you some news on updates were making to nopaque.
Since we want to make it easier for users to grasp and work with different elements of their data,
weve been working on adding some visualization features into the Corpus Analysis service. Currently, the two main modules,
“Reader” and “Concordance” have been expanded with an additional “Static Visualizations” module, but theres more to come!
</p>
<p>
With the Static Visualizations module, its now possible to view information
about your corpus, such as the number of (unique) tokens, sentences, lemmata,
corresponding information on individual texts, the distribution of these elements
within your corpus, as well as searchable lists of word frequencies with stopwords
With the Static Visualizations module, its now possible to view information
about your corpus, such as the number of (unique) tokens, sentences, lemmata,
corresponding information on individual texts, the distribution of these elements
within your corpus, as well as searchable lists of word frequencies with stopwords
that can be preset and modified. In the future, this area will be extended with more advanced visualization options.
</p>
<p>
Well keep you posted about further visualization updates. Until then, we hope the latest update improves
your research experience with nopaque. And as always, if you have any ideas for nopaque or need assistance,
Well keep you posted about further visualization updates. Until then, we hope the latest update improves
your research experience with nopaque. And as always, if you have any ideas for nopaque or need assistance,
dont hesitate to contact us!
</p>
<br>
@ -78,7 +78,7 @@
<p>Dear users,</p>
<p>
users can now upload their own language models into nopaque. This is useful for working with different languages that are not available as standard in nopaque or if a user wants to work with a language model they have developed themselves. Tesseract models can be uploaded in .traineddata format; spaCy models can be uploaded in tar.gz format. We are also working on the option to upload models in .whl format in the future.
Uploaded models can be found in the model list of the corresponding service and can be used immediately. Models can also be made public if you have a role of Contributor in nopaque.
Uploaded models can be found in the model list of the corresponding service and can be used immediately. Models can also be made public if you have a role of Contributor in nopaque.
</p>
<br>
<p><b>Please note:</b> The Contributor role must be requested from the nopaque admins if you would like to make a model public for all users.</p>
@ -86,7 +86,7 @@
</div>
</div>
</div>
<div class="col s12">
<div class="card" id="news-post-april-2022">
<div class="card-content">
@ -95,62 +95,62 @@
<br>
<p>Hello everyone,</p>
<p>
in April 2022, we released an update improving many elements of nopaque. We rewrote a lot of our code,
including a significant reworking of our backend code for more efficient use of our servers.
in April 2022, we released an update improving many elements of nopaque. We rewrote a lot of our code,
including a significant reworking of our backend code for more efficient use of our servers.
We integrated a new service, updated the existing ones, and made some minor design improvements.
</p>
<br>
<h6 style="font-weight: 300;">Database Cleanup</h6>
<p>
We may be a bit late with our spring cleaning, but weve tidied up our
database system and deleted old, empty corpora, unconfirmed user accounts and
We may be a bit late with our spring cleaning, but weve tidied up our
database system and deleted old, empty corpora, unconfirmed user accounts and
unnecessary data fields.
</p>
<h6 style="font-weight: 300;">What's new?</h6>
<p>
By partnering with Transkribus, weve reached one of our long-term goals: to integrate a
Handwritten Text Recognition (HTR) service into nopaque. The Transkribus HTR Pipeline service is implemented as a
kind of proxied service where the work is split between us and Transkribus.
By partnering with Transkribus, weve reached one of our long-term goals: to integrate a
Handwritten Text Recognition (HTR) service into nopaque. The Transkribus HTR Pipeline service is implemented as a
kind of proxied service where the work is split between us and Transkribus.
That means we do the preprocessing, storage and postprocessing, while Transkribus handles the HTR itself.
</p>
<p>
One change we needed to make in the background was to fix our performance issues.
While implementing the Transkribus HTR Pipeline service, we saw optimization potential
in different steps of our processing routine. These optimizations are now also available
in our Tesseract OCR Pipeline service and result in speeds that are about four times faster
than before. Were now finished with the major optimizations, but there could be more soon,
One change we needed to make in the background was to fix our performance issues.
While implementing the Transkribus HTR Pipeline service, we saw optimization potential
in different steps of our processing routine. These optimizations are now also available
in our Tesseract OCR Pipeline service and result in speeds that are about four times faster
than before. Were now finished with the major optimizations, but there could be more soon,
so stay tuned!
</p>
<p>
Next, we reorganized our Corpus Analysis code. It was a bit messy, but after a complete rewrite,
we are now able to query a corpus without long loading times and with better error handling,
making the user experience much more stable. The Corpus Analysis service is now modularized and comes with two modules
Next, we reorganized our Corpus Analysis code. It was a bit messy, but after a complete rewrite,
we are now able to query a corpus without long loading times and with better error handling,
making the user experience much more stable. The Corpus Analysis service is now modularized and comes with two modules
that recreate and extend the functionality of the old service.
</p>
<p>
The Query Result viewer had to be temporarily disabled, as the code was based on the old Corpus Analysis service.
The Query Result viewer had to be temporarily disabled, as the code was based on the old Corpus Analysis service.
It will be reintegrated as a module to the Corpus Analysis.
</p>
<p>
The spaCy NLP Pipeline service was also taken care of with some smaller updates. This is important preliminary work
for support of more models/languages missing the full set of linguistic features (lemma, ner, pos, simple_pos).
It still needs some testing and adjustments but will be ready soon!
The spaCy NLP Pipeline service was also taken care of with some smaller updates. This is important preliminary work
for support of more models/languages missing the full set of linguistic features (lemma, ner, pos, simple_pos).
It still needs some testing and adjustments but will be ready soon!
</p>
<p>
Last, but not least, we made some design changes. Now, you can find color in places that were previously in black and white.
Nothing big, but the new colors can aid in identifying resources more efficiently.
Last, but not least, we made some design changes. Now, you can find color in places that were previously in black and white.
Nothing big, but the new colors can aid in identifying resources more efficiently.
</p>
<h6 style="font-weight: 300;">Where is my job data?</h6>
<p>
We reached our storage limit at the beginning of the year.
At this time, some users may have noticed system instability.
Fortunately, we found a solution that avoided data loss by deleting some
non-nopaque related data in our system (yes, <a href="https://www.uni-bielefeld.de/fakultaeten/geschichtswissenschaft/abteilung/arbeitsbereiche/digital-history/">we also do things other than nopaque</a>).
To avoid facing the same problem again, we had to find a long-term solution.
In the end, this involved the deletion of all previous job data with this update and,
going forward, only keeping new job data for three months after job creation
(<b>important note:</b> corpora are not affected). All job data created prior to this
update has been backed up for you. Feel free to contact us at <a href="mailto:nopaque@uni-bielefeld.de">nopaque@uni-bielefeld.de</a>
We reached our storage limit at the beginning of the year.
At this time, some users may have noticed system instability.
Fortunately, we found a solution that avoided data loss by deleting some
non-nopaque related data in our system (yes, <a href="https://www.uni-bielefeld.de/fakultaeten/geschichtswissenschaft/abteilung/arbeitsbereiche/digital-history/">we also do things other than nopaque</a>).
To avoid facing the same problem again, we had to find a long-term solution.
In the end, this involved the deletion of all previous job data with this update and,
going forward, only keeping new job data for three months after job creation
(<b>important note:</b> corpora are not affected). All job data created prior to this
update has been backed up for you. Feel free to contact us at <a href="mailto:nopaque@uni-bielefeld.de">nopaque@uni-bielefeld.de</a>
if you would like to get this data back.
</p>
<br>
@ -173,10 +173,10 @@
<li>Corpus analysis, which makes use of CQP Query Language to search through text corpora with the aid of metadata and Natural Language Processing tags.</li>
</ul>
<p>
Nopaque was created based on our experiences working with other subprojects and a Prototyp user study in the
first phase of funding. The platform is open source under the terms of the MIT license (<a href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque">https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque</a>).
Language support and functions are currently limited extensions can be requested by sending an email to <a href="mailto:nopaque@uni-bielefeld.de">nopaque@uni-bielefeld.de</a>.
Because we are still in the beta phase, some bugs are to be expected. If you encounter any problems, please let us know!
Nopaque was created based on our experiences working with other subprojects and a Prototyp user study in the
first phase of funding. The platform is open source under the terms of the MIT license (<a href="https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque">https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque</a>).
Language support and functions are currently limited extensions can be requested by sending an email to <a href="mailto:nopaque@uni-bielefeld.de">nopaque@uni-bielefeld.de</a>.
Because we are still in the beta phase, some bugs are to be expected. If you encounter any problems, please let us know!
We are thankful for all feedback we receive.
</p>
</div>

View File

@ -6,7 +6,7 @@
<div class="col s12">
<h1 id="title">{{ title }}</h1>
</div>
<div class="col s12">
<div id="aggregated-news"></div>
<div class="card" id="april-2022-update">

View File

@ -58,7 +58,7 @@
<span class="card-title">§ 2 General information on data processing and its purpose</span>
<p>We process the personal data of our users only to the extent necessary to provide a functioning website and its functionalities. Collecting this information enables us to better diagnose problems with the application, provide support more effectively as well as ensure the continuous functionality of the service.</p>
<p> The following (personal) data is collected and stored within the system:</p>
<h6>Master Data</h6>
<p>Within the scope of user authentication, the following personal data is collected and processed: </p>
<ul class="browser-default">
@ -66,7 +66,7 @@
<li>E-Mail</li>
</ul>
<p>The registration of users is required for the provision of access to services within NOPAQUE. The freely selectable username and the corresponding email address is used to persistently identify you in NOPAQUE. The provided email address might be used to contact you in case we noticed some malfunction, to announce maintenance, or to spread important information regarding Nopaque. If you reset your password, Nopaque will use your email address to send you reset instructions via email. Nopaque does not show your email address and the username to other Nopaque users per default except, if user gave the permission to do so, according to <b>§ 7 paragraph 1</b> of the General Terms of Use for the use of NOPAQUE.</p>
<h6>Protocol and administrative data</h6>
<p>In general, when a website is visited, for technical reasons information is automatically sent from the browser to the server and stored there in access protocols. When using a web application, additional protocol data is also generated, which is necessary for tracking technical errors. This information includes:</p>
<ul class="browser-default">
@ -96,15 +96,15 @@
<li><b>remember_token</b>: Login script with remember me feature allowing the user to preserve their logged in status. When the user checks the Remember Me option, then the logged in status is serialized in the session and stored in cookies in an encrypted way.</li>
</ul>
<p>Cookies collected by NOPAQUE do not collect personal information of the users.</p>
<h6>Content Data</h6>
<p>The content data includes all data that is entered or created by users themselves in the system. This data is listed here because it is assigned to individual authors and may contain personal data. This may include: <b>uploaded files, images, text documents, other media files</b> and <b>(interim) results</b> after data processing and computations. Please note that files and scans submitted to NOPAQUE are safely stored on the NOPAQUE server in order to allow persistent access during a work session and between work sessions.</p>
<br>
<p>According to <b>§ 4 paragraph 1 - 3</b> of the General Terms of Use for the use of NOPAQUE at Bielefeld University, the users themselves are responsible for the content they upload and must comply with the legal provisions of data protection and copyright law. This includes in particular the deletion of personal data that may no longer be processed.</p>
<h6>User-added Information (optional)</h6>
<p>NOPAQUE also stores optionally user-added personal information, like users profile information (full name, affiliation) and users added profile photo (avatar).</p>
</div>
</div>
</div>

View File

@ -4,7 +4,7 @@
{% block main_attribs %}class="service-color lighten" data-service="file-setup-pipeline"{% endblock main_attribs %}
{% block page_content %}
<div class="container">
<div class="container" data-service="file-setup-pipeline">
<div class="row">
<div class="col s12">
<h1 id="title">{{ title }}</h1>

View File

@ -10,8 +10,8 @@
<div class="col s12 l4">
<h4>Profile Settings</h4>
<p>You can edit your public profile here and share it with other nopaque users.
Tell others about your (scientific) background so they can relate and network with you.
<p>You can edit your public profile here and share it with other nopaque users.
Tell others about your (scientific) background so they can relate and network with you.
You can also set what should not be visible.</p>
</div>
<div class="col s12 l8">
@ -80,7 +80,7 @@
{{ wtf.render_field(update_profile_information_form.location, material_icon='location_on') }}
<div class="right-align">
{{ wtf.render_field(update_profile_information_form.submit, material_icon='send') }}
</div>
</div>
</form>
</div>
</li>
@ -104,7 +104,7 @@
<div class="right-align">
<a class="btn red waves-effect waves-light modal-trigger" href="#delete-avatar-modal"><i class="material-icons left">delete</i>Delete</a>
{{ wtf.render_field(update_avatar_form.submit, material_icon='send') }}
</div>
</div>
</form>
</div>
</li>
@ -115,7 +115,7 @@
<div class="col s12 l4">
<h4>General Settings</h4>
<p>Make general changes to your profile here. You can change your password,
<p>Make general changes to your profile here. You can change your password,
username or email address, delete your profile and customize your notifications.</p>
</div>
<div class="col s12 l8">
@ -142,7 +142,7 @@
<div class="collapsible-header" style="justify-content: space-between;">
<span>Change Password</span>
<i class="caret material-icons">keyboard_arrow_right</i>
</div>
</div>
<div class="collapsible-body">
<form method="POST">
{{ update_password_form.hidden_tag() }}