mirror of
https://github.com/lucaspalomodevelop/eventcally.git
synced 2026-03-13 00:07:22 +00:00
commit
f1cb72186f
@ -68,13 +68,6 @@ Create `.env` file in the root directory or pass as environment variables.
|
||||
| MAIL_SERVER | " |
|
||||
| MAIL_USERNAME | " |
|
||||
|
||||
### Login with Google via OAuth
|
||||
|
||||
| Variable | Function |
|
||||
| --- | --- |
|
||||
| GOOGLE_OAUTH_CLIENT_ID | Client Id |
|
||||
| GOOGLE_OAUTH_CLIENT_SECRET | Secret |
|
||||
|
||||
### Resolve addresses with Google Maps
|
||||
|
||||
| Variable | Function |
|
||||
|
||||
@ -23,10 +23,6 @@ app.config["SECURITY_RECOVERABLE"] = True
|
||||
app.config["SECURITY_CHANGEABLE"] = True
|
||||
app.config["SECURITY_EMAIL_SENDER"] = os.getenv("MAIL_DEFAULT_SENDER")
|
||||
app.config["LANGUAGES"] = ["en", "de"]
|
||||
app.config["GOOGLE_OAUTH_CLIENT_ID"] = os.getenv("GOOGLE_OAUTH_CLIENT_ID")
|
||||
app.config["GOOGLE_OAUTH_CLIENT_SECRET"] = os.getenv("GOOGLE_OAUTH_CLIENT_SECRET")
|
||||
app.config["OAUTHLIB_INSECURE_TRANSPORT"] = True
|
||||
app.config["OAUTHLIB_RELAX_TOKEN_SCOPE"] = True
|
||||
|
||||
# Generate a nice key using secrets.token_urlsafe()
|
||||
app.config["SECRET_KEY"] = os.environ.get(
|
||||
@ -86,14 +82,10 @@ app.json_encoder = DateTimeEncoder
|
||||
|
||||
# Setup Flask-Security
|
||||
from project.models import User, Role
|
||||
from project.forms.security import ExtendedRegisterForm
|
||||
|
||||
user_datastore = SQLAlchemySessionUserDatastore(db.session, User, Role)
|
||||
security = Security(app, user_datastore)
|
||||
|
||||
# OAuth
|
||||
from project.oauth import blueprint
|
||||
|
||||
app.register_blueprint(blueprint, url_prefix="/login")
|
||||
security = Security(app, user_datastore, register_form=ExtendedRegisterForm)
|
||||
|
||||
from project import i10n
|
||||
from project import jinja_filters
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
from flask import url_for
|
||||
from flask_babelex import lazy_gettext
|
||||
from flask_wtf import FlaskForm
|
||||
from flask_wtf.file import FileField, FileAllowed
|
||||
from wtforms import StringField, BooleanField, HiddenField
|
||||
from wtforms.validators import Optional
|
||||
from markupsafe import Markup
|
||||
import re
|
||||
import base64
|
||||
|
||||
@ -62,6 +64,24 @@ class Base64ImageForm(BaseImageForm):
|
||||
obj.encoding_format = None
|
||||
|
||||
|
||||
def get_accept_tos_markup():
|
||||
tos_open = '<a href="%s">' % url_for("tos")
|
||||
tos_close = "</a>"
|
||||
|
||||
privacy_open = '<a href="%s">' % url_for("privacy")
|
||||
privacy_close = "</a>"
|
||||
|
||||
return Markup(
|
||||
lazy_gettext(
|
||||
"I read and accept %(tos_open)sTerms of Service%(tos_close)s and %(privacy_open)sPrivacy%(privacy_close)s.",
|
||||
tos_open=tos_open,
|
||||
tos_close=tos_close,
|
||||
privacy_open=privacy_open,
|
||||
privacy_close=privacy_close,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
event_rating_choices = [
|
||||
(0, lazy_gettext("0 (Little relevant)")),
|
||||
(10, "1"),
|
||||
|
||||
@ -14,7 +14,7 @@ from project.models import (
|
||||
EventRejectionReason,
|
||||
Image,
|
||||
)
|
||||
from project.forms.common import Base64ImageForm
|
||||
from project.forms.common import Base64ImageForm, get_accept_tos_markup
|
||||
from project.forms.widgets import CustomDateTimeField, TagSelectField
|
||||
|
||||
|
||||
@ -88,15 +88,14 @@ class CreateEventSuggestionForm(FlaskForm):
|
||||
"We recommend uploading a photo for the event. It looks a lot more, but of course it works without it."
|
||||
),
|
||||
)
|
||||
accept_tos = BooleanField(
|
||||
lazy_gettext(
|
||||
"I confirm that I have clarified all information (text, images, etc.) that I upload into the system with regard to their rights of use and declare that they may be passed on."
|
||||
),
|
||||
validators=[DataRequired()],
|
||||
)
|
||||
accept_tos = BooleanField(validators=[DataRequired()])
|
||||
|
||||
submit = SubmitField(lazy_gettext("Create event suggestion"))
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(CreateEventSuggestionForm, self).__init__(**kwargs)
|
||||
self._fields["accept_tos"].label.text = get_accept_tos_markup()
|
||||
|
||||
def populate_obj(self, obj):
|
||||
for name, field in self._fields.items():
|
||||
if name == "photo" and not obj.photo:
|
||||
|
||||
12
project/forms/security.py
Normal file
12
project/forms/security.py
Normal file
@ -0,0 +1,12 @@
|
||||
from flask_security.forms import RegisterForm
|
||||
from wtforms import BooleanField
|
||||
from wtforms.validators import DataRequired
|
||||
from project.forms.common import get_accept_tos_markup
|
||||
|
||||
|
||||
class ExtendedRegisterForm(RegisterForm):
|
||||
accept_tos = BooleanField(validators=[DataRequired()])
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ExtendedRegisterForm, self).__init__(*args, **kwargs)
|
||||
self._fields["accept_tos"].label.text = get_accept_tos_markup()
|
||||
@ -1,67 +0,0 @@
|
||||
from flask import flash
|
||||
from flask_security import current_user, login_user
|
||||
from flask_dance.contrib.google import make_google_blueprint
|
||||
from flask_dance.consumer import oauth_authorized, oauth_error
|
||||
from flask_dance.consumer.storage.sqla import SQLAlchemyStorage
|
||||
from project.models import OAuth
|
||||
from project import db, user_datastore
|
||||
from flask_babelex import gettext
|
||||
|
||||
blueprint = make_google_blueprint(
|
||||
scope=["profile", "email"],
|
||||
storage=SQLAlchemyStorage(OAuth, db.session, user=current_user),
|
||||
)
|
||||
|
||||
|
||||
# create/login local user on successful OAuth login
|
||||
@oauth_authorized.connect_via(blueprint)
|
||||
def google_logged_in(blueprint, token): # pragma: no cover
|
||||
if not token:
|
||||
flash("Failed to log in.", category="error")
|
||||
return False
|
||||
|
||||
resp = blueprint.session.get("/oauth2/v1/userinfo")
|
||||
if not resp.ok:
|
||||
msg = "Failed to fetch user info."
|
||||
flash(msg, category="error")
|
||||
return False
|
||||
|
||||
info = resp.json()
|
||||
user_id = info["id"]
|
||||
|
||||
# Find this OAuth token in the database, or create it
|
||||
oauth = OAuth.query.filter_by(
|
||||
provider=blueprint.name, provider_user_id=user_id
|
||||
).first()
|
||||
if oauth is None:
|
||||
oauth = OAuth(provider=blueprint.name, provider_user_id=user_id, token=token)
|
||||
|
||||
if oauth.user:
|
||||
login_user(oauth.user, authn_via=["google"])
|
||||
user_datastore.commit()
|
||||
flash(gettext("Successfully signed in."), "success")
|
||||
|
||||
else:
|
||||
# Create a new local user account for this user
|
||||
user = user_datastore.create_user(email=info["email"])
|
||||
# Associate the new local user account with the OAuth token
|
||||
oauth.user = user
|
||||
# Save and commit our database models
|
||||
db.session.add_all([user, oauth])
|
||||
db.session.commit()
|
||||
# Log in the new local user account
|
||||
login_user(user, authn_via=["google"])
|
||||
user_datastore.commit()
|
||||
flash(gettext("Successfully signed in."), "success")
|
||||
|
||||
# Disable Flask-Dance's default behavior for saving the OAuth token
|
||||
return False
|
||||
|
||||
|
||||
# notify on OAuth provider error
|
||||
@oauth_error.connect_via(blueprint)
|
||||
def google_error(blueprint, message, response): # pragma: no cover
|
||||
msg = "OAuth error from {name}! message={message} response={response}".format(
|
||||
name=blueprint.name, message=message, response=response
|
||||
)
|
||||
flash(msg, category="error")
|
||||
@ -438,10 +438,6 @@
|
||||
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_google_sign_in_button() %}
|
||||
<a href="{{ url_for('google.login') }}" class="btn btn-google" role="button"><i class="fab fa-google mr-2"></i> {{ _('Sign in with Google') }}</a>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_google_place_autocomplete_header(location_only = False) %}
|
||||
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key={{ "dev" | env_override('GOOGLE_MAPS_API_KEY') }}&libraries=places"></script>
|
||||
<script>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_google_sign_in_button, render_field_with_errors, render_field, render_field_errors %}
|
||||
{% from "_macros.html" import render_field_with_errors, render_field, render_field_errors %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
@ -24,9 +24,6 @@
|
||||
<div class="my-2">
|
||||
<a href="{{ url_for_security('register') }}" class="btn btn-dark"><i class="fa fa-user-plus mr-2"></i> {{ _('Register for free') }}</a>
|
||||
</div>
|
||||
<div class="my-2">
|
||||
{{ render_google_sign_in_button() }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_google_sign_in_button, render_field_with_errors, render_field %}
|
||||
{% from "_macros.html" import render_field_with_errors, render_field %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
@ -11,11 +11,13 @@
|
||||
{% if register_user_form.password_confirm %}
|
||||
{{ render_field_with_errors(register_user_form.password_confirm) }}
|
||||
{% endif %}
|
||||
|
||||
<div class="form-group form-check">
|
||||
{{ register_user_form.accept_tos(class="form-check-input")|safe }}
|
||||
{{ register_user_form.accept_tos.label(class="form-check-label") }}
|
||||
</div>
|
||||
|
||||
{{ render_field(register_user_form.submit) }}
|
||||
</form>
|
||||
|
||||
<hr class="my-4">
|
||||
|
||||
{{ render_google_sign_in_button() }}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
Binary file not shown.
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2020-12-12 13:52+0100\n"
|
||||
"POT-Creation-Date: 2020-12-20 15:15+0100\n"
|
||||
"PO-Revision-Date: 2020-06-07 18:51+0200\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language: de\n"
|
||||
@ -114,10 +114,6 @@ msgstr "Verifiziert"
|
||||
msgid "EventReviewStatus.rejected"
|
||||
msgstr "Abgelehnt"
|
||||
|
||||
#: project/oauth.py:42 project/oauth.py:55
|
||||
msgid "Successfully signed in."
|
||||
msgstr "Erfolgreich eingeloggt."
|
||||
|
||||
#: project/utils.py:5
|
||||
msgid "Event_"
|
||||
msgstr "Event_"
|
||||
@ -127,24 +123,24 @@ msgid "."
|
||||
msgstr "."
|
||||
|
||||
#: project/forms/admin.py:8 project/templates/layout.html:139
|
||||
#: project/views/root.py:24
|
||||
#: project/views/root.py:25
|
||||
msgid "Terms of service"
|
||||
msgstr "Nutzungsbedingungen"
|
||||
|
||||
#: project/forms/admin.py:9 project/templates/layout.html:143
|
||||
#: project/views/root.py:31
|
||||
#: project/views/root.py:33
|
||||
msgid "Legal notice"
|
||||
msgstr "Impressum"
|
||||
|
||||
#: project/forms/admin.py:10 project/templates/_macros.html:972
|
||||
#: project/forms/admin.py:10 project/templates/_macros.html:968
|
||||
#: project/templates/layout.html:147
|
||||
#: project/templates/widget/event_suggestion/create.html:171
|
||||
#: project/views/root.py:38
|
||||
#: project/views/root.py:41
|
||||
msgid "Contact"
|
||||
msgstr "Kontakt"
|
||||
|
||||
#: project/forms/admin.py:11 project/templates/layout.html:151
|
||||
#: project/views/root.py:45
|
||||
#: project/views/root.py:49
|
||||
msgid "Privacy"
|
||||
msgstr "Datenschutz"
|
||||
|
||||
@ -295,79 +291,89 @@ msgstr "Mitglied löschen"
|
||||
msgid "Update member"
|
||||
msgstr "Mitglied aktualisieren"
|
||||
|
||||
#: project/forms/common.py:12
|
||||
#: project/forms/common.py:14
|
||||
msgid "Copyright text"
|
||||
msgstr "Copyright Text"
|
||||
|
||||
#: project/forms/common.py:18
|
||||
#: project/forms/common.py:20
|
||||
msgid "File"
|
||||
msgstr "Datei"
|
||||
|
||||
#: project/forms/common.py:19
|
||||
#: project/forms/common.py:21
|
||||
msgid "Images only!"
|
||||
msgstr "Nur Bilder!"
|
||||
|
||||
#: project/forms/common.py:22
|
||||
#: project/forms/common.py:24
|
||||
msgid "Delete image"
|
||||
msgstr "Bild löschen"
|
||||
|
||||
#: project/forms/common.py:66
|
||||
#: project/forms/common.py:75
|
||||
#, python-format
|
||||
msgid ""
|
||||
"I read and accept %(tos_open)sTerms of Service%(tos_close)s and "
|
||||
"%(privacy_open)sPrivacy%(privacy_close)s."
|
||||
msgstr ""
|
||||
"Ich habe die %(tos_open)sNutzungsbedingungen%(tos_close)s und die "
|
||||
"%(privacy_open)sDatenschutzerklärung%(privacy_close)s gelesen und "
|
||||
"akzeptiere diese."
|
||||
|
||||
#: project/forms/common.py:83
|
||||
msgid "0 (Little relevant)"
|
||||
msgstr "0 (Wenig relevant)"
|
||||
|
||||
#: project/forms/common.py:76
|
||||
#: project/forms/common.py:93
|
||||
msgid "10 (Highlight)"
|
||||
msgstr "10 (Highlight)"
|
||||
|
||||
#: project/forms/common.py:80
|
||||
#: project/forms/common.py:97
|
||||
msgid "Monday"
|
||||
msgstr "Montag"
|
||||
|
||||
#: project/forms/common.py:81
|
||||
#: project/forms/common.py:98
|
||||
msgid "Tueday"
|
||||
msgstr "Dienstag"
|
||||
|
||||
#: project/forms/common.py:82
|
||||
#: project/forms/common.py:99
|
||||
msgid "Wednesday"
|
||||
msgstr "Mittwoch"
|
||||
|
||||
#: project/forms/common.py:83
|
||||
#: project/forms/common.py:100
|
||||
msgid "Thursday"
|
||||
msgstr "Donnerstag"
|
||||
|
||||
#: project/forms/common.py:84
|
||||
#: project/forms/common.py:101
|
||||
msgid "Friday"
|
||||
msgstr "Freitag"
|
||||
|
||||
#: project/forms/common.py:85
|
||||
#: project/forms/common.py:102
|
||||
msgid "Saturday"
|
||||
msgstr "Samstag"
|
||||
|
||||
#: project/forms/common.py:86
|
||||
#: project/forms/common.py:103
|
||||
msgid "Sunday"
|
||||
msgstr "Sonntag"
|
||||
|
||||
#: project/forms/common.py:90
|
||||
#: project/forms/common.py:107
|
||||
msgid "500 m"
|
||||
msgstr "500 m"
|
||||
|
||||
#: project/forms/common.py:91
|
||||
#: project/forms/common.py:108
|
||||
msgid "5 km"
|
||||
msgstr "5 km"
|
||||
|
||||
#: project/forms/common.py:92
|
||||
#: project/forms/common.py:109
|
||||
msgid "10 km"
|
||||
msgstr "10 km"
|
||||
|
||||
#: project/forms/common.py:93
|
||||
#: project/forms/common.py:110
|
||||
msgid "20 km"
|
||||
msgstr "20 km"
|
||||
|
||||
#: project/forms/common.py:94
|
||||
#: project/forms/common.py:111
|
||||
msgid "50 km"
|
||||
msgstr "50 km"
|
||||
|
||||
#: project/forms/common.py:95
|
||||
#: project/forms/common.py:112
|
||||
msgid "100 km"
|
||||
msgstr "100 km"
|
||||
|
||||
@ -564,7 +570,7 @@ msgstr "Neu angesetzt"
|
||||
msgid "Update event"
|
||||
msgstr "Veranstaltung aktualisieren"
|
||||
|
||||
#: project/forms/event.py:230 project/templates/_macros.html:918
|
||||
#: project/forms/event.py:230 project/templates/_macros.html:914
|
||||
#: project/templates/event/delete.html:6
|
||||
msgid "Delete event"
|
||||
msgstr "Veranstaltung löschen"
|
||||
@ -687,39 +693,29 @@ msgstr ""
|
||||
"Wir empfehlen dir, ein Foto für die Veranstaltung hochzuladen. Es macht "
|
||||
"schon deutlich mehr her, aber es geht natürlich auch ohne."
|
||||
|
||||
#: project/forms/event_suggestion.py:92
|
||||
msgid ""
|
||||
"I confirm that I have clarified all information (text, images, etc.) that"
|
||||
" I upload into the system with regard to their rights of use and declare "
|
||||
"that they may be passed on."
|
||||
msgstr ""
|
||||
"Ich bestätige dass ich alle Informationen (Text, Bild, etc.), die ich in "
|
||||
"das System hochlade, hinsichtlich ihrer Nutzungsrechte abgeklärt habe und"
|
||||
" erkläre, dass diese weitergegeben werden dürfen."
|
||||
|
||||
#: project/forms/event_suggestion.py:98 project/templates/example.html:10
|
||||
#: project/forms/event_suggestion.py:93 project/templates/example.html:10
|
||||
#: project/templates/widget/event_suggestion/create.html:4
|
||||
#: project/templates/widget/event_suggestion/create.html:124
|
||||
msgid "Create event suggestion"
|
||||
msgstr "Veranstaltung vorschlagen"
|
||||
|
||||
#: project/forms/event_suggestion.py:116 project/forms/reference_request.py:45
|
||||
#: project/forms/event_suggestion.py:115 project/forms/reference_request.py:45
|
||||
msgid "Rejection reason"
|
||||
msgstr "Ablehnungsgrund"
|
||||
|
||||
#: project/forms/event_suggestion.py:122
|
||||
#: project/forms/event_suggestion.py:121
|
||||
msgid "EventRejectionReason.duplicate"
|
||||
msgstr "Duplikat"
|
||||
|
||||
#: project/forms/event_suggestion.py:126
|
||||
#: project/forms/event_suggestion.py:125
|
||||
msgid "EventRejectionReason.untrustworthy"
|
||||
msgstr "Unseriös"
|
||||
|
||||
#: project/forms/event_suggestion.py:130
|
||||
#: project/forms/event_suggestion.py:129
|
||||
msgid "EventRejectionReason.illegal"
|
||||
msgstr "Unzulässig"
|
||||
|
||||
#: project/forms/event_suggestion.py:135
|
||||
#: project/forms/event_suggestion.py:134
|
||||
#: project/templates/event_suggestion/reject.html:9
|
||||
#: project/templates/event_suggestion/review.html:22
|
||||
msgid "Reject event suggestion"
|
||||
@ -769,7 +765,7 @@ msgstr "Anfrage speichern"
|
||||
msgid "Delete request"
|
||||
msgstr "Anfrage löschen"
|
||||
|
||||
#: project/forms/reference_request.py:26 project/templates/_macros.html:983
|
||||
#: project/forms/reference_request.py:26 project/templates/_macros.html:979
|
||||
#: project/templates/event_suggestion/review_status.html:18
|
||||
#: project/templates/reference_request/review_status.html:12
|
||||
msgid "Review status"
|
||||
@ -812,7 +808,7 @@ msgid "This field is required"
|
||||
msgstr "Dieses Feld ist erforderlich"
|
||||
|
||||
#: project/templates/_macros.html:116 project/templates/_macros.html:322
|
||||
#: project/templates/_macros.html:329 project/templates/_macros.html:614
|
||||
#: project/templates/_macros.html:329 project/templates/_macros.html:610
|
||||
msgid "Date"
|
||||
msgstr "Datum"
|
||||
|
||||
@ -849,15 +845,11 @@ msgstr "%(count)d Termine"
|
||||
msgid "Show directions"
|
||||
msgstr "Anreise planen"
|
||||
|
||||
#: project/templates/_macros.html:442
|
||||
msgid "Sign in with Google"
|
||||
msgstr "Mit Google anmelden"
|
||||
|
||||
#: project/templates/_macros.html:502
|
||||
#: project/templates/_macros.html:498
|
||||
msgid "Search location on Google"
|
||||
msgstr "Ort bei Google suchen"
|
||||
|
||||
#: project/templates/_macros.html:565 project/templates/_macros.html:567
|
||||
#: project/templates/_macros.html:561 project/templates/_macros.html:563
|
||||
#: project/templates/event_date/list.html:270
|
||||
#: project/templates/widget/event_suggestion/create.html:160
|
||||
#: project/templates/widget/event_suggestion/create.html:185
|
||||
@ -868,7 +860,7 @@ msgstr "Ort bei Google suchen"
|
||||
msgid "Previous"
|
||||
msgstr "Zurück"
|
||||
|
||||
#: project/templates/_macros.html:570 project/templates/_macros.html:572
|
||||
#: project/templates/_macros.html:566 project/templates/_macros.html:568
|
||||
#: project/templates/event_date/list.html:271
|
||||
#: project/templates/widget/event_suggestion/create.html:161
|
||||
#: project/templates/widget/event_suggestion/create.html:186
|
||||
@ -878,50 +870,50 @@ msgstr "Zurück"
|
||||
msgid "Next"
|
||||
msgstr "Weiter"
|
||||
|
||||
#: project/templates/_macros.html:637
|
||||
#: project/templates/_macros.html:633
|
||||
msgid "Radius"
|
||||
msgstr "Umkreis"
|
||||
|
||||
#: project/templates/_macros.html:832
|
||||
#: project/templates/_macros.html:828
|
||||
msgid "Edit image"
|
||||
msgstr "Bild bearbeiten"
|
||||
|
||||
#: project/templates/_macros.html:853
|
||||
#: project/templates/_macros.html:849
|
||||
msgid "Close"
|
||||
msgstr "Schließen"
|
||||
|
||||
#: project/templates/_macros.html:854
|
||||
#: project/templates/_macros.html:850
|
||||
msgid "Okay"
|
||||
msgstr "OK"
|
||||
|
||||
#: project/templates/_macros.html:863 project/templates/_macros.html:865
|
||||
#: project/templates/_macros.html:859 project/templates/_macros.html:861
|
||||
msgid "Choose image file"
|
||||
msgstr "Bild-Datei auswählen"
|
||||
|
||||
#: project/templates/_macros.html:913
|
||||
#: project/templates/_macros.html:909
|
||||
msgid "Actions"
|
||||
msgstr "Aktionen"
|
||||
|
||||
#: project/templates/_macros.html:917
|
||||
#: project/templates/_macros.html:913
|
||||
msgid "Edit event"
|
||||
msgstr "Veranstaltung bearbeiten"
|
||||
|
||||
#: project/templates/_macros.html:921
|
||||
#: project/templates/_macros.html:917
|
||||
msgid "Duplicate event"
|
||||
msgstr "Veranstaltung duplizieren"
|
||||
|
||||
#: project/templates/_macros.html:924
|
||||
#: project/templates/_macros.html:920
|
||||
#: project/templates/manage/references_incoming.html:10
|
||||
msgid "Reference event"
|
||||
msgstr "Veranstaltung empfehlen"
|
||||
|
||||
#: project/templates/_macros.html:927
|
||||
#: project/templates/_macros.html:923
|
||||
#: project/templates/manage/reference_requests_outgoing.html:10
|
||||
#: project/templates/manage/references_outgoing.html:10
|
||||
msgid "Empfehlung anfragen"
|
||||
msgstr "Empfehlung anfragen"
|
||||
|
||||
#: project/templates/_macros.html:950
|
||||
#: project/templates/_macros.html:946
|
||||
msgid "Event suggestion"
|
||||
msgstr "Veranstaltungsvorschlag"
|
||||
|
||||
@ -1555,3 +1547,24 @@ msgstr "Neue Veranstaltung zu prüfen"
|
||||
#~ msgid "Register"
|
||||
#~ msgstr ""
|
||||
|
||||
#~ msgid "Successfully signed in."
|
||||
#~ msgstr "Erfolgreich eingeloggt."
|
||||
|
||||
#~ msgid "Sign in with Google"
|
||||
#~ msgstr "Mit Google anmelden"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "I confirm that I have clarified "
|
||||
#~ "all information (text, images, etc.) "
|
||||
#~ "that I upload into the system with"
|
||||
#~ " regard to their rights of use "
|
||||
#~ "and declare that they may be "
|
||||
#~ "passed on."
|
||||
#~ msgstr ""
|
||||
#~ "Ich bestätige dass ich alle "
|
||||
#~ "Informationen (Text, Bild, etc.), die "
|
||||
#~ "ich in das System hochlade, hinsichtlich"
|
||||
#~ " ihrer Nutzungsrechte abgeklärt habe und"
|
||||
#~ " erkläre, dass diese weitergegeben werden"
|
||||
#~ " dürfen."
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ blinker==1.4
|
||||
certifi==2020.12.5
|
||||
cffi==1.14.4
|
||||
cfgv==3.2.0
|
||||
chardet==4.0.0
|
||||
chardet==3.0.4
|
||||
click==7.1.2
|
||||
colour==0.1.5
|
||||
coverage==5.3
|
||||
|
||||
@ -20,6 +20,7 @@ class UtilActions(object):
|
||||
"email": email,
|
||||
"password": password,
|
||||
"password_confirm": password,
|
||||
"accept_tos": "y",
|
||||
"csrf_token": self.get_csrf(response),
|
||||
"submit": "Register",
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user