Add admin email test page #388

This commit is contained in:
Daniel Grams 2023-03-24 21:45:34 +01:00
parent a78932d81c
commit 5178e73843
23 changed files with 472 additions and 140 deletions

View File

@ -1,6 +1,7 @@
[run] [run]
omit = omit =
project/celery.py project/celery.py
project/base_tasks.py
project/celery_tasks.py project/celery_tasks.py
project/cli/test.py project/cli/test.py
project/templates/email/* project/templates/email/*

View File

@ -1,4 +1,4 @@
# Open Event Database # EventCally - Open event calendar
![Tests](https://github.com/eventcally/eventcally/workflows/Tests/badge.svg) [![codecov](https://codecov.io/gh/eventcally/eventcally/branch/main/graph/badge.svg?token=66CLLWWV7Y)](https://codecov.io/gh/eventcally/eventcally) [![Cypress](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/32g194/main&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/32g194/runs) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![Docker Pulls](https://img.shields.io/docker/pulls/eventcally/eventcally)](https://hub.docker.com/r/eventcally/eventcally) ![Tests](https://github.com/eventcally/eventcally/workflows/Tests/badge.svg) [![codecov](https://codecov.io/gh/eventcally/eventcally/branch/main/graph/badge.svg?token=66CLLWWV7Y)](https://codecov.io/gh/eventcally/eventcally) [![Cypress](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/32g194/main&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/32g194/runs) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![Docker Pulls](https://img.shields.io/docker/pulls/eventcally/eventcally)](https://hub.docker.com/r/eventcally/eventcally)

View File

@ -24,6 +24,7 @@ x-web-env:
JWT_PRIVATE_KEY: ${JWT_PRIVATE_KEY} JWT_PRIVATE_KEY: ${JWT_PRIVATE_KEY}
JWT_PUBLIC_JWKS: ${JWT_PUBLIC_JWKS} JWT_PUBLIC_JWKS: ${JWT_PUBLIC_JWKS}
DOCS_URL: ${DOCS_URL} DOCS_URL: ${DOCS_URL}
SITE_NAME: ${SITE_NAME}
x-web: x-web:
&default-web &default-web

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2023-03-16 19:11+0100\n" "POT-Creation-Date: 2023-03-24 21:24+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -198,93 +198,101 @@ msgstr ""
msgid "You have received an invitation" msgid "You have received an invitation"
msgstr "" msgstr ""
#: project/forms/admin.py:10 project/templates/layout.html:294 #: project/forms/admin.py:11 project/templates/layout.html:294
#: project/views/root.py:57 #: project/views/root.py:53
msgid "Terms of service" msgid "Terms of service"
msgstr "" msgstr ""
#: project/forms/admin.py:11 project/templates/layout.html:298 #: project/forms/admin.py:12 project/templates/layout.html:298
#: project/views/root.py:65 #: project/views/root.py:61
msgid "Legal notice" msgid "Legal notice"
msgstr "" msgstr ""
#: project/forms/admin.py:12 project/templates/_macros.html:1395 #: project/forms/admin.py:13 project/templates/_macros.html:1395
#: project/templates/layout.html:302 #: project/templates/layout.html:302
#: project/templates/widget/event_suggestion/create.html:204 #: project/templates/widget/event_suggestion/create.html:204
#: project/views/admin_unit.py:73 project/views/root.py:73 #: project/views/admin_unit.py:73 project/views/root.py:69
msgid "Contact" msgid "Contact"
msgstr "" msgstr ""
#: project/forms/admin.py:13 project/templates/layout.html:306 #: project/forms/admin.py:14 project/templates/layout.html:306
#: project/views/root.py:81 #: project/views/root.py:77
msgid "Privacy" msgid "Privacy"
msgstr "" msgstr ""
#: project/forms/admin.py:14 #: project/forms/admin.py:15
msgid "Start page" msgid "Start page"
msgstr "" msgstr ""
#: project/forms/admin.py:16 project/forms/oauth2_client.py:24 #: project/forms/admin.py:17 project/forms/oauth2_client.py:24
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: project/forms/admin.py:20 project/forms/admin_unit_member.py:12 #: project/forms/admin.py:21 project/forms/admin_unit_member.py:12
#: project/forms/admin_unit_member.py:32 #: project/forms/admin_unit_member.py:32
msgid "Roles" msgid "Roles"
msgstr "" msgstr ""
#: project/forms/admin.py:21 project/templates/admin/update_user.html:4 #: project/forms/admin.py:22 project/templates/admin/update_user.html:4
#: project/templates/admin/update_user.html:8 #: project/templates/admin/update_user.html:8
msgid "Update user" msgid "Update user"
msgstr "" msgstr ""
#: project/forms/admin.py:26 #: project/forms/admin.py:27
msgid "Incoming reference requests allowed" msgid "Incoming reference requests allowed"
msgstr "" msgstr ""
#: project/forms/admin.py:27 #: project/forms/admin.py:28
msgid "" msgid ""
"If set, other organizations can ask this organization to reference their " "If set, other organizations can ask this organization to reference their "
"event." "event."
msgstr "" msgstr ""
#: project/forms/admin.py:33 #: project/forms/admin.py:34
msgid "Suggestions enabled" msgid "Suggestions enabled"
msgstr "" msgstr ""
#: project/forms/admin.py:34 #: project/forms/admin.py:35
msgid "If set, the organization can work with suggestions." msgid "If set, the organization can work with suggestions."
msgstr "" msgstr ""
#: project/forms/admin.py:38 #: project/forms/admin.py:39
msgid "Create other organizations" msgid "Create other organizations"
msgstr "" msgstr ""
#: project/forms/admin.py:39 #: project/forms/admin.py:40
msgid "If set, members of the organization can create other organizations." msgid "If set, members of the organization can create other organizations."
msgstr "" msgstr ""
#: project/forms/admin.py:45 #: project/forms/admin.py:46
msgid "Invite other organizations" msgid "Invite other organizations"
msgstr "" msgstr ""
#: project/forms/admin.py:46 #: project/forms/admin.py:47
msgid "If set, members of the organization can invite other organizations." msgid "If set, members of the organization can invite other organizations."
msgstr "" msgstr ""
#: project/forms/admin.py:52 #: project/forms/admin.py:53
msgid "Verify other organizations" msgid "Verify other organizations"
msgstr "" msgstr ""
#: project/forms/admin.py:53 #: project/forms/admin.py:54
msgid "If set, members of the organization can verify other organizations." msgid "If set, members of the organization can verify other organizations."
msgstr "" msgstr ""
#: project/forms/admin.py:58 project/templates/admin/update_admin_unit.html:4 #: project/forms/admin.py:59 project/templates/admin/update_admin_unit.html:4
#: project/templates/admin/update_admin_unit.html:8 #: project/templates/admin/update_admin_unit.html:8
msgid "Update organization" msgid "Update organization"
msgstr "" msgstr ""
#: project/forms/admin.py:63
msgid "Recipient"
msgstr ""
#: project/forms/admin.py:65
msgid "Send test mail synchronously"
msgstr ""
#: project/forms/admin_unit.py:15 project/forms/event_place.py:12 #: project/forms/admin_unit.py:15 project/forms/event_place.py:12
#: project/forms/organizer.py:12 #: project/forms/organizer.py:12
msgid "Street" msgid "Street"
@ -348,7 +356,8 @@ msgstr ""
#: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28 #: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28
#: project/forms/event.py:107 project/forms/event_suggestion.py:38 #: project/forms/event.py:107 project/forms/event_suggestion.py:38
#: project/forms/organizer.py:27 project/templates/_macros.html:235 #: project/forms/organizer.py:27 project/templates/_macros.html:235
#: project/templates/_macros.html:1491 project/templates/admin/users.html:19 #: project/templates/_macros.html:1491 project/templates/admin/admin.html:27
#: project/templates/admin/users.html:19
msgid "Email" msgid "Email"
msgstr "" msgstr ""
@ -1365,15 +1374,10 @@ msgstr ""
msgid "Enter list name" msgid "Enter list name"
msgstr "" msgstr ""
#: project/templates/home.html:27 #: project/templates/home.html:24
msgid "Manage" msgid "Manage"
msgstr "" msgstr ""
#: project/templates/home.html:29 project/templates/security/login_user.html:38
#: project/views/widget.py:159
msgid "Register for free"
msgstr ""
#: project/templates/layout.html:152 project/templates/layout.html:200 #: project/templates/layout.html:152 project/templates/layout.html:200
#: project/templates/manage/events.html:6 #: project/templates/manage/events.html:6
#: project/templates/manage/events.html:42 #: project/templates/manage/events.html:42
@ -1409,6 +1413,8 @@ msgstr ""
#: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9 #: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9
#: project/templates/admin/admin_units.html:10 #: project/templates/admin/admin_units.html:10
#: project/templates/admin/email.html:65
#: project/templates/admin/settings.html:10
#: project/templates/admin/users.html:10 project/templates/layout.html:171 #: project/templates/admin/users.html:10 project/templates/layout.html:171
msgid "Admin" msgid "Admin"
msgstr "" msgstr ""
@ -1495,9 +1501,10 @@ msgstr ""
msgid "Organization invitations" msgid "Organization invitations"
msgstr "" msgstr ""
#: project/templates/admin/admin.html:15 #: project/templates/admin/admin.html:15 project/templates/admin/email.html:4
#: project/templates/admin/email.html:66
#: project/templates/admin/settings.html:4 #: project/templates/admin/settings.html:4
#: project/templates/admin/settings.html:8 #: project/templates/admin/settings.html:11
#: project/templates/admin_unit/update.html:6 #: project/templates/admin_unit/update.html:6
#: project/templates/admin_unit/update.html:23 #: project/templates/admin_unit/update.html:23
#: project/templates/layout.html:253 project/templates/manage/widgets.html:11 #: project/templates/layout.html:253 project/templates/manage/widgets.html:11
@ -1553,6 +1560,18 @@ msgstr ""
msgid "Edit" msgid "Edit"
msgstr "" msgstr ""
#: project/templates/admin/email.html:47 project/views/admin.py:119
msgid "Mail sent successfully"
msgstr ""
#: project/templates/admin/email.html:103
msgid "Test mail"
msgstr ""
#: project/templates/admin/email.html:111
msgid "Send test mail asynchronously"
msgstr ""
#: project/templates/admin_unit/create.html:58 #: project/templates/admin_unit/create.html:58
#: project/templates/admin_unit/update.html:59 #: project/templates/admin_unit/update.html:59
#: project/templates/event/create.html:347 #: project/templates/event/create.html:347
@ -1665,6 +1684,14 @@ msgstr ""
msgid "The review status of your event has been updated." msgid "The review status of your event has been updated."
msgstr "" msgstr ""
#: project/templates/email/test_email.html:4
msgid "This is a test mail"
msgstr ""
#: project/templates/email/test_email.html:5
msgid "Click here to open the site"
msgstr ""
#: project/templates/event/actions.html:5 #: project/templates/event/actions.html:5
#: project/templates/event/actions.html:22 #: project/templates/event/actions.html:22
msgid "Actions for event" msgid "Actions for event"
@ -1984,6 +2011,10 @@ msgstr ""
msgid "You do not have an account yet? Not a problem!" msgid "You do not have an account yet? Not a problem!"
msgstr "" msgstr ""
#: project/templates/security/login_user.html:38 project/views/widget.py:159
msgid "Register for free"
msgstr ""
#: project/templates/widget/event_date/list.html:5 #: project/templates/widget/event_date/list.html:5
msgid "Widget" msgid "Widget"
msgstr "" msgstr ""
@ -2004,15 +2035,20 @@ msgstr ""
msgid "Preview" msgid "Preview"
msgstr "" msgstr ""
#: project/views/admin.py:44 #: project/views/admin.py:55
msgid "Organization successfully updated" msgid "Organization successfully updated"
msgstr "" msgstr ""
#: project/views/admin.py:68 project/views/manage.py:361 #: project/views/admin.py:79 project/views/manage.py:361
msgid "Settings successfully updated" msgid "Settings successfully updated"
msgstr "" msgstr ""
#: project/views/admin.py:103 #: project/views/admin.py:108
#, python-format
msgid "Test mail from %(site_name)s"
msgstr ""
#: project/views/admin.py:152
msgid "User successfully updated" msgid "User successfully updated"
msgstr "" msgstr ""

View File

@ -16,10 +16,18 @@ from flask_wtf.csrf import CSRFProtect
from project.custom_session_interface import CustomSessionInterface from project.custom_session_interface import CustomSessionInterface
def getenv_bool(name: str, default: str = "False"): # pragma: no cover def getenv_bool(name: str, default: str = "False"):
return os.getenv(name, default).lower() in ("true", "1", "t") return os.getenv(name, default).lower() in ("true", "1", "t")
def set_env_to_app(app: Flask, key: str, default: str = None):
if key in os.environ and os.environ[key]: # pragma: no cover
app.config[key] = os.environ[key]
if default:
app.config[key] = default
# Create app # Create app
app = Flask(__name__) app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ["DATABASE_URL"] app.config["SQLALCHEMY_DATABASE_URI"] = os.environ["DATABASE_URL"]
@ -34,7 +42,6 @@ app.config["SECURITY_RECOVERABLE"] = True
app.config["SECURITY_CHANGEABLE"] = True app.config["SECURITY_CHANGEABLE"] = True
app.config["SECURITY_EMAIL_SENDER"] = os.getenv("MAIL_DEFAULT_SENDER") app.config["SECURITY_EMAIL_SENDER"] = os.getenv("MAIL_DEFAULT_SENDER")
app.config["LANGUAGES"] = ["en", "de"] app.config["LANGUAGES"] = ["en", "de"]
app.config["SITE_NAME"] = os.getenv("SITE_NAME", "eventcally")
app.config["SERVER_NAME"] = os.getenv("SERVER_NAME") app.config["SERVER_NAME"] = os.getenv("SERVER_NAME")
app.config["DOCS_URL"] = os.getenv("DOCS_URL") app.config["DOCS_URL"] = os.getenv("DOCS_URL")
app.config["ADMIN_UNIT_CREATE_REQUIRES_ADMIN"] = os.getenv( app.config["ADMIN_UNIT_CREATE_REQUIRES_ADMIN"] = os.getenv(
@ -42,6 +49,7 @@ app.config["ADMIN_UNIT_CREATE_REQUIRES_ADMIN"] = os.getenv(
) )
app.config["SEO_SITEMAP_PING_GOOGLE"] = getenv_bool("SEO_SITEMAP_PING_GOOGLE", "False") app.config["SEO_SITEMAP_PING_GOOGLE"] = getenv_bool("SEO_SITEMAP_PING_GOOGLE", "False")
app.config["GOOGLE_MAPS_API_KEY"] = os.getenv("GOOGLE_MAPS_API_KEY") app.config["GOOGLE_MAPS_API_KEY"] = os.getenv("GOOGLE_MAPS_API_KEY")
set_env_to_app(app, "SITE_NAME", "EventCally")
# Proxy handling # Proxy handling
if os.getenv("PREFERRED_URL_SCHEME"): # pragma: no cover if os.getenv("PREFERRED_URL_SCHEME"): # pragma: no cover
@ -58,11 +66,8 @@ app.config.update(
"broker_url": app.config["REDIS_URL"], "broker_url": app.config["REDIS_URL"],
"result_backend": app.config["REDIS_URL"], "result_backend": app.config["REDIS_URL"],
"result_expires": timedelta(hours=1), "result_expires": timedelta(hours=1),
"broker_pool_limit": None,
"redis_max_connections": 2,
"timezone": "Europe/Berlin", "timezone": "Europe/Berlin",
"broker_transport_options": { "broker_transport_options": {
"max_connections": 2,
"queue_order_strategy": "priority", "queue_order_strategy": "priority",
"priority_steps": list(range(3)), "priority_steps": list(range(3)),
"sep": ":", "sep": ":",

10
project/base_tasks.py Normal file
View File

@ -0,0 +1,10 @@
from project import app, celery
from project.views.utils import send_mail
@celery.task(
base=getattr(app, "celery_http_task_cls"),
priority=0,
)
def send_mail_task(recipient, subject, template):
send_mail(recipient, subject, template)

View File

@ -2,13 +2,8 @@ from smtplib import SMTPException
from urllib.error import URLError from urllib.error import URLError
from celery import Celery from celery import Celery
from celery.signals import ( from celery import Task as BaseTask
after_setup_logger, from celery.signals import after_setup_logger, after_setup_task_logger, task_postrun
after_setup_task_logger,
task_postrun,
worker_ready,
)
from celery_singleton import Singleton, clear_locks
from requests.exceptions import RequestException from requests.exceptions import RequestException
@ -19,7 +14,7 @@ class HttpTaskException(Exception):
def create_celery(app): def create_celery(app):
celery = Celery(app.import_name) celery = Celery(app.import_name)
celery.conf.update(app.config["CELERY_CONFIG"]) celery.conf.update(app.config["CELERY_CONFIG"])
TaskBase = Singleton TaskBase = BaseTask
class ContextTask(TaskBase): class ContextTask(TaskBase):
abstract = True abstract = True
@ -71,13 +66,6 @@ def setup_task_logger(logger, *args, **kwargs):
init_logger_with_one_line_formatter(logger) init_logger_with_one_line_formatter(logger)
@worker_ready.connect
def unlock_all(**kwargs):
from project import celery
clear_locks(celery)
@task_postrun.connect @task_postrun.connect
def close_session(*args, **kwargs): def close_session(*args, **kwargs):
from project import app from project import app

View File

@ -1,7 +1,8 @@
from flask_babelex import lazy_gettext from flask_babelex import lazy_gettext
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import BooleanField, SubmitField, TextAreaField from wtforms import BooleanField, SubmitField, TextAreaField
from wtforms.validators import Optional from wtforms.fields.html5 import EmailField
from wtforms.validators import DataRequired, Optional
from project.forms.widgets import MultiCheckboxField from project.forms.widgets import MultiCheckboxField
@ -56,3 +57,9 @@ class UpdateAdminUnitForm(FlaskForm):
validators=[Optional()], validators=[Optional()],
) )
submit = SubmitField(lazy_gettext("Update organization")) submit = SubmitField(lazy_gettext("Update organization"))
class AdminTestEmailForm(FlaskForm):
recipient = EmailField(lazy_gettext("Recipient"), validators=[DataRequired()])
submit = SubmitField(lazy_gettext("Send test mail synchronously"))

View File

@ -26,6 +26,9 @@ def any_dict_value_true(data: dict):
def ensure_link_scheme(link: str): def ensure_link_scheme(link: str):
if not link: # pragma: no cover
return link
if link.startswith("http://") or link.startswith("https://"): if link.startswith("http://") or link.startswith("https://"):
return link return link

View File

@ -23,6 +23,10 @@
{{ _('Users') }} {{ _('Users') }}
<i class="fa fa-caret-right"></i> <i class="fa fa-caret-right"></i>
</a> </a>
<a href="{{ url_for('admin_email') }}" class="list-group-item">
{{ _('Email') }}
<i class="fa fa-caret-right"></i>
</a>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,124 @@
{% extends "layout.html" %}
{% from "_macros.html" import render_field, render_field_with_errors %}
{%- block title -%}
{{ _('Settings') }}
{%- endblock -%}
{% block header %}
<script>
function submit_async() {
handle_request_start();
$.ajax({
url: "{{ url_for('admin_email', async=1) }}",
type: "post",
dataType: "json",
data: $("#test_mail_form").serialize(),
error: function(xhr, status, error) {
handle_request_error(xhr, status, error);
},
success: function (data) {
poll(data["result_id"]);
}
});
}
function poll(result_id) {
$.ajax({
url: "{{ url_for('admin_email') }}",
type: "get",
dataType: "json",
data: "poll=" + result_id,
error: function(xhr, status, error) {
handle_request_error(xhr, status, error);
},
success: function (data) {
if (!data["ready"]) {
setTimeout(function() {
poll(result_id);
}, 500);
return;
}
if (!data["successful"]) {
console.error(data);
handle_request_error(null, JSON.stringify(data), data);
return;
}
$("#result_container").text("{{ _('Mail sent successfully') }}");
handle_request_success();
}
});
}
$( function() {
$("#submit_async").click(function(){
submit_async();
return false;
});
});
</script>
{% endblock %}
{% block content %}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ url_for('admin') }}">{{ _('Admin') }}</a></li>
<li class="breadcrumb-item active" aria-current="page">{{ _('Settings') }}</li>
</ol>
</nav>
<table class="table table-striped table-bordered my-4">
<tbody>
<tr>
<td>MAIL_SUPPRESS_SEND</td>
<td>{{ config["MAIL_SUPPRESS_SEND"] }}</td>
</tr>
<tr>
<td>MAIL_SERVER</td>
<td>{{ config["MAIL_SERVER"] }}</td>
</tr>
<tr>
<td>MAIL_PORT</td>
<td>{{ config["MAIL_PORT"] }}</td>
</tr>
<tr>
<td>MAIL_USE_TLS</td>
<td>{{ config["MAIL_USE_TLS"] }}</td>
</tr>
<tr>
<td>MAIL_USE_SSL</td>
<td>{{ config["MAIL_USE_SSL"] }}</td>
</tr>
<tr>
<td>MAIL_USERNAME</td>
<td>{{ config["MAIL_USERNAME"] }}</td>
</tr>
<tr>
<td>MAIL_PASSWORD</td>
<td>{{ config["MAIL_PASSWORD"] }}</td>
</tr>
</tbody>
</table>
<h4>{{ _('Test mail')}} </h4>
<form id="test_mail_form" action="" method="POST">
{{ form.hidden_tag() }}
{{ render_field_with_errors(form.recipient) }}
{{ render_field(form.submit) }}
</form>
<p>
<button id="submit_async" type="button" class="btn btn-outline-primary">{{ _('Send test mail asynchronously') }}</button>
<div class="col-md">
<div id="result_container">
</div>
<div class="spinner-border m-3" role="status" id="spinner" style="display: none;">
<span class="sr-only">Loading&hellip;</span>
</div>
<div class="alert alert-danger m-3" role="alert" id="error_alert" style="display: none;"></div>
</div>
</p>
{% endblock %}

View File

@ -5,7 +5,12 @@
{%- endblock -%} {%- endblock -%}
{% block content %} {% block content %}
<h1>{{ _('Settings') }}</h1> <nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ url_for('admin') }}">{{ _('Admin') }}</a></li>
<li class="breadcrumb-item active" aria-current="page">{{ _('Settings') }}</li>
</ol>
</nav>
<form action="" method="POST"> <form action="" method="POST">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}

View File

@ -0,0 +1,6 @@
{% extends "email/layout.html" %}
{% from "_macros.html" import render_email_button %}
{% block content %}
<p>{{ _('This is a test mail') }}</p>
{{ render_email_button(url_for('home', _external=True), _('Click here to open the site')) }}
{% endblock %}

View File

@ -0,0 +1,3 @@
{{ _('This is a test mail') }}
{{ _('Click the link below to open the site') }}
{{ url_for('home', _external=True) }}

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2023-03-16 19:11+0100\n" "POT-Creation-Date: 2023-03-24 21:24+0100\n"
"PO-Revision-Date: 2020-06-07 18:51+0200\n" "PO-Revision-Date: 2020-06-07 18:51+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: de\n" "Language: de\n"
@ -199,51 +199,51 @@ msgstr "message"
msgid "You have received an invitation" msgid "You have received an invitation"
msgstr "Du hast eine Einladung erhalten" msgstr "Du hast eine Einladung erhalten"
#: project/forms/admin.py:10 project/templates/layout.html:294 #: project/forms/admin.py:11 project/templates/layout.html:294
#: project/views/root.py:57 #: project/views/root.py:53
msgid "Terms of service" msgid "Terms of service"
msgstr "Nutzungsbedingungen" msgstr "Nutzungsbedingungen"
#: project/forms/admin.py:11 project/templates/layout.html:298 #: project/forms/admin.py:12 project/templates/layout.html:298
#: project/views/root.py:65 #: project/views/root.py:61
msgid "Legal notice" msgid "Legal notice"
msgstr "Impressum" msgstr "Impressum"
#: project/forms/admin.py:12 project/templates/_macros.html:1395 #: project/forms/admin.py:13 project/templates/_macros.html:1395
#: project/templates/layout.html:302 #: project/templates/layout.html:302
#: project/templates/widget/event_suggestion/create.html:204 #: project/templates/widget/event_suggestion/create.html:204
#: project/views/admin_unit.py:73 project/views/root.py:73 #: project/views/admin_unit.py:73 project/views/root.py:69
msgid "Contact" msgid "Contact"
msgstr "Kontakt" msgstr "Kontakt"
#: project/forms/admin.py:13 project/templates/layout.html:306 #: project/forms/admin.py:14 project/templates/layout.html:306
#: project/views/root.py:81 #: project/views/root.py:77
msgid "Privacy" msgid "Privacy"
msgstr "Datenschutz" msgstr "Datenschutz"
#: project/forms/admin.py:14 #: project/forms/admin.py:15
msgid "Start page" msgid "Start page"
msgstr "Startseite" msgstr "Startseite"
#: project/forms/admin.py:16 project/forms/oauth2_client.py:24 #: project/forms/admin.py:17 project/forms/oauth2_client.py:24
msgid "Save" msgid "Save"
msgstr "Speichern" msgstr "Speichern"
#: project/forms/admin.py:20 project/forms/admin_unit_member.py:12 #: project/forms/admin.py:21 project/forms/admin_unit_member.py:12
#: project/forms/admin_unit_member.py:32 #: project/forms/admin_unit_member.py:32
msgid "Roles" msgid "Roles"
msgstr "Rollen" msgstr "Rollen"
#: project/forms/admin.py:21 project/templates/admin/update_user.html:4 #: project/forms/admin.py:22 project/templates/admin/update_user.html:4
#: project/templates/admin/update_user.html:8 #: project/templates/admin/update_user.html:8
msgid "Update user" msgid "Update user"
msgstr "Nutzer aktualisieren" msgstr "Nutzer aktualisieren"
#: project/forms/admin.py:26 #: project/forms/admin.py:27
msgid "Incoming reference requests allowed" msgid "Incoming reference requests allowed"
msgstr "Eingehende Empfehlungsanfragen erlauben" msgstr "Eingehende Empfehlungsanfragen erlauben"
#: project/forms/admin.py:27 #: project/forms/admin.py:28
msgid "" msgid ""
"If set, other organizations can ask this organization to reference their " "If set, other organizations can ask this organization to reference their "
"event." "event."
@ -251,49 +251,57 @@ msgstr ""
"Wenn gesetzt, können andere Organisationen diese Organisation bitten, " "Wenn gesetzt, können andere Organisationen diese Organisation bitten, "
"deren Veranstaltungen zu empfehlen." "deren Veranstaltungen zu empfehlen."
#: project/forms/admin.py:33 #: project/forms/admin.py:34
msgid "Suggestions enabled" msgid "Suggestions enabled"
msgstr "Vorschläge aktiv" msgstr "Vorschläge aktiv"
#: project/forms/admin.py:34 #: project/forms/admin.py:35
msgid "If set, the organization can work with suggestions." msgid "If set, the organization can work with suggestions."
msgstr "Wenn gesetzt, kann die Organisation mit Vorschlägen arbeiten." msgstr "Wenn gesetzt, kann die Organisation mit Vorschlägen arbeiten."
#: project/forms/admin.py:38 #: project/forms/admin.py:39
msgid "Create other organizations" msgid "Create other organizations"
msgstr "Andere Organisationen erstellen" msgstr "Andere Organisationen erstellen"
#: project/forms/admin.py:39 #: project/forms/admin.py:40
msgid "If set, members of the organization can create other organizations." msgid "If set, members of the organization can create other organizations."
msgstr "" msgstr ""
"Wenn gesetzt, können Mitglieder der Organisation andere Organisationen " "Wenn gesetzt, können Mitglieder der Organisation andere Organisationen "
"erstellen." "erstellen."
#: project/forms/admin.py:45 #: project/forms/admin.py:46
msgid "Invite other organizations" msgid "Invite other organizations"
msgstr "Andere Organisationen einladen" msgstr "Andere Organisationen einladen"
#: project/forms/admin.py:46 #: project/forms/admin.py:47
msgid "If set, members of the organization can invite other organizations." msgid "If set, members of the organization can invite other organizations."
msgstr "" msgstr ""
"Wenn gesetzt, können Mitglieder der Organisation andere Organisationen " "Wenn gesetzt, können Mitglieder der Organisation andere Organisationen "
"einladen." "einladen."
#: project/forms/admin.py:52 #: project/forms/admin.py:53
msgid "Verify other organizations" msgid "Verify other organizations"
msgstr "Andere Organisationen verifizieren" msgstr "Andere Organisationen verifizieren"
#: project/forms/admin.py:53 #: project/forms/admin.py:54
msgid "If set, members of the organization can verify other organizations." msgid "If set, members of the organization can verify other organizations."
msgstr "" msgstr ""
"Wenn gesetzt, können Mitglieder der Organisation andere Organisationen " "Wenn gesetzt, können Mitglieder der Organisation andere Organisationen "
"verifizieren." "verifizieren."
#: project/forms/admin.py:58 project/templates/admin/update_admin_unit.html:4 #: project/forms/admin.py:59 project/templates/admin/update_admin_unit.html:4
#: project/templates/admin/update_admin_unit.html:8 #: project/templates/admin/update_admin_unit.html:8
msgid "Update organization" msgid "Update organization"
msgstr "Organisation aktualisieren" msgstr "Organisation aktualisieren"
#: project/forms/admin.py:63
msgid "Recipient"
msgstr "Empfänger"
#: project/forms/admin.py:65
msgid "Send test mail synchronously"
msgstr "Test-Mail synchron senden"
#: project/forms/admin_unit.py:15 project/forms/event_place.py:12 #: project/forms/admin_unit.py:15 project/forms/event_place.py:12
#: project/forms/organizer.py:12 #: project/forms/organizer.py:12
msgid "Street" msgid "Street"
@ -360,7 +368,8 @@ msgstr "Link URL"
#: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28 #: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28
#: project/forms/event.py:107 project/forms/event_suggestion.py:38 #: project/forms/event.py:107 project/forms/event_suggestion.py:38
#: project/forms/organizer.py:27 project/templates/_macros.html:235 #: project/forms/organizer.py:27 project/templates/_macros.html:235
#: project/templates/_macros.html:1491 project/templates/admin/users.html:19 #: project/templates/_macros.html:1491 project/templates/admin/admin.html:27
#: project/templates/admin/users.html:19
msgid "Email" msgid "Email"
msgstr "Email" msgstr "Email"
@ -1415,15 +1424,10 @@ msgstr "Veranstalter eingeben"
msgid "Enter list name" msgid "Enter list name"
msgstr "Listenname eingeben" msgstr "Listenname eingeben"
#: project/templates/home.html:27 #: project/templates/home.html:24
msgid "Manage" msgid "Manage"
msgstr "Verwaltung" msgstr "Verwaltung"
#: project/templates/home.html:29 project/templates/security/login_user.html:38
#: project/views/widget.py:159
msgid "Register for free"
msgstr "Kostenlos registrieren"
#: project/templates/layout.html:152 project/templates/layout.html:200 #: project/templates/layout.html:152 project/templates/layout.html:200
#: project/templates/manage/events.html:6 #: project/templates/manage/events.html:6
#: project/templates/manage/events.html:42 #: project/templates/manage/events.html:42
@ -1459,6 +1463,8 @@ msgstr "Profil"
#: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9 #: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9
#: project/templates/admin/admin_units.html:10 #: project/templates/admin/admin_units.html:10
#: project/templates/admin/email.html:65
#: project/templates/admin/settings.html:10
#: project/templates/admin/users.html:10 project/templates/layout.html:171 #: project/templates/admin/users.html:10 project/templates/layout.html:171
msgid "Admin" msgid "Admin"
msgstr "Administration" msgstr "Administration"
@ -1545,9 +1551,10 @@ msgstr "Beziehungen"
msgid "Organization invitations" msgid "Organization invitations"
msgstr "Organisationseinladungen" msgstr "Organisationseinladungen"
#: project/templates/admin/admin.html:15 #: project/templates/admin/admin.html:15 project/templates/admin/email.html:4
#: project/templates/admin/email.html:66
#: project/templates/admin/settings.html:4 #: project/templates/admin/settings.html:4
#: project/templates/admin/settings.html:8 #: project/templates/admin/settings.html:11
#: project/templates/admin_unit/update.html:6 #: project/templates/admin_unit/update.html:6
#: project/templates/admin_unit/update.html:23 #: project/templates/admin_unit/update.html:23
#: project/templates/layout.html:253 project/templates/manage/widgets.html:11 #: project/templates/layout.html:253 project/templates/manage/widgets.html:11
@ -1603,6 +1610,18 @@ msgstr "Benutzer"
msgid "Edit" msgid "Edit"
msgstr "Bearbeiten" msgstr "Bearbeiten"
#: project/templates/admin/email.html:47 project/views/admin.py:119
msgid "Mail sent successfully"
msgstr "Mail erfolgreich gesendet"
#: project/templates/admin/email.html:103
msgid "Test mail"
msgstr "Test-Mail"
#: project/templates/admin/email.html:111
msgid "Send test mail asynchronously"
msgstr "Test-Mail asynchron senden"
#: project/templates/admin_unit/create.html:58 #: project/templates/admin_unit/create.html:58
#: project/templates/admin_unit/update.html:59 #: project/templates/admin_unit/update.html:59
#: project/templates/event/create.html:347 #: project/templates/event/create.html:347
@ -1717,6 +1736,14 @@ msgstr "Klicke hier, um den Vorschlag zu prüfen"
msgid "The review status of your event has been updated." msgid "The review status of your event has been updated."
msgstr "Der Prüfungsstatus deiner Veranstaltung wurde aktualisiert" msgstr "Der Prüfungsstatus deiner Veranstaltung wurde aktualisiert"
#: project/templates/email/test_email.html:4
msgid "This is a test mail"
msgstr "Das ist eine Test-Mail"
#: project/templates/email/test_email.html:5
msgid "Click here to open the site"
msgstr "Klicke hier, um die Seite zu öffnen"
#: project/templates/event/actions.html:5 #: project/templates/event/actions.html:5
#: project/templates/event/actions.html:22 #: project/templates/event/actions.html:22
msgid "Actions for event" msgid "Actions for event"
@ -2045,6 +2072,10 @@ msgstr "Angemeldet bleiben"
msgid "You do not have an account yet? Not a problem!" msgid "You do not have an account yet? Not a problem!"
msgstr "Du hast noch keinen Account? Kein Problem!" msgstr "Du hast noch keinen Account? Kein Problem!"
#: project/templates/security/login_user.html:38 project/views/widget.py:159
msgid "Register for free"
msgstr "Kostenlos registrieren"
#: project/templates/widget/event_date/list.html:5 #: project/templates/widget/event_date/list.html:5
msgid "Widget" msgid "Widget"
msgstr "Widget" msgstr "Widget"
@ -2065,15 +2096,20 @@ msgstr "Optionale Details"
msgid "Preview" msgid "Preview"
msgstr "Vorschau" msgstr "Vorschau"
#: project/views/admin.py:44 #: project/views/admin.py:55
msgid "Organization successfully updated" msgid "Organization successfully updated"
msgstr "Organisation erfolgreich aktualisiert" msgstr "Organisation erfolgreich aktualisiert"
#: project/views/admin.py:68 project/views/manage.py:361 #: project/views/admin.py:79 project/views/manage.py:361
msgid "Settings successfully updated" msgid "Settings successfully updated"
msgstr "Einstellungen erfolgreich aktualisiert" msgstr "Einstellungen erfolgreich aktualisiert"
#: project/views/admin.py:103 #: project/views/admin.py:108
#, python-format
msgid "Test mail from %(site_name)s"
msgstr "Test-Mail from %(site_name)s"
#: project/views/admin.py:152
msgid "User successfully updated" msgid "User successfully updated"
msgstr "Nutzer erfolgreich aktualisiert" msgstr "Nutzer erfolgreich aktualisiert"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2023-03-16 19:11+0100\n" "POT-Creation-Date: 2023-03-24 21:24+0100\n"
"PO-Revision-Date: 2021-04-30 15:04+0200\n" "PO-Revision-Date: 2021-04-30 15:04+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n" "Language: en\n"
@ -199,93 +199,101 @@ msgstr ""
msgid "You have received an invitation" msgid "You have received an invitation"
msgstr "" msgstr ""
#: project/forms/admin.py:10 project/templates/layout.html:294 #: project/forms/admin.py:11 project/templates/layout.html:294
#: project/views/root.py:57 #: project/views/root.py:53
msgid "Terms of service" msgid "Terms of service"
msgstr "" msgstr ""
#: project/forms/admin.py:11 project/templates/layout.html:298 #: project/forms/admin.py:12 project/templates/layout.html:298
#: project/views/root.py:65 #: project/views/root.py:61
msgid "Legal notice" msgid "Legal notice"
msgstr "" msgstr ""
#: project/forms/admin.py:12 project/templates/_macros.html:1395 #: project/forms/admin.py:13 project/templates/_macros.html:1395
#: project/templates/layout.html:302 #: project/templates/layout.html:302
#: project/templates/widget/event_suggestion/create.html:204 #: project/templates/widget/event_suggestion/create.html:204
#: project/views/admin_unit.py:73 project/views/root.py:73 #: project/views/admin_unit.py:73 project/views/root.py:69
msgid "Contact" msgid "Contact"
msgstr "" msgstr ""
#: project/forms/admin.py:13 project/templates/layout.html:306 #: project/forms/admin.py:14 project/templates/layout.html:306
#: project/views/root.py:81 #: project/views/root.py:77
msgid "Privacy" msgid "Privacy"
msgstr "" msgstr ""
#: project/forms/admin.py:14 #: project/forms/admin.py:15
msgid "Start page" msgid "Start page"
msgstr "" msgstr ""
#: project/forms/admin.py:16 project/forms/oauth2_client.py:24 #: project/forms/admin.py:17 project/forms/oauth2_client.py:24
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: project/forms/admin.py:20 project/forms/admin_unit_member.py:12 #: project/forms/admin.py:21 project/forms/admin_unit_member.py:12
#: project/forms/admin_unit_member.py:32 #: project/forms/admin_unit_member.py:32
msgid "Roles" msgid "Roles"
msgstr "" msgstr ""
#: project/forms/admin.py:21 project/templates/admin/update_user.html:4 #: project/forms/admin.py:22 project/templates/admin/update_user.html:4
#: project/templates/admin/update_user.html:8 #: project/templates/admin/update_user.html:8
msgid "Update user" msgid "Update user"
msgstr "" msgstr ""
#: project/forms/admin.py:26 #: project/forms/admin.py:27
msgid "Incoming reference requests allowed" msgid "Incoming reference requests allowed"
msgstr "" msgstr ""
#: project/forms/admin.py:27 #: project/forms/admin.py:28
msgid "" msgid ""
"If set, other organizations can ask this organization to reference their " "If set, other organizations can ask this organization to reference their "
"event." "event."
msgstr "" msgstr ""
#: project/forms/admin.py:33 #: project/forms/admin.py:34
msgid "Suggestions enabled" msgid "Suggestions enabled"
msgstr "" msgstr ""
#: project/forms/admin.py:34 #: project/forms/admin.py:35
msgid "If set, the organization can work with suggestions." msgid "If set, the organization can work with suggestions."
msgstr "" msgstr ""
#: project/forms/admin.py:38 #: project/forms/admin.py:39
msgid "Create other organizations" msgid "Create other organizations"
msgstr "" msgstr ""
#: project/forms/admin.py:39 #: project/forms/admin.py:40
msgid "If set, members of the organization can create other organizations." msgid "If set, members of the organization can create other organizations."
msgstr "" msgstr ""
#: project/forms/admin.py:45 #: project/forms/admin.py:46
msgid "Invite other organizations" msgid "Invite other organizations"
msgstr "" msgstr ""
#: project/forms/admin.py:46 #: project/forms/admin.py:47
msgid "If set, members of the organization can invite other organizations." msgid "If set, members of the organization can invite other organizations."
msgstr "" msgstr ""
#: project/forms/admin.py:52 #: project/forms/admin.py:53
msgid "Verify other organizations" msgid "Verify other organizations"
msgstr "" msgstr ""
#: project/forms/admin.py:53 #: project/forms/admin.py:54
msgid "If set, members of the organization can verify other organizations." msgid "If set, members of the organization can verify other organizations."
msgstr "" msgstr ""
#: project/forms/admin.py:58 project/templates/admin/update_admin_unit.html:4 #: project/forms/admin.py:59 project/templates/admin/update_admin_unit.html:4
#: project/templates/admin/update_admin_unit.html:8 #: project/templates/admin/update_admin_unit.html:8
msgid "Update organization" msgid "Update organization"
msgstr "" msgstr ""
#: project/forms/admin.py:63
msgid "Recipient"
msgstr ""
#: project/forms/admin.py:65
msgid "Send test mail synchronously"
msgstr ""
#: project/forms/admin_unit.py:15 project/forms/event_place.py:12 #: project/forms/admin_unit.py:15 project/forms/event_place.py:12
#: project/forms/organizer.py:12 #: project/forms/organizer.py:12
msgid "Street" msgid "Street"
@ -349,7 +357,8 @@ msgstr ""
#: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28 #: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28
#: project/forms/event.py:107 project/forms/event_suggestion.py:38 #: project/forms/event.py:107 project/forms/event_suggestion.py:38
#: project/forms/organizer.py:27 project/templates/_macros.html:235 #: project/forms/organizer.py:27 project/templates/_macros.html:235
#: project/templates/_macros.html:1491 project/templates/admin/users.html:19 #: project/templates/_macros.html:1491 project/templates/admin/admin.html:27
#: project/templates/admin/users.html:19
msgid "Email" msgid "Email"
msgstr "" msgstr ""
@ -1366,15 +1375,10 @@ msgstr ""
msgid "Enter list name" msgid "Enter list name"
msgstr "" msgstr ""
#: project/templates/home.html:27 #: project/templates/home.html:24
msgid "Manage" msgid "Manage"
msgstr "" msgstr ""
#: project/templates/home.html:29 project/templates/security/login_user.html:38
#: project/views/widget.py:159
msgid "Register for free"
msgstr ""
#: project/templates/layout.html:152 project/templates/layout.html:200 #: project/templates/layout.html:152 project/templates/layout.html:200
#: project/templates/manage/events.html:6 #: project/templates/manage/events.html:6
#: project/templates/manage/events.html:42 #: project/templates/manage/events.html:42
@ -1410,6 +1414,8 @@ msgstr ""
#: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9 #: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9
#: project/templates/admin/admin_units.html:10 #: project/templates/admin/admin_units.html:10
#: project/templates/admin/email.html:65
#: project/templates/admin/settings.html:10
#: project/templates/admin/users.html:10 project/templates/layout.html:171 #: project/templates/admin/users.html:10 project/templates/layout.html:171
msgid "Admin" msgid "Admin"
msgstr "" msgstr ""
@ -1496,9 +1502,10 @@ msgstr ""
msgid "Organization invitations" msgid "Organization invitations"
msgstr "" msgstr ""
#: project/templates/admin/admin.html:15 #: project/templates/admin/admin.html:15 project/templates/admin/email.html:4
#: project/templates/admin/email.html:66
#: project/templates/admin/settings.html:4 #: project/templates/admin/settings.html:4
#: project/templates/admin/settings.html:8 #: project/templates/admin/settings.html:11
#: project/templates/admin_unit/update.html:6 #: project/templates/admin_unit/update.html:6
#: project/templates/admin_unit/update.html:23 #: project/templates/admin_unit/update.html:23
#: project/templates/layout.html:253 project/templates/manage/widgets.html:11 #: project/templates/layout.html:253 project/templates/manage/widgets.html:11
@ -1554,6 +1561,18 @@ msgstr ""
msgid "Edit" msgid "Edit"
msgstr "" msgstr ""
#: project/templates/admin/email.html:47 project/views/admin.py:119
msgid "Mail sent successfully"
msgstr ""
#: project/templates/admin/email.html:103
msgid "Test mail"
msgstr ""
#: project/templates/admin/email.html:111
msgid "Send test mail asynchronously"
msgstr ""
#: project/templates/admin_unit/create.html:58 #: project/templates/admin_unit/create.html:58
#: project/templates/admin_unit/update.html:59 #: project/templates/admin_unit/update.html:59
#: project/templates/event/create.html:347 #: project/templates/event/create.html:347
@ -1666,6 +1685,14 @@ msgstr ""
msgid "The review status of your event has been updated." msgid "The review status of your event has been updated."
msgstr "" msgstr ""
#: project/templates/email/test_email.html:4
msgid "This is a test mail"
msgstr ""
#: project/templates/email/test_email.html:5
msgid "Click here to open the site"
msgstr ""
#: project/templates/event/actions.html:5 #: project/templates/event/actions.html:5
#: project/templates/event/actions.html:22 #: project/templates/event/actions.html:22
msgid "Actions for event" msgid "Actions for event"
@ -1985,6 +2012,10 @@ msgstr ""
msgid "You do not have an account yet? Not a problem!" msgid "You do not have an account yet? Not a problem!"
msgstr "" msgstr ""
#: project/templates/security/login_user.html:38 project/views/widget.py:159
msgid "Register for free"
msgstr ""
#: project/templates/widget/event_date/list.html:5 #: project/templates/widget/event_date/list.html:5
msgid "Widget" msgid "Widget"
msgstr "" msgstr ""
@ -2005,15 +2036,20 @@ msgstr ""
msgid "Preview" msgid "Preview"
msgstr "" msgstr ""
#: project/views/admin.py:44 #: project/views/admin.py:55
msgid "Organization successfully updated" msgid "Organization successfully updated"
msgstr "" msgstr ""
#: project/views/admin.py:68 project/views/manage.py:361 #: project/views/admin.py:79 project/views/manage.py:361
msgid "Settings successfully updated" msgid "Settings successfully updated"
msgstr "" msgstr ""
#: project/views/admin.py:103 #: project/views/admin.py:108
#, python-format
msgid "Test mail from %(site_name)s"
msgstr ""
#: project/views/admin.py:152
msgid "User successfully updated" msgid "User successfully updated"
msgstr "" msgstr ""

View File

@ -1,15 +1,26 @@
from flask import flash, redirect, render_template, url_for from flask import flash, redirect, render_template, request, url_for
from flask_babelex import gettext from flask_babelex import gettext
from flask_security import roles_required from flask_security import roles_required
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.sql import func from sqlalchemy.sql import func
from project import app, db from project import app, celery, db
from project.forms.admin import AdminSettingsForm, UpdateAdminUnitForm, UpdateUserForm from project.base_tasks import send_mail_task
from project.forms.admin import (
AdminSettingsForm,
AdminTestEmailForm,
UpdateAdminUnitForm,
UpdateUserForm,
)
from project.models import AdminUnit, Role, User from project.models import AdminUnit, Role, User
from project.services.admin import upsert_settings from project.services.admin import upsert_settings
from project.services.user import set_roles_for_user from project.services.user import set_roles_for_user
from project.views.utils import flash_errors, get_pagination_urls, handleSqlError from project.views.utils import (
flash_errors,
get_pagination_urls,
handleSqlError,
send_mail,
)
@app.route("/admin") @app.route("/admin")
@ -76,6 +87,44 @@ def admin_settings():
return render_template("admin/settings.html", form=form) return render_template("admin/settings.html", form=form)
@app.route("/admin/email", methods=["GET", "POST"])
@roles_required("admin")
def admin_email():
form = AdminTestEmailForm()
if "poll" in request.args: # pragma: no cover
try:
result = celery.AsyncResult(request.args["poll"])
ready = result.ready()
return {
"ready": ready,
"successful": result.successful() if ready else None,
"value": result.get() if ready else result.result,
}
except Exception as e:
return {"ready": True, "successful": False, "error": str(e)}
if form.validate_on_submit():
subject = gettext(
"Test mail from %(site_name)s",
site_name=app.config["SITE_NAME"],
)
if "async" in request.args: # pragma: no cover
result = send_mail_task.delay(form.recipient.data, subject, "test_email")
return {"result_id": result.id}
try:
send_mail(form.recipient.data, subject, "test_email")
flash(gettext("Mail sent successfully"), "success")
except Exception as e: # pragma: no cover
flash(str(e), "danger")
else: # pragma: no cover
flash_errors(form)
return render_template("admin/email.html", form=form)
@app.route("/admin/users") @app.route("/admin/users")
@roles_required("admin") @roles_required("admin")
def admin_users(): def admin_users():

View File

@ -27,7 +27,7 @@ def get_current_admin_unit(fallback=True):
if admin_unit: if admin_unit:
return admin_unit return admin_unit
if current_user.is_authenticated: if current_user and current_user.is_authenticated:
admin_unit = get_current_admin_unit_from_cookies() admin_unit = get_current_admin_unit_from_cookies()
if not admin_unit and fallback: if not admin_unit and fallback:
@ -44,7 +44,7 @@ def get_current_admin_unit(fallback=True):
def get_current_admin_unit_from_cookies(): def get_current_admin_unit_from_cookies():
try: try:
if "manage_admin_unit_id" in request.cookies: if request and request.cookies and "manage_admin_unit_id" in request.cookies:
encoded = request.cookies.get("manage_admin_unit_id") encoded = request.cookies.get("manage_admin_unit_id")
manage_admin_unit_id = int(decode_cookie(encoded)) manage_admin_unit_id = int(decode_cookie(encoded))
return get_admin_unit_for_manage(manage_admin_unit_id) return get_admin_unit_for_manage(manage_admin_unit_id)

View File

@ -17,7 +17,6 @@ black==23.1.0
blinker==1.4 blinker==1.4
cached-property==1.5.2 cached-property==1.5.2
celery==5.2.7 celery==5.2.7
celery-singleton==0.3.1
certifi==2020.12.5 certifi==2020.12.5
cffi==1.14.4 cffi==1.14.4
cfgv==3.2.0 cfgv==3.2.0
@ -121,7 +120,7 @@ TatSu==4.4.0
toml==0.10.2 toml==0.10.2
tomli==2.0.1 tomli==2.0.1
typed-ast==1.5.4 typed-ast==1.5.4
typing_extensions==4.5.0 typing-extensions==4.5.0
urllib3==1.26.5 urllib3==1.26.5
URLObject==2.4.3 URLObject==2.4.3
validators==0.18.2 validators==0.18.2

View File

@ -60,6 +60,25 @@ def test_admin_settings(client, seeder, utils, app, mocker, db_error):
assert settings.privacy == "Mein Datenschutz" assert settings.privacy == "Mein Datenschutz"
def test_admin_email(client, seeder, utils, app, mocker):
user_id, admin_unit_id = seeder.setup_base(True)
url = utils.get_url("admin_email")
response = utils.get_ok(url)
mail_mock = utils.mock_send_mails(mocker)
response = utils.post_form(
url,
response,
{
"recipient": "test@test.de",
},
)
utils.assert_response_ok(response)
utils.assert_send_mail_called(mail_mock, "test@test.de")
def test_admin_users(client, seeder, utils, app): def test_admin_users(client, seeder, utils, app):
seeder.create_user(admin=True) seeder.create_user(admin=True)
user = utils.login() user = utils.login()

View File

@ -1,3 +1,3 @@
def test_index(client): def test_index(client):
response = client.get("/") response = client.get("/")
assert b"eventcally" in response.data assert b"EventCally" in response.data