Skip to content
Snippets Groups Projects
Commit 700e11ec authored by Patrick Jentsch's avatar Patrick Jentsch
Browse files

Rename and rework profile packege (new name settings)

parent 1092033a
No related branches found
No related tags found
No related merge requests found
Showing with 316 additions and 236 deletions
...@@ -28,22 +28,23 @@ def create_app(config_name): ...@@ -28,22 +28,23 @@ def create_app(config_name):
socketio.init_app( socketio.init_app(
app, message_queue=config[config_name].SOCKETIO_MESSAGE_QUEUE_URI) app, message_queue=config[config_name].SOCKETIO_MESSAGE_QUEUE_URI)
from . import events with app.app_context():
from .admin import admin as admin_blueprint from . import events
from .admin import admin as admin_blueprint
from .auth import auth as auth_blueprint
from .corpora import corpora as corpora_blueprint
from .errors import errors as errors_blueprint
from .jobs import jobs as jobs_blueprint
from .main import main as main_blueprint
from .services import services as services_blueprint
from .settings import settings as settings_blueprint
app.register_blueprint(admin_blueprint, url_prefix='/admin') app.register_blueprint(admin_blueprint, url_prefix='/admin')
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint, url_prefix='/auth') app.register_blueprint(auth_blueprint, url_prefix='/auth')
from .corpora import corpora as corpora_blueprint
app.register_blueprint(corpora_blueprint, url_prefix='/corpora') app.register_blueprint(corpora_blueprint, url_prefix='/corpora')
from .errors import errors as errors_blueprint
app.register_blueprint(errors_blueprint) app.register_blueprint(errors_blueprint)
from .jobs import jobs as jobs_blueprint
app.register_blueprint(jobs_blueprint, url_prefix='/jobs') app.register_blueprint(jobs_blueprint, url_prefix='/jobs')
from .main import main as main_blueprint
app.register_blueprint(main_blueprint) app.register_blueprint(main_blueprint)
from .profile import profile as profile_blueprint
app.register_blueprint(profile_blueprint, url_prefix='/profile')
from .services import services as services_blueprint
app.register_blueprint(services_blueprint, url_prefix='/services') app.register_blueprint(services_blueprint, url_prefix='/services')
app.register_blueprint(settings_blueprint, url_prefix='/settings')
return app return app
from flask import current_app
from ..models import User from ..models import User
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import (BooleanField, PasswordField, StringField, SubmitField, from wtforms import (BooleanField, PasswordField, StringField, SubmitField,
...@@ -17,9 +18,9 @@ class RegistrationForm(FlaskForm): ...@@ -17,9 +18,9 @@ class RegistrationForm(FlaskForm):
username = StringField( username = StringField(
'Username', 'Username',
validators=[DataRequired(), Length(1, 64), validators=[DataRequired(), Length(1, 64),
Regexp('^[A-Za-z][A-Za-z0-9_.]*$', 0, Regexp(current_app.config['ALLOWED_USERNAME_REGEX'],
'Usernames must have only letters, numbers, dots ' message='Usernames must have only letters, numbers,'
'or underscores')] ' dots or underscores')]
) )
password = PasswordField( password = PasswordField(
'Password', 'Password',
......
from .. import db
from ..decorators import background
from ..models import User
@background
def delete_user(user_id, *args, **kwargs):
with kwargs['app'].app_context():
user = User.query.get(user_id)
if user is None:
raise Exception('User {} not found'.format(user_id))
user.delete()
db.session.commit()
from flask import flash, redirect, render_template, url_for
from flask_login import current_user, login_required, logout_user
from . import profile
from . import tasks
from .forms import EditEmailForm, EditGeneralSettingsForm, EditPasswordForm
from .. import db
@profile.route('/settings', methods=['GET', 'POST'])
@login_required
def settings():
edit_email_form = EditEmailForm(prefix='edit-email-form')
edit_general_settings_form = EditGeneralSettingsForm(
prefix='edit-general-settings-form')
edit_password_form = EditPasswordForm(prefix='edit-password-form',
user=current_user)
# Check if edit_email_form is submitted and valid
if (edit_email_form.save_email.data
and edit_email_form.validate_on_submit()):
db.session.add(current_user)
db.session.commit()
flash('Your email address has been updated.')
return redirect(url_for('profile.settings'))
# Check if edit_settings_form is submitted and valid
if (edit_general_settings_form.save_settings.data
and edit_general_settings_form.validate_on_submit()):
current_user.setting_dark_mode = \
edit_general_settings_form.dark_mode.data
current_user.setting_job_status_mail_notifications = \
edit_general_settings_form.job_status_mail_notifications.data
current_user.setting_job_status_site_notifications = \
edit_general_settings_form.job_status_site_notifications.data
db.session.add(current_user)
db.session.commit()
flash('Your settings have been updated.')
return redirect(url_for('profile.settings'))
# Check if edit_password_form is submitted and valid
if (edit_password_form.save_password.data
and edit_password_form.validate_on_submit()):
current_user.password = edit_password_form.password.data
db.session.add(current_user)
db.session.commit()
flash('Your password has been updated.')
return redirect(url_for('profile.settings'))
# If no form is submitted or valid, fill out fields with current values
edit_email_form.email.data = current_user.email
edit_general_settings_form.dark_mode.data = current_user.setting_dark_mode
edit_general_settings_form.job_status_site_notifications.data = \
current_user.setting_job_status_site_notifications
edit_general_settings_form.job_status_mail_notifications.data = \
current_user.setting_job_status_mail_notifications
return render_template(
'profile/settings.html.j2',
edit_email_form=edit_email_form,
edit_password_form=edit_password_form,
edit_general_settings_form=edit_general_settings_form,
title='Settings')
@profile.route('/delete', methods=['GET', 'POST'])
@login_required
def delete():
"""
View to delete yourslef and all associated data.
"""
tasks.delete_user(current_user.id)
logout_user()
flash('Your account has been deleted!')
return redirect(url_for('main.index'))
from flask import Blueprint from flask import Blueprint
profile = Blueprint('profile', __name__) settings = Blueprint('settings', __name__)
from . import views # noqa from . import views # noqa
from flask import current_app
from flask_login import current_user
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import (BooleanField, PasswordField, SelectField, StringField, from wtforms import (BooleanField, PasswordField, SelectField, StringField,
SubmitField, ValidationError) SubmitField, ValidationError)
from wtforms.validators import DataRequired, Email, EqualTo from wtforms.validators import DataRequired, Email, EqualTo, Length, Regexp
class EditEmailForm(FlaskForm): class ChangePasswordForm(FlaskForm):
email = StringField('New email', validators=[Email(), DataRequired()]) password = PasswordField('Old password', validators=[DataRequired()])
save_email = SubmitField('Save email') new_password = PasswordField(
'New password',
validators=[DataRequired(), EqualTo('password_confirmation',
message='Passwords must match.')]
)
new_password2 = PasswordField(
'Confirm new password', validators=[DataRequired()])
submit = SubmitField('Change password')
def __init__(self, user=current_user, *args, **kwargs):
super().__init__(*args, **kwargs)
self.user = user
def validate_current_password(self, field):
if not self.user.verify_password(field.data):
raise ValidationError('Invalid password.')
class EditGeneralSettingsForm(FlaskForm): class EditGeneralSettingsForm(FlaskForm):
dark_mode = BooleanField('Dark mode') dark_mode = BooleanField('Dark mode')
email = StringField('E-Mail',
validators=[DataRequired(), Length(1, 254), Email()])
username = StringField(
'Benutzername',
validators=[DataRequired(),
Length(1, 64),
Regexp(current_app.config['ALLOWED_USERNAME_REGEX'],
message='Usernames must have only letters, numbers,'
' dots or underscores')]
)
submit = SubmitField('Submit')
def __init__(self, user=current_user, *args, **kwargs):
super().__init__(*args, **kwargs)
self.user = user
self.email.data = self.email.data or user.email
self.dark_mode.data = self.dark_mode.data or user.setting_dark_mode
self.username.data = self.username.data or user.username
def validate_email(self, field):
if (field.data != self.user.email
and User.query.filter_by(email=field.data).first()):
raise ValidationError('Email already registered.')
def validate_username(self, field):
if (field.data != self.user.username
and User.query.filter_by(username=field.data).first()):
raise ValidationError('Username already in use.')
class EditNotificationSettingsForm(FlaskForm):
job_status_mail_notifications = SelectField( job_status_mail_notifications = SelectField(
'Job status mail notifications', 'Job status mail notifications',
choices=[('', 'Choose your option'), choices=[('', 'Choose your option'),
...@@ -25,28 +73,14 @@ class EditGeneralSettingsForm(FlaskForm): ...@@ -25,28 +73,14 @@ class EditGeneralSettingsForm(FlaskForm):
('end', 'Notify only when a job ended'), ('end', 'Notify only when a job ended'),
('none', 'No status update notifications')], ('none', 'No status update notifications')],
validators=[DataRequired()]) validators=[DataRequired()])
save_settings = SubmitField('Save settings') submit = SubmitField('Save settings')
class EditPasswordForm(FlaskForm): def __init__(self, user=current_user, *args, **kwargs):
current_password = PasswordField('Current password', super().__init__(*args, **kwargs)
validators=[DataRequired()])
password = PasswordField(
'New password',
validators=[DataRequired(), EqualTo('password_confirmation',
message='Passwords must match.')]
)
password_confirmation = PasswordField(
'Password confirmation',
validators=[DataRequired(),
EqualTo('password', message='Passwords must match.')]
)
save_password = SubmitField('Save password')
def __init__(self, user, *args, **kwargs):
super(EditPasswordForm, self).__init__(*args, **kwargs)
self.user = user self.user = user
self.job_status_mail_notifications.data = \
def validate_current_password(self, field): self.job_status_mail_notifications.data \
if not self.user.verify_password(field.data): or user.setting_job_status_mail_notifications
raise ValidationError('Invalid password.') self.job_status_site_notifications.data = \
self.job_status_site_notifications.data \
or user.setting_job_status_site_notifications
from flask import current_app, flash, redirect, render_template, url_for
from flask_login import current_user, login_required
from . import settings
from .forms import (ChangePasswordForm, EditGeneralSettingsForm,
EditNotificationSettingsForm)
from .. import db
from ..decorators import admin_required
from ..models import Role, User
import os
import uuid
@settings.route('/')
@login_required
def index():
return redirect(url_for('.edit_general_settings'))
@settings.route('/change_password', methods=['GET', 'POST'])
@login_required
def change_password():
form = ChangePasswordForm()
if form.validate_on_submit():
current_user.password = form.new_password.data
db.session.commit()
flash('Your password has been updated.')
return redirect(url_for('.change_password'))
return render_template('settings/change_password.html.j2',
form=form,
title='Change password')
@settings.route('/edit_general_settings')
@login_required
def edit_general_settings():
form = EditGeneralSettingsForm()
if form.validate_on_submit():
current_user.email = form.email.data
current_user.setting_dark_mode = form.dark_mode.data
current_user.username = form.username.data
db.session.commit()
flash('Your changes have been saved.')
return render_template('settings/edit_general_settings.html.j2',
form=form,
title='General settings')
@settings.route('/edit_notification_settings')
@login_required
def edit_notification_settings():
form = EditNotificationSettingsForm()
if form.validate_on_submit():
current_user.setting_job_status_mail_notifications = \
form.job_status_mail_notifications.data
current_user.setting_job_status_site_notifications = \
form.job_status_site_notifications.data
db.session.commit()
flash('Your changes have been saved.')
return render_template('settings/edit_notification_settings.html.j2',
form=form,
title='Notification settings')
@settings.route('/delete')
@login_required
def delete():
"""
View to delete current_user and all associated data.
"""
tasks.delete_user(current_user.id)
logout_user()
flash('Your account has been deleted!')
return redirect(url_for('main.index'))
...@@ -84,8 +84,7 @@ ...@@ -84,8 +84,7 @@
<li{% if request.path == url_for('auth.register') %} class="active"{% endif %}><a href="{{ url_for('auth.register') }}"><i class="material-icons left">assignment</i>Register</a></li> <li{% if request.path == url_for('auth.register') %} class="active"{% endif %}><a href="{{ url_for('auth.register') }}"><i class="material-icons left">assignment</i>Register</a></li>
<li{% if request.path == url_for('auth.login') %} class="active"{% endif %}><a href="{{ url_for('auth.login') }}"><i class="material-icons left">login</i>Log in</a></li> <li{% if request.path == url_for('auth.login') %} class="active"{% endif %}><a href="{{ url_for('auth.login') }}"><i class="material-icons left">login</i>Log in</a></li>
{% else %} {% else %}
<li{% if request.path == url_for('main.dashboard', _anchor='corpora') %} class="active"{% endif %}><a href="{{ url_for('main.dashboard', _anchor='corpora') }}"><i class="material-icons left">book</i>My Corpora</a></li> <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>
<li{% if request.path == url_for('main.dashboard', _anchor='jobs') %} class="active"{% endif %}><a href="{{ url_for('main.dashboard', _anchor='jobs') }}"><i class="material-icons left">work</i>My Jobs</a></li>
<li><a class="dropdown-trigger no-autoinit" data-target="nav-more-dropdown" href="#!" id="nav-more-dropdown-trigger"><i class="material-icons">more_vert</i></a></li> <li><a class="dropdown-trigger no-autoinit" data-target="nav-more-dropdown" href="#!" id="nav-more-dropdown-trigger"><i class="material-icons">more_vert</i></a></li>
{% endif %} {% endif %}
</ul> </ul>
...@@ -98,7 +97,7 @@ ...@@ -98,7 +97,7 @@
{% if current_user.is_authenticated %} {% if current_user.is_authenticated %}
<ul class="dropdown-content" id="nav-more-dropdown"> <ul class="dropdown-content" id="nav-more-dropdown">
<li><a href="{{ url_for('profile.settings') }}"><i class="material-icons left">settings</i>Settings</a></li> <li><a href="{{ url_for('settings.index') }}"><i class="material-icons left">settings</i>Settings</a></li>
<li class="divider" tabindex="-1"></li> <li class="divider" tabindex="-1"></li>
<li><a href="{{ url_for('auth.logout') }}">Log out</a></li> <li><a href="{{ url_for('auth.logout') }}">Log out</a></li>
</ul> </ul>
...@@ -127,7 +126,7 @@ ...@@ -127,7 +126,7 @@
<li style="background-color: {{ colors.nlp }}; border-left: 10px solid {{ colors.nlp_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='nlp') }}"><i class="material-icons">format_textdirection_l_to_r</i>NLP</a></li> <li style="background-color: {{ colors.nlp }}; border-left: 10px solid {{ colors.nlp_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='nlp') }}"><i class="material-icons">format_textdirection_l_to_r</i>NLP</a></li>
<li style="background-color: {{ colors.corpus_analysis }}; border-left: 10px solid {{ colors.corpus_analysis_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='corpus_analysis') }}"><i class="material-icons">search</i>Corpus analysis</a></li> <li style="background-color: {{ colors.corpus_analysis }}; border-left: 10px solid {{ colors.corpus_analysis_darken }}; margin-top: 5px;"><a href="{{ url_for('services.service', service='corpus_analysis') }}"><i class="material-icons">search</i>Corpus analysis</a></li>
<li class="hide-on-large-only"><div class="divider"></div></li> <li class="hide-on-large-only"><div class="divider"></div></li>
<li class="hide-on-large-only"><a href="{{ url_for('profile.settings') }}"><i class="material-icons">settings</i>Settings</a></li> <li class="hide-on-large-only"><a href="{{ url_for('settings.index') }}"><i class="material-icons">settings</i>Settings</a></li>
<li class="hide-on-large-only"><a href="{{ url_for('auth.logout') }}">Log out</a></li> <li class="hide-on-large-only"><a href="{{ url_for('auth.logout') }}">Log out</a></li>
{% else %} {% else %}
<li class="hide-on-large-only"><a href="{{ url_for('auth.register') }}"><i class="material-icons">assignment</i>Register</a></li> <li class="hide-on-large-only"><a href="{{ url_for('auth.register') }}"><i class="material-icons">assignment</i>Register</a></li>
......
{% extends "nopaque.html.j2" %}
{% block page_content %}
<div class="col s12 m4">
<h3>General settings</h3>
</div>
<div class="col s12 m8">
<br class="hide-on-small-only">
<div class="card">
<form method="POST">
<div class="card-content">
{{ edit_general_settings_form.hidden_tag() }}
<div class="row">
<div class="col s9">
<p><i class="material-icons left">brightness_3</i>{{ edit_general_settings_form.dark_mode.label.text }}</p>
<p class="light">Activate dark mode to ease your eyes.</p>
</div>
<div class="col s3 right-align">
{{ M.render_field(edit_general_settings_form.dark_mode, label=False) }}
</div>
<div class="col s12"><p>&nbsp;</p></div>
<div class="col s12 divider"></div>
<div class="col s12"><p>&nbsp;</p></div>
<div class="col s12 m8">
<p><i class="material-icons left">notifications</i>Job status site notifications</p>
<p class="light">Receive site notifications about job status changes.</p>
</div>
<div class="col s12 m4 right-align" style="margin-top: -1rem;">
{{ M.render_field(edit_general_settings_form.job_status_site_notifications, label=False) }}
</div>
<div class="col s12"><p>&nbsp;</p></div>
<div class="col s12 divider"></div>
<div class="col s12"><p>&nbsp;</p></div>
<div class="col s12 m8">
<p><i class="material-icons left">notifications</i>Job status mail notifications</p>
<p class="light">Receive mail notifications about job status changes.</p>
</div>
<div class="col s12 m4 right-align" style="margin-top: -1rem;">
{{ M.render_field(edit_general_settings_form.job_status_mail_notifications, label=False) }}
</div>
<!--
Seperate each setting with the following two elements
<div class="col s12 divider"></div>
<div class="col s12"><p>&nbsp;</p></div>
-->
</div>
</div>
<div class="card-action right-align">
{{ M.render_field(edit_general_settings_form.save_settings, material_icon='send') }}
</div>
</form>
</div>
</div>
<div class="col s12"></div>
<div class="col s12 m4">
<h3>Change password</h3>
</div>
<div class="col s12 m8">
<br class="hide-on-small-only">
<div class="card">
<form method="POST">
<div class="card-content">
{{ edit_password_form.hidden_tag() }}
{{ M.render_field(edit_password_form.current_password, data_length='128', material_icon='vpn_key') }}
{{ M.render_field(edit_password_form.password, data_length='128', material_icon='vpn_key') }}
{{ M.render_field(edit_password_form.password_confirmation, data_length='128', material_icon='vpn_key') }}
</div>
<div class="card-action right-align">
{{ M.render_field(edit_password_form.save_password, material_icon='send') }}
</div>
</form>
</div>
</div>
<div class="col s12"></div>
<div class="col s12 m4">
<h3>Change email</h3>
</div>
<div class="col s12 m8">
<br class="hide-on-small-only">
<div class="card">
<form method="POST">
<div class="card-content">
{{ edit_email_form.hidden_tag() }}
{{ M.render_field(edit_email_form.email, class_='validate', material_icon='email', type='email') }}
</div>
<div class="card-action right-align">
{{ M.render_field(edit_email_form.save_email, material_icon='send') }}
</div>
</form>
</div>
</div>
<div class="col s12"></div>
<div class="col s12 m4">
<h3>Delete account</h3>
</div>
<div class="col s12 m8">
<br class="hide-on-small-only">
<div class="card">
<div class="card-content">
<p>Deleting an account has the following effects:</p>
<ul>
<li>All data associated with your corpora and jobs will be permanently deleted.</li>
<li>All settings will be permanently deleted.</li>
</ul>
</div>
<div class="card-action right-align">
<a href="#delete-account-modal" class="btn modal-trigger red waves-effect waves-light"><i class="material-icons left">delete</i>Delete</a>
</div>
</div>
</div>
<!-- Modals -->
<div class="modal" id="delete-account-modal">
<div class="modal-content">
<h4>Confirm deletion</h4>
<p>Do you really want to delete your account and all associated data? All associated corpora, jobs and files will be permanently deleted!</p>
</div>
<div class="modal-footer">
<a href="#!" class="btn modal-close waves-effect waves-light">Cancel</a>
<a href="{{ url_for('profile.delete') }}" class="btn red waves-effect waves-light"><i class="material-icons left">delete</i>Delete</a>
</div>
</div>
{% endblock %}
<div class="collection">
<a href="{{ url_for('.edit_general_settings') }}" class="collection-item{%if request.path == url_for('.edit_general_settings') %} active{% endif %}">Edit general settings</a>
<a href="{{ url_for('.change_password') }}" class="collection-item{%if request.path == url_for('.change_password') %} active{% endif %}">Change password</a>
<a href="{{ url_for('.edit_notification_settings') }}" class="collection-item{%if request.path == url_for('.edit_notification_settings') %} active{% endif %}">Edit notification settings</a>
</div>
{% extends 'nopaque.html.j2' %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1 id="title">Settings</h1>
</div>
<div class="col s12 m4">
{% include 'settings/_menu.html.j2' %}
</div>
<div class="col s12 m8">
<div class="card">
<form enctype="multipart/form-data" method="POST">
<div class="card-content">
<span class="card-title">{{ title }}</span>
{{ form.hidden_tag() }}
{{ wtf.render_field(form.password, material_icon='vpn_key') }}
{{ wtf.render_field(form.new_password, material_icon='vpn_key') }}
{{ wtf.render_field(form.new_password2, material_icon='vpn_key') }}
</div>
<div class="card-action">
<div class="right-align">
{{ wtf.render_field(form.submit, material_icon='send') }}
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock page_content %}
{% extends 'nopaque.html.j2' %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1 id="title">Settings</h1>
</div>
<div class="col s12 m4">
{% include 'settings/_menu.html.j2' %}
</div>
<div class="col s12 m8">
<div class="card">
<form enctype="multipart/form-data" method="POST">
<div class="card-content">
<span class="card-title">{{ title }}</span>
{{ form.hidden_tag() }}
{{ wtf.render_field(form.username, data_length='64', material_icon='person') }}
{{ wtf.render_field(form.email, data_length='254', material_icon='email') }}
{{ wtf.render_field(form.dark_mode, material_icon='brightness_3') }}
</div>
<div class="card-action">
<div class="right-align">
{{ wtf.render_field(form.submit, material_icon='send') }}
</div>
</div>
</form>
</div>
<div class="card">
<div class="card-content">
<span class="card-title">Delete account</span>
<p>Deleting an account has the following effects:</p>
<ul>
<li>All data associated with your corpora and jobs will be permanently deleted.</li>
<li>All settings will be permanently deleted.</li>
</ul>
</div>
<div class="card-action right-align">
<a href="#delete-account-modal" class="btn modal-trigger red waves-effect waves-light"><i class="material-icons left">delete</i>Delete</a>
</div>
</div>
</div>
</div>
</div>
<!-- Modals -->
<div class="modal" id="delete-account-modal">
<div class="modal-content">
<h4>Confirm deletion</h4>
<p>Do you really want to delete your account and all associated data? All associated corpora, jobs and files will be permanently deleted!</p>
</div>
<div class="modal-footer">
<a href="#!" class="btn modal-close waves-effect waves-light">Cancel</a>
<a href="{{ url_for('.delete') }}" class="btn red waves-effect waves-light"><i class="material-icons left">delete</i>Delete</a>
</div>
</div>
{% endblock page_content %}
{% extends 'nopaque.html.j2' %}
{% import 'materialize/wtf.html.j2' as wtf %}
{% block page_content %}
<div class="container">
<div class="row">
<div class="col s12">
<h1 id="title">Settings</h1>
</div>
<div class="col s12 m4">
{% include 'settings/_menu.html.j2' %}
</div>
<div class="col s12 m8">
<div class="card">
<form enctype="multipart/form-data" method="POST">
<div class="card-content">
<span class="card-title">{{ title }}</span>
{{ form.hidden_tag() }}
{{ wtf.render_field(form.job_status_mail_notifications, material_icon='notifications') }}
{{ wtf.render_field(form.job_status_site_notifications, material_icon='feedback') }}
</div>
<div class="card-action">
<div class="right-align">
{{ wtf.render_field(form.submit, material_icon='send') }}
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock page_content %}
...@@ -31,6 +31,7 @@ class Config: ...@@ -31,6 +31,7 @@ class Config:
''' # General # ''' ''' # General # '''
ADMIN_EMAIL_ADRESS = os.environ.get('NOPAQUE_ADMIN_EMAIL_ADRESS') ADMIN_EMAIL_ADRESS = os.environ.get('NOPAQUE_ADMIN_EMAIL_ADRESS')
ALLOWED_USERNAME_REGEX = '^[A-Za-zÄÖÜäöüß0-9_.]*$'
CONTACT_EMAIL_ADRESS = os.environ.get('NOPAQUE_CONTACT_EMAIL_ADRESS') CONTACT_EMAIL_ADRESS = os.environ.get('NOPAQUE_CONTACT_EMAIL_ADRESS')
DATA_DIR = os.environ.get('NOPAQUE_DATA_DIR', '/mnt/nopaque') DATA_DIR = os.environ.get('NOPAQUE_DATA_DIR', '/mnt/nopaque')
SECRET_KEY = os.environ.get('NOPAQUE_SECRET_KEY', 'hard to guess string') SECRET_KEY = os.environ.get('NOPAQUE_SECRET_KEY', 'hard to guess string')
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment