mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2024-11-15 01:05:42 +00:00
Add dashboard2
This commit is contained in:
parent
5a396ce214
commit
9904e54c51
@ -30,6 +30,12 @@ def dashboard():
|
|||||||
return render_template('main/dashboard.html.j2', title='Dashboard')
|
return render_template('main/dashboard.html.j2', title='Dashboard')
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/dashboard2')
|
||||||
|
@login_required
|
||||||
|
def dashboard2():
|
||||||
|
return render_template('main/dashboard2.html.j2', title='Dashboard')
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/user_manual')
|
@bp.route('/user_manual')
|
||||||
def user_manual():
|
def user_manual():
|
||||||
return render_template('main/user_manual.html.j2', title='User manual')
|
return render_template('main/user_manual.html.j2', title='User manual')
|
||||||
|
@ -226,6 +226,7 @@ class Role(HashidMixin, db.Model):
|
|||||||
db.session.add(role)
|
db.session.add(role)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
class Token(db.Model):
|
class Token(db.Model):
|
||||||
__tablename__ = 'tokens'
|
__tablename__ = 'tokens'
|
||||||
# Primary key
|
# Primary key
|
||||||
@ -249,31 +250,33 @@ class Token(db.Model):
|
|||||||
yesterday = datetime.utcnow() - timedelta(days=1)
|
yesterday = datetime.utcnow() - timedelta(days=1)
|
||||||
Token.query.filter(Token.refresh_expiration < yesterday).delete()
|
Token.query.filter(Token.refresh_expiration < yesterday).delete()
|
||||||
|
|
||||||
|
|
||||||
class Avatar(HashidMixin, FileMixin, db.Model):
|
class Avatar(HashidMixin, FileMixin, db.Model):
|
||||||
__tablename__ = 'avatars'
|
__tablename__ = 'avatars'
|
||||||
# Primary key
|
# Primary key
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
# Foreign keys
|
# Foreign keys
|
||||||
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
|
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
|
||||||
|
# Backrefs: user: User
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def path(self):
|
def path(self):
|
||||||
return os.path.join(self.user.path, 'avatar')
|
return os.path.join(self.user.path, 'avatar')
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
try:
|
try:
|
||||||
os.remove(self.path)
|
os.remove(self.path)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
current_app.logger.error(e)
|
current_app.logger.error(e)
|
||||||
db.session.delete(self)
|
db.session.delete(self)
|
||||||
|
|
||||||
|
|
||||||
class User(HashidMixin, UserMixin, db.Model):
|
class User(HashidMixin, UserMixin, db.Model):
|
||||||
__tablename__ = 'users'
|
__tablename__ = 'users'
|
||||||
# Primary key
|
# Primary key
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
# Foreign keys
|
# Foreign keys
|
||||||
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
|
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
|
||||||
# privacy_id = db.Column(db.Integer, db.ForeignKey('privacies.id'))
|
|
||||||
# Fields
|
# Fields
|
||||||
email = db.Column(db.String(254), index=True, unique=True)
|
email = db.Column(db.String(254), index=True, unique=True)
|
||||||
username = db.Column(db.String(64), index=True, unique=True)
|
username = db.Column(db.String(64), index=True, unique=True)
|
||||||
@ -555,7 +558,6 @@ class User(HashidMixin, UserMixin, db.Model):
|
|||||||
'show_email': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_EMAIL),
|
'show_email': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_EMAIL),
|
||||||
'show_last_seen': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_LAST_SEEN),
|
'show_last_seen': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_LAST_SEEN),
|
||||||
'show_member_since': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_MEMBER_SINCE)
|
'show_member_since': self.has_profile_privacy_setting(ProfilePrivacySettings.SHOW_MEMBER_SINCE)
|
||||||
|
|
||||||
}
|
}
|
||||||
if backrefs:
|
if backrefs:
|
||||||
json_serializeable['role'] = \
|
json_serializeable['role'] = \
|
||||||
@ -579,6 +581,7 @@ class User(HashidMixin, UserMixin, db.Model):
|
|||||||
}
|
}
|
||||||
return json_serializeable
|
return json_serializeable
|
||||||
|
|
||||||
|
|
||||||
class TesseractOCRPipelineModel(FileMixin, HashidMixin, db.Model):
|
class TesseractOCRPipelineModel(FileMixin, HashidMixin, db.Model):
|
||||||
__tablename__ = 'tesseract_ocr_pipeline_models'
|
__tablename__ = 'tesseract_ocr_pipeline_models'
|
||||||
# Primary key
|
# Primary key
|
||||||
@ -869,7 +872,7 @@ class JobInput(FileMixin, HashidMixin, db.Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def user_id(self):
|
def user_id(self):
|
||||||
return self.job.user_id
|
return self.job.user.id
|
||||||
|
|
||||||
def to_json_serializeable(self, backrefs=False, relationships=False):
|
def to_json_serializeable(self, backrefs=False, relationships=False):
|
||||||
json_serializeable = {
|
json_serializeable = {
|
||||||
@ -925,7 +928,7 @@ class JobResult(FileMixin, HashidMixin, db.Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def user_id(self):
|
def user_id(self):
|
||||||
return self.job.user_id
|
return self.job.user.id
|
||||||
|
|
||||||
def to_json_serializeable(self, backrefs=False, relationships=False):
|
def to_json_serializeable(self, backrefs=False, relationships=False):
|
||||||
json_serializeable = {
|
json_serializeable = {
|
||||||
@ -1166,6 +1169,7 @@ class CorpusFile(FileMixin, HashidMixin, db.Model):
|
|||||||
self.corpus.to_json_serializeable(backrefs=True)
|
self.corpus.to_json_serializeable(backrefs=True)
|
||||||
return json_serializeable
|
return json_serializeable
|
||||||
|
|
||||||
|
|
||||||
class Corpus(HashidMixin, db.Model):
|
class Corpus(HashidMixin, db.Model):
|
||||||
'''
|
'''
|
||||||
Class to define a corpus.
|
Class to define a corpus.
|
||||||
|
178
app/templates/main/dashboard2.html.j2
Normal file
178
app/templates/main/dashboard2.html.j2
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
{% extends "base.html.j2" %}
|
||||||
|
{% from "main/_breadcrumbs.html.j2" import breadcrumbs with context %}
|
||||||
|
|
||||||
|
{% block page_content %}
|
||||||
|
<div class="corpus-list no-autoinit" id="corpus-list" data-user-id="{{ current_user.hashid }}">
|
||||||
|
<div class="parallax-container">
|
||||||
|
<div class="parallax"><img src="{{ url_for('static', filename='images/parallax_hq/canvas.png') }}"></div>
|
||||||
|
<div style="position: absolute; bottom: 0; width: 100%;">
|
||||||
|
<div class="container">
|
||||||
|
<div class="white" style="padding: 1px 35px 0 10px; border-radius: 35px;">
|
||||||
|
<div class="input-field">
|
||||||
|
<i class="material-icons prefix">search</i>
|
||||||
|
<input class="search" id="corpus-list-search" type="text">
|
||||||
|
<label for="corpus-list-search">Search Corpus</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s1"></div>
|
||||||
|
<div class="col s3">
|
||||||
|
<h2 id="corpora">My Corpora</h1>
|
||||||
|
<p>Create a corpus to interactively perform linguistic analysis.</p>
|
||||||
|
<p>Or browse our users public corpora.<span class="new badge"></span></p>
|
||||||
|
</div>
|
||||||
|
<div class="col s7">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<div>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th>Title and Description</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="list"></tbody>
|
||||||
|
</table>
|
||||||
|
<ul class="pagination"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-action right-align">
|
||||||
|
<a class="btn disabled waves-effect waves-light" href="{{ url_for('corpora.import_corpus') }}">Import Corpus<i class="material-icons right">import_export</i></a>
|
||||||
|
<a class="btn waves-effect waves-light" href="{{ url_for('corpora.create_corpus') }}">Create corpus<i class="material-icons right">add</i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="job-list no-autoinit" id="job-list" data-user-id="{{ current_user.hashid }}">
|
||||||
|
<div class="parallax-container">
|
||||||
|
<div class="parallax"><img src="{{ url_for('static', filename='images/parallax_hq/canvas.png') }}"></div>
|
||||||
|
<div style="position: absolute; bottom: 0; width: 100%;">
|
||||||
|
<div class="container">
|
||||||
|
<div class="white" style="padding: 1px 35px 0 10px; border-radius: 35px;">
|
||||||
|
<div class="input-field">
|
||||||
|
<i class="material-icons prefix">search</i>
|
||||||
|
<input class="search" id="job-list-search" type="text">
|
||||||
|
<label for="job-list-search">Search Job</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s1"></div>
|
||||||
|
<div class="col s3">
|
||||||
|
<h2 id="jobs">My Jobs</h1>
|
||||||
|
<p>
|
||||||
|
A job is the execution of a service provided by nopaque. You can
|
||||||
|
create any number of jobs and let them be processed simultaneously. We
|
||||||
|
<b>strongly recommend</b> that you create a folder on your computer where you
|
||||||
|
save the various files that nopaque provides you with after each
|
||||||
|
pre-processing step. You will need the result of each step for the
|
||||||
|
next step.
|
||||||
|
</p>
|
||||||
|
<p><b>Where is my Job data?</b> Don't worry, please read <a href="{{ url_for('main.news', _anchor='april-2022-update') }}">this news</a> entry</p>
|
||||||
|
</div>
|
||||||
|
<div class="col s7">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<div>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th>Title and Description</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="list"></tbody>
|
||||||
|
</table>
|
||||||
|
<ul class="pagination"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-action right-align">
|
||||||
|
<a class="btn modal-trigger waves-effect waves-light" data-target="create-job-modal"><i class="material-icons left">add</i>Create job</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock page_content %}
|
||||||
|
|
||||||
|
{% block modals %}
|
||||||
|
{{ super() }}
|
||||||
|
<div id="create-job-modal" class="modal">
|
||||||
|
<div class="modal-content">
|
||||||
|
<h4>Select a service</h4>
|
||||||
|
<p> </p>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12 m4">
|
||||||
|
<div class="card-panel center-align hoverable">
|
||||||
|
<br>
|
||||||
|
<a href="{{ url_for('services.file_setup_pipeline') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);">
|
||||||
|
<i class="nopaque-icons service-color darken service-icon" data-service="file-setup-pipeline"></i>
|
||||||
|
</a>
|
||||||
|
<br><br>
|
||||||
|
<p class="service-color-text darken" data-service="file-setup-pipeline"><b>File setup</b></p>
|
||||||
|
<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.</p>
|
||||||
|
<a href="{{ url_for('services.file_setup_pipeline') }}" class="waves-effect waves-light btn service-color darken" data-service="file-setup-pipeline">Create Job</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m4">
|
||||||
|
<div class="card-panel center-align hoverable">
|
||||||
|
<br>
|
||||||
|
<a href="{{ url_for('services.tesseract_ocr_pipeline') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);">
|
||||||
|
<i class="nopaque-icons service-color darken service-icon" data-service="tesseract-ocr-pipeline" style="font-size: 2.5rem;"></i>
|
||||||
|
</a>
|
||||||
|
<br><br>
|
||||||
|
<p class="service-color-text darken" data-service="tesseract-ocr-pipeline"><b>Optical Character Recognition</b></p>
|
||||||
|
<p class="light">nopaque converts your image data – like photos or scans – into text data through a process called OCR. This step enables you to proceed with further computational analysis of your documents.</p>
|
||||||
|
<a href="{{ url_for('services.tesseract_ocr_pipeline') }}" class="waves-effect waves-light btn service-color darken" data-service="tesseract-ocr-pipeline">Create Job</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col s12 m4">
|
||||||
|
<div class="card-panel center-align hoverable">
|
||||||
|
<br>
|
||||||
|
<a href="{{ url_for('services.spacy_nlp_pipeline') }}" class="btn-floating btn-large waves-effect waves-light" style="transform: scale(2);">
|
||||||
|
<i class="nopaque-icons service-color darken service-icon" data-service="spacy-nlp-pipeline" style="font-size: 2.5rem;"></i>
|
||||||
|
</a>
|
||||||
|
<br><br>
|
||||||
|
<p class="service-color-text darken" data-service="spacy-nlp-pipeline"><b>Natural Language Processing</b></p>
|
||||||
|
<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>
|
||||||
|
<a href="{{ url_for('services.spacy_nlp_pipeline') }}" class="waves-effect waves-light btn service-color darken" data-service="spacy-nlp-pipeline">Create Job</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a class="btn-flat modal-close waves-effect waves-light">Close</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock modals %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{{ super() }}
|
||||||
|
<script>
|
||||||
|
let corpusListElement = document.querySelector('#corpus-list');
|
||||||
|
let corpusListOptions = {initialHtmlGenerator: null};
|
||||||
|
let corpusList = new CorpusList(corpusListElement, corpusListOptions);
|
||||||
|
let jobListElement = document.querySelector('#job-list');
|
||||||
|
let jobListOptions = {initialHtmlGenerator: null};
|
||||||
|
let jobList = new JobList(jobListElement, jobListOptions);
|
||||||
|
</script>
|
||||||
|
{% endblock scripts %}
|
Loading…
Reference in New Issue
Block a user