Merge pull request #302 from DanielGrams/issue/301

Mitveranstalter #301
This commit is contained in:
Daniel Grams 2021-09-20 20:12:16 +02:00 committed by GitHub
commit ae466e7b73
27 changed files with 875 additions and 363 deletions

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2021-09-10 09:01+0200\n"
"POT-Creation-Date: 2021-09-19 16:31+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -191,7 +191,7 @@ msgstr ""
msgid "Legal notice"
msgstr ""
#: project/forms/admin.py:12 project/templates/_macros.html:1389
#: project/forms/admin.py:12 project/templates/_macros.html:1405
#: project/templates/layout.html:313
#: project/templates/widget/event_suggestion/create.html:204
#: project/views/admin_unit.py:36 project/views/root.py:58
@ -279,7 +279,7 @@ msgid "Longitude"
msgstr ""
#: project/forms/admin_unit.py:28 project/forms/event.py:36
#: project/forms/event.py:65 project/forms/event.py:379
#: project/forms/event.py:65 project/forms/event.py:399
#: project/forms/event_place.py:25 project/forms/event_place.py:50
#: project/forms/event_suggestion.py:26 project/forms/oauth2_client.py:66
#: project/forms/organizer.py:25 project/forms/organizer.py:52
@ -299,7 +299,7 @@ msgstr ""
msgid "The short name is used to create a unique identifier for your events"
msgstr ""
#: project/forms/admin_unit.py:40 project/templates/_macros.html:1525
#: project/forms/admin_unit.py:40 project/templates/_macros.html:1541
msgid "Short name must contain only letters numbers or underscore"
msgstr ""
@ -313,7 +313,7 @@ msgstr ""
#: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28
#: project/forms/event.py:58 project/forms/event_suggestion.py:38
#: project/forms/organizer.py:27 project/templates/_macros.html:262
#: project/templates/_macros.html:1485 project/templates/admin/users.html:19
#: project/templates/_macros.html:1501 project/templates/admin/users.html:19
msgid "Email"
msgstr ""
@ -492,8 +492,8 @@ msgstr ""
msgid "All-day"
msgstr ""
#: project/forms/event.py:86 project/templates/event/create.html:252
#: project/templates/event/update.html:143
#: project/forms/event.py:86 project/templates/event/create.html:274
#: project/templates/event/update.html:165
#: project/templates/widget/event_suggestion/create.html:240
msgid "Recurring event"
msgstr ""
@ -650,16 +650,16 @@ msgid ""
" course it works without it."
msgstr ""
#: project/forms/event.py:208 project/templates/_macros.html:1246
#: project/forms/event.py:208 project/templates/_macros.html:1262
msgid "The start must be before the end."
msgstr ""
#: project/forms/event.py:214 project/templates/_macros.html:1263
#: project/forms/event.py:214 project/templates/_macros.html:1279
msgid "An event can last a maximum of 14 days."
msgstr ""
#: project/forms/event.py:222 project/templates/_macros.html:419
#: project/templates/_macros.html:575
#: project/templates/_macros.html:582
msgid "Previous start date"
msgstr ""
@ -677,8 +677,8 @@ msgstr ""
#: project/forms/event.py:235 project/forms/reference.py:14
#: project/forms/reference.py:27 project/forms/reference_request.py:76
#: project/templates/event/create.html:366
#: project/templates/event/update.html:223
#: project/templates/event/create.html:390
#: project/templates/event/update.html:246
msgid "Rating"
msgstr ""
@ -689,152 +689,166 @@ msgid ""
"visible and is used for sorting."
msgstr ""
#: project/forms/event.py:247 project/forms/event.py:256
#: project/forms/event.py:325 project/forms/event_suggestion.py:50
#: project/templates/_macros.html:459 project/templates/_macros.html:612
#: project/templates/event/create.html:291
#: project/templates/event/update.html:173
#: project/forms/event.py:244
msgid "Co-organizers"
msgstr ""
#: project/forms/event.py:247
msgid ""
"Select optional co-organizers. You can add and modify organizers at "
"Organization > Organizers."
msgstr ""
#: project/forms/event.py:258
msgid "Invalid co-organizer."
msgstr ""
#: project/forms/event.py:267 project/forms/event.py:276
#: project/forms/event.py:345 project/forms/event_suggestion.py:50
#: project/templates/_macros.html:459 project/templates/_macros.html:619
#: project/templates/event/create.html:315
#: project/templates/event/update.html:196
#: project/templates/event_place/create.html:31
#: project/templates/event_place/delete.html:13
#: project/templates/event_place/update.html:31
msgid "Place"
msgstr ""
#: project/forms/event.py:249
#: project/forms/event.py:269
msgid "Select existing place"
msgstr ""
#: project/forms/event.py:250
#: project/forms/event.py:270
msgid "Enter new place"
msgstr ""
#: project/forms/event.py:263 project/forms/event.py:272
#: project/forms/event.py:333 project/forms/event.py:395
#: project/forms/event_suggestion.py:60 project/templates/_macros.html:497
#: project/templates/_macros.html:649 project/templates/event/create.html:262
#: project/templates/event/update.html:164
#: project/forms/event.py:283 project/forms/event.py:292
#: project/forms/event.py:353 project/forms/event.py:415
#: project/forms/event_suggestion.py:60 project/templates/_macros.html:496
#: project/templates/_macros.html:656 project/templates/event/create.html:284
#: project/templates/event/update.html:186
#: project/templates/organizer/create.html:27
#: project/templates/organizer/delete.html:13
#: project/templates/organizer/update.html:27
msgid "Organizer"
msgstr ""
#: project/forms/event.py:265
#: project/forms/event.py:285
msgid "Select existing organizer"
msgstr ""
#: project/forms/event.py:266
#: project/forms/event.py:286
msgid "Enter new organizer"
msgstr ""
#: project/forms/event.py:278
#: project/forms/event.py:298
msgid "Save as draft"
msgstr ""
#: project/forms/event.py:279
#: project/forms/event.py:299
msgid "Publish event"
msgstr ""
#: project/forms/event.py:309
#: project/forms/event.py:329
msgid "Select existing place or enter new place"
msgstr ""
#: project/forms/event.py:316
#: project/forms/event.py:336
msgid "Select existing organizer or enter new organizer"
msgstr ""
#: project/forms/event.py:328
#: project/forms/event.py:348
msgid ""
"Choose where the event takes place. You can add and modify places at "
"Manage > Places."
"Organization > Places."
msgstr ""
#: project/forms/event.py:336
#: project/forms/event.py:356
msgid ""
"Select the organizer. You can add and modify organizers at Manage > "
"Organizers."
"Select the organizer. You can add and modify organizers at Organization >"
" Organizers."
msgstr ""
#: project/forms/event.py:342 project/templates/event/update.html:153
#: project/forms/event.py:362 project/templates/event/update.html:175
#: project/templates/oauth2_token/list.html:21
msgid "Status"
msgstr ""
#: project/forms/event.py:345
#: project/forms/event.py:365
msgid "EventStatus.scheduled"
msgstr ""
#: project/forms/event.py:346 project/templates/layout.html:82
#: project/forms/event.py:366 project/templates/layout.html:82
#: project/templates/layout.html:97
msgid "EventStatus.cancelled"
msgstr ""
#: project/forms/event.py:347 project/templates/layout.html:85
#: project/forms/event.py:367 project/templates/layout.html:85
#: project/templates/layout.html:100
msgid "EventStatus.movedOnline"
msgstr ""
#: project/forms/event.py:348 project/templates/layout.html:88
#: project/forms/event.py:368 project/templates/layout.html:88
#: project/templates/layout.html:103
msgid "EventStatus.postponed"
msgstr ""
#: project/forms/event.py:349 project/templates/layout.html:91
#: project/forms/event.py:369 project/templates/layout.html:91
#: project/templates/layout.html:106
msgid "EventStatus.rescheduled"
msgstr ""
#: project/forms/event.py:351
#: project/forms/event.py:371
msgid "Select the status of the event."
msgstr ""
#: project/forms/event.py:355
#: project/forms/event.py:375
msgid "Public status"
msgstr ""
#: project/forms/event.py:358
#: project/forms/event.py:378
msgid "PublicStatus.published"
msgstr ""
#: project/forms/event.py:359 project/templates/_macros.html:282
#: project/forms/event.py:379 project/templates/_macros.html:282
msgid "PublicStatus.draft"
msgstr ""
#: project/forms/event.py:361
#: project/forms/event.py:381
msgid "Select the public status of the event."
msgstr ""
#: project/forms/event.py:364 project/templates/event/update.html:5
#: project/templates/event/update.html:119
#: project/forms/event.py:384 project/templates/event/update.html:5
#: project/templates/event/update.html:141
msgid "Update event"
msgstr ""
#: project/forms/event.py:378 project/templates/_macros.html:1218
#: project/forms/event.py:398 project/templates/_macros.html:1234
#: project/templates/event/actions.html:47
#: project/templates/event/delete.html:6
msgid "Delete event"
msgstr ""
#: project/forms/event.py:386 project/forms/event_date.py:15
#: project/forms/event.py:406 project/forms/event_date.py:15
#: project/forms/planing.py:14
msgid "From"
msgstr ""
#: project/forms/event.py:388 project/forms/event_date.py:17
#: project/forms/event.py:408 project/forms/event_date.py:17
#: project/forms/planing.py:16
msgid "to"
msgstr ""
#: project/forms/event.py:390 project/forms/event_date.py:19
#: project/forms/event.py:410 project/forms/event_date.py:19
msgid "Keyword"
msgstr ""
#: project/forms/event.py:392 project/forms/event_date.py:21
#: project/forms/event.py:412 project/forms/event_date.py:21
#: project/forms/planing.py:19 project/templates/_macros.html:392
msgid "Category"
msgstr ""
#: project/forms/event.py:398
#: project/forms/event.py:418
msgid "Find events"
msgstr ""
@ -895,13 +909,13 @@ msgstr ""
msgid "I would like to be notified by email after the review"
msgstr ""
#: project/forms/event_suggestion.py:52 project/templates/event/create.html:296
#: project/forms/event_suggestion.py:52 project/templates/event/create.html:320
msgid ""
"Choose where the event takes place. If the venue is not yet in the list, "
"just enter it."
msgstr ""
#: project/forms/event_suggestion.py:62 project/templates/event/create.html:266
#: project/forms/event_suggestion.py:62 project/templates/event/create.html:288
msgid ""
"Select the organizer. If the organizer is not yet on the list, just enter"
" it."
@ -983,7 +997,7 @@ msgid "Weekdays"
msgstr ""
#: project/forms/reference.py:11 project/forms/reference_request.py:16
#: project/templates/_macros.html:518 project/templates/_macros.html:675
#: project/templates/_macros.html:512 project/templates/_macros.html:672
#: project/templates/admin_unit/create.html:28
#: project/templates/admin_unit/update.html:29
#: project/templates/layout.html:258
@ -1011,7 +1025,7 @@ msgstr ""
msgid "Delete request"
msgstr ""
#: project/forms/reference_request.py:28 project/templates/_macros.html:1401
#: project/forms/reference_request.py:28 project/templates/_macros.html:1417
#: project/templates/event_suggestion/review_status.html:18
#: project/templates/reference_request/review_status.html:12
msgid "Review status"
@ -1078,7 +1092,7 @@ msgid "This field is required."
msgstr ""
#: project/templates/_macros.html:134 project/templates/_macros.html:414
#: project/templates/_macros.html:914
#: project/templates/_macros.html:930
msgid "Date"
msgstr ""
@ -1118,64 +1132,64 @@ msgstr ""
msgid "Last updated at %(updated_at)s."
msgstr ""
#: project/templates/_macros.html:408 project/templates/_macros.html:571
#: project/templates/_macros.html:408 project/templates/_macros.html:578
#: project/templates/event/actions.html:12
#: project/templates/event/create.html:235
#: project/templates/event/create.html:257
#: project/templates/event/delete.html:13
#: project/templates/event/update.html:126
#: project/templates/event/update.html:148
#: project/templates/widget/event_suggestion/create.html:229
msgid "Event"
msgstr ""
#: project/templates/_macros.html:441 project/templates/_macros.html:593
#: project/templates/_macros.html:1470 project/templates/event/actions.html:32
#: project/templates/_macros.html:441 project/templates/_macros.html:600
#: project/templates/_macros.html:1486 project/templates/event/actions.html:32
msgid "Share"
msgstr ""
#: project/templates/_macros.html:445 project/templates/_macros.html:597
#: project/templates/_macros.html:1500
#: project/templates/_macros.html:445 project/templates/_macros.html:604
#: project/templates/_macros.html:1516
msgid "Add to calendar"
msgstr ""
#: project/templates/_macros.html:453 project/templates/_macros.html:605
#: project/templates/_macros.html:453 project/templates/_macros.html:612
#: project/templates/event/report.html:4
msgid "Report event"
msgstr ""
#: project/templates/_macros.html:480 project/templates/_macros.html:631
#: project/templates/_macros.html:480 project/templates/_macros.html:638
msgid "Show directions"
msgstr ""
#: project/templates/_macros.html:485 project/templates/_macros.html:636
#: project/templates/_macros.html:485 project/templates/_macros.html:643
msgid "The event takes place online."
msgstr ""
#: project/templates/_macros.html:487 project/templates/_macros.html:638
#: project/templates/_macros.html:487 project/templates/_macros.html:645
msgid "The event takes place both offline and online."
msgstr ""
#: project/templates/_macros.html:699 project/templates/event_date/list.html:5
#: project/templates/_macros.html:696 project/templates/event_date/list.html:5
#: project/templates/event_date/list.html:300
#: project/templates/event_date/search.html:3
#: project/templates/reference_request/review.html:32
msgid "Event Dates"
msgstr ""
#: project/templates/_macros.html:772
#: project/templates/_macros.html:788
msgid "Search location on Google"
msgstr ""
#: project/templates/_macros.html:838
#: project/templates/_macros.html:854
#, python-format
msgid "%(count)d event dates"
msgstr ""
#: project/templates/_macros.html:854 project/templates/_macros.html:856
#: project/templates/_macros.html:870 project/templates/_macros.html:872
#: project/templates/event_date/list.html:321
msgid "First"
msgstr ""
#: project/templates/_macros.html:859 project/templates/_macros.html:861
#: project/templates/_macros.html:875 project/templates/_macros.html:877
#: project/templates/event_date/list.html:322
#: project/templates/widget/event_suggestion/create.html:193
#: project/templates/widget/event_suggestion/create.html:218
@ -1186,12 +1200,12 @@ msgstr ""
msgid "Previous"
msgstr ""
#: project/templates/_macros.html:863
#: project/templates/_macros.html:879
#, python-format
msgid "Page %(page)d of %(pages)d (%(total)d total)"
msgstr ""
#: project/templates/_macros.html:865 project/templates/_macros.html:867
#: project/templates/_macros.html:881 project/templates/_macros.html:883
#: project/templates/event_date/list.html:324
#: project/templates/widget/event_suggestion/create.html:194
#: project/templates/widget/event_suggestion/create.html:219
@ -1201,73 +1215,73 @@ msgstr ""
msgid "Next"
msgstr ""
#: project/templates/_macros.html:870 project/templates/_macros.html:872
#: project/templates/_macros.html:886 project/templates/_macros.html:888
#: project/templates/event_date/list.html:325
msgid "Last"
msgstr ""
#: project/templates/_macros.html:937
#: project/templates/_macros.html:953
msgid "Radius"
msgstr ""
#: project/templates/_macros.html:1147
#: project/templates/_macros.html:1163
msgid "Edit image"
msgstr ""
#: project/templates/_macros.html:1168
#: project/templates/_macros.html:1184
msgid "Close"
msgstr ""
#: project/templates/_macros.html:1169
#: project/templates/_macros.html:1185
msgid "Okay"
msgstr ""
#: project/templates/_macros.html:1181
#: project/templates/_macros.html:1197
msgid "Choose image file"
msgstr ""
#: project/templates/_macros.html:1217 project/templates/event/actions.html:46
#: project/templates/_macros.html:1233 project/templates/event/actions.html:46
msgid "Edit event"
msgstr ""
#: project/templates/_macros.html:1220 project/templates/manage/events.html:40
#: project/templates/_macros.html:1236 project/templates/manage/events.html:40
msgid "More"
msgstr ""
#: project/templates/_macros.html:1267
#: project/templates/_macros.html:1283
msgid "Please enter a valid time, between 00:00 and 23:59."
msgstr ""
#: project/templates/_macros.html:1295
#: project/templates/_macros.html:1311
#, python-format
msgid "Just use %(term)s"
msgstr ""
#: project/templates/_macros.html:1361
#: project/templates/_macros.html:1377
msgid "Event suggestion"
msgstr ""
#: project/templates/_macros.html:1479
#: project/templates/_macros.html:1495
msgid "Link copied"
msgstr ""
#: project/templates/_macros.html:1479
#: project/templates/_macros.html:1495
msgid "Copy link"
msgstr ""
#: project/templates/_macros.html:1508
#: project/templates/_macros.html:1524
msgid "Google calendar"
msgstr ""
#: project/templates/_macros.html:1509
#: project/templates/_macros.html:1525
msgid "Apple calendar"
msgstr ""
#: project/templates/_macros.html:1510
#: project/templates/_macros.html:1526
msgid "Yahoo calendar"
msgstr ""
#: project/templates/_macros.html:1511
#: project/templates/_macros.html:1527
msgid "Other calendar"
msgstr ""
@ -1327,7 +1341,7 @@ msgid "Show events"
msgstr ""
#: project/templates/event/create.html:5
#: project/templates/event/create.html:228 project/templates/layout.html:226
#: project/templates/event/create.html:250 project/templates/layout.html:226
#: project/templates/manage/events.html:22
#: project/templates/manage/organizers.html:21
msgid "Create event"
@ -1444,8 +1458,8 @@ msgstr ""
#: project/templates/admin_unit/create.html:58
#: project/templates/admin_unit/update.html:59
#: project/templates/event/create.html:354
#: project/templates/event/update.html:211
#: project/templates/event/create.html:378
#: project/templates/event/update.html:234
#: project/templates/event_place/create.html:57
#: project/templates/event_place/update.html:57
#: project/templates/organizer/create.html:56
@ -1570,31 +1584,33 @@ msgid "Enter place or address"
msgstr ""
#: project/templates/event/create.html:183
#: project/templates/event/create.html:240
#: project/templates/event/update.html:106
#: project/templates/event/update.html:132
#: project/templates/widget/event_suggestion/create.html:129
msgid "Enter organizer"
msgstr ""
#: project/templates/event/create.html:245
#: project/templates/event/update.html:136
#: project/templates/event/create.html:267
#: project/templates/event/update.html:158
msgid "Event date"
msgstr ""
#: project/templates/event/create.html:283
#: project/templates/event/create.html:305
msgid "Switch to organizer search"
msgstr ""
#: project/templates/event/create.html:316
#: project/templates/event/create.html:340
msgid "Switch to place search"
msgstr ""
#: project/templates/event/create.html:327
#: project/templates/event/update.html:184
#: project/templates/event/create.html:351
#: project/templates/event/update.html:207
msgid "Access"
msgstr ""
#: project/templates/event/create.html:341
#: project/templates/event/update.html:198
#: project/templates/event/create.html:365
#: project/templates/event/update.html:221
msgid "Target group"
msgstr ""
@ -1900,11 +1916,11 @@ msgstr ""
msgid "Event successfully deleted"
msgstr ""
#: project/views/event.py:397
#: project/views/event.py:404
msgid "Referenced event changed"
msgstr ""
#: project/views/event.py:420
#: project/views/event.py:427
msgid "New event report"
msgstr ""

View File

@ -0,0 +1,61 @@
"""empty message
Revision ID: 811e16ed3bf0
Revises: 12ca023b94f8
Create Date: 2021-09-18 16:21:08.415884
"""
import sqlalchemy as sa
import sqlalchemy_utils
from alembic import op
from project import dbtypes
# revision identifiers, used by Alembic.
revision = "811e16ed3bf0"
down_revision = "12ca023b94f8"
branch_labels = None
depends_on = None
def upgrade():
op.create_table(
"event_coorganizers",
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("event_id", sa.Integer(), nullable=False),
sa.Column("organizer_id", sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(
["event_id"],
["event.id"],
),
sa.ForeignKeyConstraint(
["organizer_id"],
["eventorganizer.id"],
),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("event_id", "organizer_id"),
)
op.create_unique_constraint(
"event_eventcategories_event_id_category_id",
"event_eventcategories",
["event_id", "category_id"],
)
op.create_unique_constraint(
"eventsuggestion_eventcategories_event_suggestion_id_category_id",
"eventsuggestion_eventcategories",
["event_suggestion_id", "category_id"],
)
def downgrade():
op.drop_constraint(
"eventsuggestion_eventcategories_event_suggestion_id_category_id",
"eventsuggestion_eventcategories",
type_="unique",
)
op.drop_constraint(
"event_eventcategories_event_id_category_id",
"event_eventcategories",
type_="unique",
)
op.drop_table("event_coorganizers")

View File

@ -16,7 +16,11 @@ from project.api.image.schemas import (
ImageSchema,
)
from project.api.organization.schemas import OrganizationRefSchema
from project.api.organizer.schemas import OrganizerRefSchema, OrganizerWriteIdSchema
from project.api.organizer.schemas import (
OrganizerDumpIdSchema,
OrganizerRefSchema,
OrganizerWriteIdSchema,
)
from project.api.place.schemas import (
PlaceRefSchema,
PlaceSearchItemSchema,
@ -167,6 +171,7 @@ class EventSchema(EventIdSchema, EventBaseSchemaMixin):
place = fields.Nested(PlaceRefSchema, attribute="event_place")
photo = fields.Nested(ImageSchema)
categories = fields.List(fields.Nested(EventCategoryRefSchema))
co_organizers = fields.List(fields.Nested(OrganizerRefSchema))
class EventDumpSchema(EventIdSchema, EventBaseSchemaMixin):
@ -177,6 +182,9 @@ class EventDumpSchema(EventIdSchema, EventBaseSchemaMixin):
category_ids = fields.Pluck(
EventCategoryIdSchema, "id", many=True, attribute="categories"
)
co_organizer_ids = fields.Pluck(
OrganizerDumpIdSchema, "id", many=True, attribute="co_organizers"
)
class EventRefSchema(EventIdSchema):
@ -262,6 +270,10 @@ class EventWriteSchemaMixin(object):
required=True,
metadata={"description": "Who is organizing the event."},
)
co_organizers = fields.List(
fields.Nested(OrganizerWriteIdSchema),
metadata={"description": "Optional co-organizers."},
)
place = fields.Nested(
PlaceWriteIdSchema,
required=True,

View File

@ -31,6 +31,10 @@ class OrganizerIdSchema(OrganizerModelSchema, IdSchemaMixin):
pass
class OrganizerDumpIdSchema(OrganizerModelSchema, IdSchemaMixin):
pass
class OrganizerWriteIdSchema(OrganizerModelSchema, WriteIdSchemaMixin):
pass

View File

@ -2,6 +2,7 @@ import json
import click
from flask.cli import AppGroup
from flask_migrate import stamp
from flask_security.confirmable import confirm_user
from sqlalchemy import MetaData
@ -97,6 +98,7 @@ def drop_all():
@test_cli.command("create-all")
def create_all():
stamp()
db.create_all()
click.echo("Create all done.")

View File

@ -240,6 +240,25 @@ class BaseEventForm(SharedEventForm):
"Choose how relevant the event is to your organization. The value is not visible and is used for sorting."
),
)
co_organizer_ids = SelectMultipleField(
lazy_gettext("Co-organizers"),
validators=[Optional()],
coerce=int,
description=lazy_gettext(
"Select optional co-organizers. You can add and modify organizers at Organization > Organizers."
),
)
def validate(self):
result = super().validate()
if self.co_organizer_ids.data and self.organizer_id.data:
if self.organizer_id.data in self.co_organizer_ids.data:
msg = gettext("Invalid co-organizer.")
self.co_organizer_ids.errors.append(msg)
result = False
return result
class CreateEventForm(BaseEventForm):
@ -301,7 +320,7 @@ class CreateEventForm(BaseEventForm):
)
def validate(self):
if not super(BaseEventForm, self).validate():
if not super().validate():
return False
if (
not self.event_place_id.data or self.event_place_id.data == 0
@ -326,7 +345,7 @@ class UpdateEventForm(BaseEventForm):
validators=[DataRequired()],
coerce=int,
description=lazy_gettext(
"Choose where the event takes place. You can add and modify places at Manage > Places."
"Choose where the event takes place. You can add and modify places at Organization > Places."
),
)
organizer_id = SelectField(
@ -334,7 +353,7 @@ class UpdateEventForm(BaseEventForm):
validators=[DataRequired()],
coerce=int,
description=lazy_gettext(
"Select the organizer. You can add and modify organizers at Manage > Organizers."
"Select the organizer. You can add and modify organizers at Organization > Organizers."
),
)

View File

@ -133,8 +133,13 @@ def get_sd_for_event_date(event_date):
result["location"] = get_sd_for_place(event.event_place)
organizer_list = list()
if event.organizer:
organizer_list.append(get_sd_for_organizer(event.organizer))
for co_organizer in event.co_organizers:
organizer_list.append(get_sd_for_organizer(co_organizer))
if event.admin_unit:
organizer_list.append(get_sd_for_admin_unit(event.admin_unit))
result["organizer"] = organizer_list

View File

@ -331,6 +331,12 @@ class AdminUnitRelation(db.Model, TrackableMixin):
raise make_check_violation("There must be no self-reference.")
@listens_for(AdminUnitRelation, "before_insert")
@listens_for(AdminUnitRelation, "before_update")
def before_saving_admin_unit_relation(mapper, connect, self):
self.validate()
class AdminUnit(db.Model, TrackableMixin):
__tablename__ = "adminunit"
id = Column(Integer(), primary_key=True)
@ -765,6 +771,11 @@ class Event(db.Model, TrackableMixin, EventMixin):
event_place = db.relationship("EventPlace", uselist=False)
categories = relationship("EventCategory", secondary="event_eventcategories")
co_organizers = relationship(
"EventOrganizer",
secondary="event_coorganizers",
backref=backref("co_organized_events", lazy=True),
)
public_status = Column(
IntegerEnum(PublicStatus),
@ -798,12 +809,30 @@ class Event(db.Model, TrackableMixin, EventMixin):
else:
return None
@property
def co_organizer_ids(self):
return [c.id for c in self.co_organizers]
@co_organizer_ids.setter
def co_organizer_ids(self, value):
self.co_organizers = EventOrganizer.query.filter(
EventOrganizer.id.in_(value)
).all()
def validate(self):
if self.organizer and self.organizer.admin_unit_id != self.admin_unit_id:
raise make_check_violation("Invalid organizer")
raise make_check_violation("Invalid organizer.")
if self.co_organizers:
for co_organizer in self.co_organizers:
if (
co_organizer.admin_unit_id != self.admin_unit_id
or co_organizer.id == self.organizer_id
):
raise make_check_violation("Invalid co-organizer.")
if self.event_place and self.event_place.admin_unit_id != self.admin_unit_id:
raise make_check_violation("Invalid place")
raise make_check_violation("Invalid place.")
if self.start and self.end:
if self.start > self.end:
@ -816,7 +845,8 @@ class Event(db.Model, TrackableMixin, EventMixin):
@listens_for(Event, "before_insert")
@listens_for(Event, "before_update")
def purge_event(mapper, connect, self):
def before_saving_event(mapper, connect, self):
self.validate()
self.purge_event_mixin()
@ -842,6 +872,7 @@ def purge_event_date(mapper, connect, self):
class EventEventCategories(db.Model):
__tablename__ = "event_eventcategories"
__table_args__ = (UniqueConstraint("event_id", "category_id"),)
id = Column(Integer(), primary_key=True)
event_id = db.Column(db.Integer, db.ForeignKey("event.id"), nullable=False)
category_id = db.Column(
@ -851,6 +882,7 @@ class EventEventCategories(db.Model):
class EventSuggestionEventCategories(db.Model):
__tablename__ = "eventsuggestion_eventcategories"
__table_args__ = (UniqueConstraint("event_suggestion_id", "category_id"),)
id = Column(Integer(), primary_key=True)
event_suggestion_id = db.Column(
db.Integer, db.ForeignKey("eventsuggestion.id"), nullable=False
@ -860,6 +892,16 @@ class EventSuggestionEventCategories(db.Model):
)
class EventCoOrganizers(db.Model):
__tablename__ = "event_coorganizers"
__table_args__ = (UniqueConstraint("event_id", "organizer_id"),)
id = Column(Integer(), primary_key=True)
event_id = db.Column(db.Integer, db.ForeignKey("event.id"), nullable=False)
organizer_id = db.Column(
db.Integer, db.ForeignKey("eventorganizer.id"), nullable=False
)
class Analytics(db.Model):
__tablename__ = "analytics"
id = Column(Integer(), primary_key=True)

View File

@ -491,25 +491,19 @@
</div>
{% if event.organizer %}
<div class="card mb-3">
<div class="card-header">
{{ _('Organizer') }}
</div>
<div class="card-body">
<h5 class="card-title">{{ render_string_prop(event.organizer.name) }}</h5>
{% if event.organizer.logo_id %}
<div class="my-4">{{ render_logo(event.organizer.logo) }}</div>
{% endif %}
{{ render_link_prop(event.organizer.url) }}
{{ render_email_prop(event.organizer.email) }}
{{ render_phone_prop(event.organizer.phone) }}
{{ render_fax_prop(event.organizer.fax) }}
{{ render_event_props_organizer(event.organizer) }}
{% for co_organizer in event.co_organizers %}
<div{% if loop.index > 0 %} class="mt-4"{% endif %}>
{{ render_event_props_organizer(co_organizer) }}
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% if show_admin_unit %}
@ -539,6 +533,19 @@
{% endmacro %}
{% macro render_event_props_organizer(organizer) %}
<h5 class="card-title">{{ render_string_prop(organizer.name) }}</h5>
{% if organizer.logo_id %}
<div class="my-4">{{ render_logo(organizer.logo) }}</div>
{% endif %}
{{ render_link_prop(organizer.url) }}
{{ render_email_prop(organizer.email) }}
{{ render_phone_prop(organizer.phone) }}
{{ render_fax_prop(organizer.fax) }}
{% endmacro %}
{% macro render_event_props_seo(event, start, end, allday, dates = None, show_rating = False, show_admin_unit = True, user_rights=None, share_links=None, calendar_links=None) %}
<div class="w-normal mx-auto">
@ -648,22 +655,12 @@
<div class="card-body">
<h2 class="mt-0">{{ _('Organizer') }}</h2>
<div class="row">
{% if event.organizer.logo_id %}
<div class="col-12 col-sm-auto order-sm-last">{{ render_logo(event.organizer.logo) }}</div>
{% endif %}
<div class="col-12 col-sm">
<div class="font-weight-bold">
{{ render_string_prop(event.organizer.name) }}
</div>
{{ render_link_prop(event.organizer.url) }}
{{ render_email_prop(event.organizer.email) }}
{{ render_phone_prop(event.organizer.phone) }}
{{ render_fax_prop(event.organizer.fax) }}
{{ render_event_props_seo_organizer(event.organizer) }}
{% for co_organizer in event.co_organizers %}
<div{% if loop.index > 0 %} class="mt-4"{% endif %}>
{{ render_event_props_seo_organizer(co_organizer) }}
</div>
</div>
{% endfor %}
</div>
</div>
@ -710,6 +707,25 @@
{% endmacro %}
{% macro render_event_props_seo_organizer(organizer) %}
<div class="row">
{% if organizer.logo_id %}
<div class="col-12 col-sm-auto order-sm-last">{{ render_logo(organizer.logo) }}</div>
{% endif %}
<div class="col-12 col-sm">
<div class="font-weight-bold">
{{ render_string_prop(organizer.name) }}
</div>
{{ render_link_prop(organizer.url) }}
{{ render_email_prop(organizer.email) }}
{{ render_phone_prop(organizer.phone) }}
{{ render_fax_prop(organizer.fax) }}
</div>
</div>
{% endmacro %}
{% macro render_google_place_autocomplete_header() %}
<script>
$( function() {

View File

@ -218,6 +218,28 @@ $( function() {
update_organizer_container($('input[type=radio][name=organizer_choice]:checked').val());
$('#co_organizer_ids').select2({
width: '100%',
ajax: {
url: "{{ url_for('api_v1_organization_organizer_list', id=admin_unit.id) }}",
dataType: 'json',
delay: 250,
cache: true,
data: function (params) {
return {
name: params.term,
per_page: 5
};
},
processResults: function (data) {
return {
results: data.items.map(p => ({"id": p.id, "text": p.name}))
};
}
},
placeholder: "{{ _('Enter organizer') }}"
});
{{ render_end_container_handling() }}
});
@ -283,6 +305,8 @@ $( function() {
<a href="#" id="new_organizer_container_search_link"><i class="fa fa-search"></i> {{ _('Switch to organizer search') }}</a>
</div>
</div>
{{ render_field_with_errors(form.co_organizer_ids, class="w-100") }}
</div>
</div>

View File

@ -110,6 +110,28 @@
$(this).valid();
});
$('#co_organizer_ids').select2({
width: '100%',
ajax: {
url: "{{ url_for('api_v1_organization_organizer_list', id=event.admin_unit.id) }}",
dataType: 'json',
delay: 250,
cache: true,
data: function (params) {
return {
name: params.term,
per_page: 5
};
},
processResults: function (data) {
return {
results: data.items.map(p => ({"id": p.id, "text": p.name}))
};
}
},
placeholder: "{{ _('Enter organizer') }}"
});
{{ render_end_container_handling() }}
});
</script>
@ -165,6 +187,7 @@
</div>
<div class="card-body pb-0">
{{ render_field_with_errors(form.organizer_id, class="w-100", label_hidden=True) }}
{{ render_field_with_errors(form.co_organizer_ids, class="w-100") }}
</div>
</div>

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2021-09-10 09:01+0200\n"
"POT-Creation-Date: 2021-09-19 16:31+0200\n"
"PO-Revision-Date: 2020-06-07 18:51+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: de\n"
@ -192,7 +192,7 @@ msgstr "Nutzungsbedingungen"
msgid "Legal notice"
msgstr "Impressum"
#: project/forms/admin.py:12 project/templates/_macros.html:1389
#: project/forms/admin.py:12 project/templates/_macros.html:1405
#: project/templates/layout.html:313
#: project/templates/widget/event_suggestion/create.html:204
#: project/views/admin_unit.py:36 project/views/root.py:58
@ -284,7 +284,7 @@ msgid "Longitude"
msgstr "Längengrad"
#: project/forms/admin_unit.py:28 project/forms/event.py:36
#: project/forms/event.py:65 project/forms/event.py:379
#: project/forms/event.py:65 project/forms/event.py:399
#: project/forms/event_place.py:25 project/forms/event_place.py:50
#: project/forms/event_suggestion.py:26 project/forms/oauth2_client.py:66
#: project/forms/organizer.py:25 project/forms/organizer.py:52
@ -307,7 +307,7 @@ msgstr ""
"eindeutig zu identifizieren. Der Kurzname darf nur Buchstaben, Nummern "
"und Unterstriche enthalten."
#: project/forms/admin_unit.py:40 project/templates/_macros.html:1525
#: project/forms/admin_unit.py:40 project/templates/_macros.html:1541
msgid "Short name must contain only letters numbers or underscore"
msgstr "Der Kurzname darf nur Buchstaben, Nummern und Unterstriche enthalten"
@ -321,7 +321,7 @@ msgstr "Link URL"
#: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28
#: project/forms/event.py:58 project/forms/event_suggestion.py:38
#: project/forms/organizer.py:27 project/templates/_macros.html:262
#: project/templates/_macros.html:1485 project/templates/admin/users.html:19
#: project/templates/_macros.html:1501 project/templates/admin/users.html:19
msgid "Email"
msgstr "Email"
@ -505,8 +505,8 @@ msgstr ""
msgid "All-day"
msgstr "Ganztägig"
#: project/forms/event.py:86 project/templates/event/create.html:252
#: project/templates/event/update.html:143
#: project/forms/event.py:86 project/templates/event/create.html:274
#: project/templates/event/update.html:165
#: project/templates/widget/event_suggestion/create.html:240
msgid "Recurring event"
msgstr "Regelmäßige Veranstaltung"
@ -674,16 +674,16 @@ 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.py:208 project/templates/_macros.html:1246
#: project/forms/event.py:208 project/templates/_macros.html:1262
msgid "The start must be before the end."
msgstr "Der Start muss vor dem Ende sein."
#: project/forms/event.py:214 project/templates/_macros.html:1263
#: project/forms/event.py:214 project/templates/_macros.html:1279
msgid "An event can last a maximum of 14 days."
msgstr "Eine Veranstaltung darf maximal 14 Tage dauern."
#: project/forms/event.py:222 project/templates/_macros.html:419
#: project/templates/_macros.html:575
#: project/templates/_macros.html:582
msgid "Previous start date"
msgstr "Vorheriges Startdatum"
@ -703,8 +703,8 @@ msgstr "Wähle Kategorien, die zur Veranstaltung passen."
#: project/forms/event.py:235 project/forms/reference.py:14
#: project/forms/reference.py:27 project/forms/reference_request.py:76
#: project/templates/event/create.html:366
#: project/templates/event/update.html:223
#: project/templates/event/create.html:390
#: project/templates/event/update.html:246
msgid "Rating"
msgstr "Bewertung"
@ -717,156 +717,172 @@ msgstr ""
"Wähle aus, wie relevant die Veranstaltung für deine Organisation ist. Der"
" Wert ist nicht sichtbar und dient der Sortierung."
#: project/forms/event.py:247 project/forms/event.py:256
#: project/forms/event.py:325 project/forms/event_suggestion.py:50
#: project/templates/_macros.html:459 project/templates/_macros.html:612
#: project/templates/event/create.html:291
#: project/templates/event/update.html:173
#: project/forms/event.py:244
msgid "Co-organizers"
msgstr "Mitveranstalter"
#: project/forms/event.py:247
msgid ""
"Select optional co-organizers. You can add and modify organizers at "
"Organization > Organizers."
msgstr ""
"Wähle optionale Mitveranstalter. Du kannst Veranstalter unter "
"Organisation > Veranstalter hinzufügen und ändern."
#: project/forms/event.py:258
msgid "Invalid co-organizer."
msgstr "Ungültiger Mitveranstalter."
#: project/forms/event.py:267 project/forms/event.py:276
#: project/forms/event.py:345 project/forms/event_suggestion.py:50
#: project/templates/_macros.html:459 project/templates/_macros.html:619
#: project/templates/event/create.html:315
#: project/templates/event/update.html:196
#: project/templates/event_place/create.html:31
#: project/templates/event_place/delete.html:13
#: project/templates/event_place/update.html:31
msgid "Place"
msgstr "Ort"
#: project/forms/event.py:249
#: project/forms/event.py:269
msgid "Select existing place"
msgstr "Vorhandenen Ort auswählen"
#: project/forms/event.py:250
#: project/forms/event.py:270
msgid "Enter new place"
msgstr "Neuen Ort eingeben"
#: project/forms/event.py:263 project/forms/event.py:272
#: project/forms/event.py:333 project/forms/event.py:395
#: project/forms/event_suggestion.py:60 project/templates/_macros.html:497
#: project/templates/_macros.html:649 project/templates/event/create.html:262
#: project/templates/event/update.html:164
#: project/forms/event.py:283 project/forms/event.py:292
#: project/forms/event.py:353 project/forms/event.py:415
#: project/forms/event_suggestion.py:60 project/templates/_macros.html:496
#: project/templates/_macros.html:656 project/templates/event/create.html:284
#: project/templates/event/update.html:186
#: project/templates/organizer/create.html:27
#: project/templates/organizer/delete.html:13
#: project/templates/organizer/update.html:27
msgid "Organizer"
msgstr "Veranstalter"
#: project/forms/event.py:265
#: project/forms/event.py:285
msgid "Select existing organizer"
msgstr "Vorhandenen Veranstalter auswählen"
#: project/forms/event.py:266
#: project/forms/event.py:286
msgid "Enter new organizer"
msgstr "Neuen Veranstalter eingeben"
#: project/forms/event.py:278
#: project/forms/event.py:298
msgid "Save as draft"
msgstr "Als Entwurf speichern"
#: project/forms/event.py:279
#: project/forms/event.py:299
msgid "Publish event"
msgstr "Veranstaltung veröffentlichen"
#: project/forms/event.py:309
#: project/forms/event.py:329
msgid "Select existing place or enter new place"
msgstr "Existierenden Ort wählen oder neuen Ort eingeben"
#: project/forms/event.py:316
#: project/forms/event.py:336
msgid "Select existing organizer or enter new organizer"
msgstr "Wähle einen vorhandenen Veranstalter oder gib einen neuen Veranstalter ein"
#: project/forms/event.py:328
#: project/forms/event.py:348
msgid ""
"Choose where the event takes place. You can add and modify places at "
"Manage > Places."
"Organization > Places."
msgstr ""
"Wähle, wo die Veranstaltung stattfindet. Du kannst Orte unter Verwaltung "
"> Orte hinzufügen und ändern."
"Wähle, wo die Veranstaltung stattfindet. Du kannst Orte unter "
"Organisation > Orte hinzufügen und ändern."
#: project/forms/event.py:336
#: project/forms/event.py:356
msgid ""
"Select the organizer. You can add and modify organizers at Manage > "
"Organizers."
"Select the organizer. You can add and modify organizers at Organization >"
" Organizers."
msgstr ""
"Wähle den Veranstalter. Du kannst Veranstalter unter Verwaltung > "
"Wähle den Veranstalter. Du kannst Veranstalter unter Organisation > "
"Veranstalter hinzufügen und ändern."
#: project/forms/event.py:342 project/templates/event/update.html:153
#: project/forms/event.py:362 project/templates/event/update.html:175
#: project/templates/oauth2_token/list.html:21
msgid "Status"
msgstr "Status"
#: project/forms/event.py:345
#: project/forms/event.py:365
msgid "EventStatus.scheduled"
msgstr "Geplant"
#: project/forms/event.py:346 project/templates/layout.html:82
#: project/forms/event.py:366 project/templates/layout.html:82
#: project/templates/layout.html:97
msgid "EventStatus.cancelled"
msgstr "Abgesagt"
#: project/forms/event.py:347 project/templates/layout.html:85
#: project/forms/event.py:367 project/templates/layout.html:85
#: project/templates/layout.html:100
msgid "EventStatus.movedOnline"
msgstr "Online verschoben"
#: project/forms/event.py:348 project/templates/layout.html:88
#: project/forms/event.py:368 project/templates/layout.html:88
#: project/templates/layout.html:103
msgid "EventStatus.postponed"
msgstr "Verschoben"
#: project/forms/event.py:349 project/templates/layout.html:91
#: project/forms/event.py:369 project/templates/layout.html:91
#: project/templates/layout.html:106
msgid "EventStatus.rescheduled"
msgstr "Neu angesetzt"
#: project/forms/event.py:351
#: project/forms/event.py:371
msgid "Select the status of the event."
msgstr "Wähle den Status der Veranstaltung."
#: project/forms/event.py:355
#: project/forms/event.py:375
msgid "Public status"
msgstr "Öffentlicher Status"
#: project/forms/event.py:358
#: project/forms/event.py:378
msgid "PublicStatus.published"
msgstr "Veröffentlicht"
#: project/forms/event.py:359 project/templates/_macros.html:282
#: project/forms/event.py:379 project/templates/_macros.html:282
msgid "PublicStatus.draft"
msgstr "Entwurf"
#: project/forms/event.py:361
#: project/forms/event.py:381
msgid "Select the public status of the event."
msgstr "Wähle den öffentlichen Status der Veranstaltung."
#: project/forms/event.py:364 project/templates/event/update.html:5
#: project/templates/event/update.html:119
#: project/forms/event.py:384 project/templates/event/update.html:5
#: project/templates/event/update.html:141
msgid "Update event"
msgstr "Veranstaltung aktualisieren"
#: project/forms/event.py:378 project/templates/_macros.html:1218
#: project/forms/event.py:398 project/templates/_macros.html:1234
#: project/templates/event/actions.html:47
#: project/templates/event/delete.html:6
msgid "Delete event"
msgstr "Veranstaltung löschen"
#: project/forms/event.py:386 project/forms/event_date.py:15
#: project/forms/event.py:406 project/forms/event_date.py:15
#: project/forms/planing.py:14
msgid "From"
msgstr "Von"
#: project/forms/event.py:388 project/forms/event_date.py:17
#: project/forms/event.py:408 project/forms/event_date.py:17
#: project/forms/planing.py:16
msgid "to"
msgstr "bis"
#: project/forms/event.py:390 project/forms/event_date.py:19
#: project/forms/event.py:410 project/forms/event_date.py:19
msgid "Keyword"
msgstr "Stichwort"
#: project/forms/event.py:392 project/forms/event_date.py:21
#: project/forms/event.py:412 project/forms/event_date.py:21
#: project/forms/planing.py:19 project/templates/_macros.html:392
msgid "Category"
msgstr "Kategorie"
#: project/forms/event.py:398
#: project/forms/event.py:418
msgid "Find events"
msgstr "Veranstaltungen finden"
@ -927,7 +943,7 @@ msgstr "Bitte gib deine Email-Adresse oder deine Telefonnummer für die Prüfung
msgid "I would like to be notified by email after the review"
msgstr "Ich möchte per Email benachrichtigt werden nach der Prüfung"
#: project/forms/event_suggestion.py:52 project/templates/event/create.html:296
#: project/forms/event_suggestion.py:52 project/templates/event/create.html:320
msgid ""
"Choose where the event takes place. If the venue is not yet in the list, "
"just enter it."
@ -935,7 +951,7 @@ msgstr ""
"Wähle aus, wo die Veranstaltung stattfindet. Ist der Veranstaltungsort "
"noch nicht in der Liste, trage ihn einfach ein."
#: project/forms/event_suggestion.py:62 project/templates/event/create.html:266
#: project/forms/event_suggestion.py:62 project/templates/event/create.html:288
msgid ""
"Select the organizer. If the organizer is not yet on the list, just enter"
" it."
@ -1019,7 +1035,7 @@ msgid "Weekdays"
msgstr "Wochentage"
#: project/forms/reference.py:11 project/forms/reference_request.py:16
#: project/templates/_macros.html:518 project/templates/_macros.html:675
#: project/templates/_macros.html:512 project/templates/_macros.html:672
#: project/templates/admin_unit/create.html:28
#: project/templates/admin_unit/update.html:29
#: project/templates/layout.html:258
@ -1047,7 +1063,7 @@ msgstr "Anfrage speichern"
msgid "Delete request"
msgstr "Anfrage löschen"
#: project/forms/reference_request.py:28 project/templates/_macros.html:1401
#: project/forms/reference_request.py:28 project/templates/_macros.html:1417
#: project/templates/event_suggestion/review_status.html:18
#: project/templates/reference_request/review_status.html:12
msgid "Review status"
@ -1114,7 +1130,7 @@ msgid "This field is required."
msgstr "Dieses Feld ist erforderlich."
#: project/templates/_macros.html:134 project/templates/_macros.html:414
#: project/templates/_macros.html:914
#: project/templates/_macros.html:930
msgid "Date"
msgstr "Datum"
@ -1154,66 +1170,66 @@ msgstr "Zuletzt aktualisiert am %(updated_at)s von %(updated_by)s."
msgid "Last updated at %(updated_at)s."
msgstr "Zuletzt aktualisiert am %(updated_at)s."
#: project/templates/_macros.html:408 project/templates/_macros.html:571
#: project/templates/_macros.html:408 project/templates/_macros.html:578
#: project/templates/event/actions.html:12
#: project/templates/event/create.html:235
#: project/templates/event/create.html:257
#: project/templates/event/delete.html:13
#: project/templates/event/update.html:126
#: project/templates/event/update.html:148
#: project/templates/widget/event_suggestion/create.html:229
msgid "Event"
msgstr "Veranstaltung"
#: project/templates/_macros.html:441 project/templates/_macros.html:593
#: project/templates/_macros.html:1470 project/templates/event/actions.html:32
#: project/templates/_macros.html:441 project/templates/_macros.html:600
#: project/templates/_macros.html:1486 project/templates/event/actions.html:32
msgid "Share"
msgstr "Teilen"
#: project/templates/_macros.html:445 project/templates/_macros.html:597
#: project/templates/_macros.html:1500
#: project/templates/_macros.html:445 project/templates/_macros.html:604
#: project/templates/_macros.html:1516
msgid "Add to calendar"
msgstr "Zum Kalender"
#: project/templates/_macros.html:453 project/templates/_macros.html:605
#: project/templates/_macros.html:453 project/templates/_macros.html:612
#: project/templates/event/report.html:4
msgid "Report event"
msgstr "Veranstaltung melden"
#: project/templates/_macros.html:480 project/templates/_macros.html:631
#: project/templates/_macros.html:480 project/templates/_macros.html:638
msgid "Show directions"
msgstr "Anreise planen"
#: project/templates/_macros.html:485 project/templates/_macros.html:636
#: project/templates/_macros.html:485 project/templates/_macros.html:643
msgid "The event takes place online."
msgstr "Die Veranstaltung findet online statt."
#: project/templates/_macros.html:487 project/templates/_macros.html:638
#: project/templates/_macros.html:487 project/templates/_macros.html:645
msgid "The event takes place both offline and online."
msgstr ""
"Die Veranstaltung findet sowohl als Präsenzveranstaltung als auch online "
"statt."
#: project/templates/_macros.html:699 project/templates/event_date/list.html:5
#: project/templates/_macros.html:696 project/templates/event_date/list.html:5
#: project/templates/event_date/list.html:300
#: project/templates/event_date/search.html:3
#: project/templates/reference_request/review.html:32
msgid "Event Dates"
msgstr "Termine"
#: project/templates/_macros.html:772
#: project/templates/_macros.html:788
msgid "Search location on Google"
msgstr "Ort bei Google suchen"
#: project/templates/_macros.html:838
#: project/templates/_macros.html:854
#, python-format
msgid "%(count)d event dates"
msgstr "%(count)d Termine"
#: project/templates/_macros.html:854 project/templates/_macros.html:856
#: project/templates/_macros.html:870 project/templates/_macros.html:872
#: project/templates/event_date/list.html:321
msgid "First"
msgstr "Letzte"
#: project/templates/_macros.html:859 project/templates/_macros.html:861
#: project/templates/_macros.html:875 project/templates/_macros.html:877
#: project/templates/event_date/list.html:322
#: project/templates/widget/event_suggestion/create.html:193
#: project/templates/widget/event_suggestion/create.html:218
@ -1224,12 +1240,12 @@ msgstr "Letzte"
msgid "Previous"
msgstr "Zurück"
#: project/templates/_macros.html:863
#: project/templates/_macros.html:879
#, python-format
msgid "Page %(page)d of %(pages)d (%(total)d total)"
msgstr "Seite %(page)d von %(pages)d (%(total)d insgesamt)"
#: project/templates/_macros.html:865 project/templates/_macros.html:867
#: project/templates/_macros.html:881 project/templates/_macros.html:883
#: project/templates/event_date/list.html:324
#: project/templates/widget/event_suggestion/create.html:194
#: project/templates/widget/event_suggestion/create.html:219
@ -1239,73 +1255,73 @@ msgstr "Seite %(page)d von %(pages)d (%(total)d insgesamt)"
msgid "Next"
msgstr "Weiter"
#: project/templates/_macros.html:870 project/templates/_macros.html:872
#: project/templates/_macros.html:886 project/templates/_macros.html:888
#: project/templates/event_date/list.html:325
msgid "Last"
msgstr "Erste"
#: project/templates/_macros.html:937
#: project/templates/_macros.html:953
msgid "Radius"
msgstr "Umkreis"
#: project/templates/_macros.html:1147
#: project/templates/_macros.html:1163
msgid "Edit image"
msgstr "Bild bearbeiten"
#: project/templates/_macros.html:1168
#: project/templates/_macros.html:1184
msgid "Close"
msgstr "Schließen"
#: project/templates/_macros.html:1169
#: project/templates/_macros.html:1185
msgid "Okay"
msgstr "OK"
#: project/templates/_macros.html:1181
#: project/templates/_macros.html:1197
msgid "Choose image file"
msgstr "Bild-Datei auswählen"
#: project/templates/_macros.html:1217 project/templates/event/actions.html:46
#: project/templates/_macros.html:1233 project/templates/event/actions.html:46
msgid "Edit event"
msgstr "Veranstaltung bearbeiten"
#: project/templates/_macros.html:1220 project/templates/manage/events.html:40
#: project/templates/_macros.html:1236 project/templates/manage/events.html:40
msgid "More"
msgstr "Mehr"
#: project/templates/_macros.html:1267
#: project/templates/_macros.html:1283
msgid "Please enter a valid time, between 00:00 and 23:59."
msgstr "Bitte gib eine gültige Uhrzeit zwischen 00:00 und 23:59 ein."
#: project/templates/_macros.html:1295
#: project/templates/_macros.html:1311
#, python-format
msgid "Just use %(term)s"
msgstr "Verwende einfach %(term)s"
#: project/templates/_macros.html:1361
#: project/templates/_macros.html:1377
msgid "Event suggestion"
msgstr "Veranstaltungsvorschlag"
#: project/templates/_macros.html:1479
#: project/templates/_macros.html:1495
msgid "Link copied"
msgstr "Link kopiert"
#: project/templates/_macros.html:1479
#: project/templates/_macros.html:1495
msgid "Copy link"
msgstr "Link kopieren"
#: project/templates/_macros.html:1508
#: project/templates/_macros.html:1524
msgid "Google calendar"
msgstr "Google Kalender"
#: project/templates/_macros.html:1509
#: project/templates/_macros.html:1525
msgid "Apple calendar"
msgstr "Apple Kalender"
#: project/templates/_macros.html:1510
#: project/templates/_macros.html:1526
msgid "Yahoo calendar"
msgstr "Yahoo Kalender"
#: project/templates/_macros.html:1511
#: project/templates/_macros.html:1527
msgid "Other calendar"
msgstr "Anderer Kalender"
@ -1365,7 +1381,7 @@ msgid "Show events"
msgstr "Veranstaltungen anzeigen"
#: project/templates/event/create.html:5
#: project/templates/event/create.html:228 project/templates/layout.html:226
#: project/templates/event/create.html:250 project/templates/layout.html:226
#: project/templates/manage/events.html:22
#: project/templates/manage/organizers.html:21
msgid "Create event"
@ -1482,8 +1498,8 @@ msgstr "Bearbeiten"
#: project/templates/admin_unit/create.html:58
#: project/templates/admin_unit/update.html:59
#: project/templates/event/create.html:354
#: project/templates/event/update.html:211
#: project/templates/event/create.html:378
#: project/templates/event/update.html:234
#: project/templates/event_place/create.html:57
#: project/templates/event_place/update.html:57
#: project/templates/organizer/create.html:56
@ -1610,31 +1626,33 @@ msgid "Enter place or address"
msgstr "Orte oder Adresse eingeben"
#: project/templates/event/create.html:183
#: project/templates/event/create.html:240
#: project/templates/event/update.html:106
#: project/templates/event/update.html:132
#: project/templates/widget/event_suggestion/create.html:129
msgid "Enter organizer"
msgstr "Veranstalter eingeben"
#: project/templates/event/create.html:245
#: project/templates/event/update.html:136
#: project/templates/event/create.html:267
#: project/templates/event/update.html:158
msgid "Event date"
msgstr "Termin"
#: project/templates/event/create.html:283
#: project/templates/event/create.html:305
msgid "Switch to organizer search"
msgstr "Zur Veranstaltersuche wechseln"
#: project/templates/event/create.html:316
#: project/templates/event/create.html:340
msgid "Switch to place search"
msgstr "Zur Ortssuche wechseln"
#: project/templates/event/create.html:327
#: project/templates/event/update.html:184
#: project/templates/event/create.html:351
#: project/templates/event/update.html:207
msgid "Access"
msgstr "Zugang"
#: project/templates/event/create.html:341
#: project/templates/event/update.html:198
#: project/templates/event/create.html:365
#: project/templates/event/update.html:221
msgid "Target group"
msgstr "Zielgruppe"
@ -1943,11 +1961,11 @@ msgstr "Der eingegebene Name entspricht nicht dem Namen der Veranstaltung"
msgid "Event successfully deleted"
msgstr "Veranstaltung erfolgreich gelöscht"
#: project/views/event.py:397
#: project/views/event.py:404
msgid "Referenced event changed"
msgstr "Empfohlene Veranstaltung wurde geändert"
#: project/views/event.py:420
#: project/views/event.py:427
msgid "New event report"
msgstr "Neue Meldung zu einer Veranstaltung"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2021-09-10 09:01+0200\n"
"POT-Creation-Date: 2021-09-19 16:31+0200\n"
"PO-Revision-Date: 2021-04-30 15:04+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
@ -192,7 +192,7 @@ msgstr ""
msgid "Legal notice"
msgstr ""
#: project/forms/admin.py:12 project/templates/_macros.html:1389
#: project/forms/admin.py:12 project/templates/_macros.html:1405
#: project/templates/layout.html:313
#: project/templates/widget/event_suggestion/create.html:204
#: project/views/admin_unit.py:36 project/views/root.py:58
@ -280,7 +280,7 @@ msgid "Longitude"
msgstr ""
#: project/forms/admin_unit.py:28 project/forms/event.py:36
#: project/forms/event.py:65 project/forms/event.py:379
#: project/forms/event.py:65 project/forms/event.py:399
#: project/forms/event_place.py:25 project/forms/event_place.py:50
#: project/forms/event_suggestion.py:26 project/forms/oauth2_client.py:66
#: project/forms/organizer.py:25 project/forms/organizer.py:52
@ -300,7 +300,7 @@ msgstr ""
msgid "The short name is used to create a unique identifier for your events"
msgstr ""
#: project/forms/admin_unit.py:40 project/templates/_macros.html:1525
#: project/forms/admin_unit.py:40 project/templates/_macros.html:1541
msgid "Short name must contain only letters numbers or underscore"
msgstr ""
@ -314,7 +314,7 @@ msgstr ""
#: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28
#: project/forms/event.py:58 project/forms/event_suggestion.py:38
#: project/forms/organizer.py:27 project/templates/_macros.html:262
#: project/templates/_macros.html:1485 project/templates/admin/users.html:19
#: project/templates/_macros.html:1501 project/templates/admin/users.html:19
msgid "Email"
msgstr ""
@ -493,8 +493,8 @@ msgstr ""
msgid "All-day"
msgstr ""
#: project/forms/event.py:86 project/templates/event/create.html:252
#: project/templates/event/update.html:143
#: project/forms/event.py:86 project/templates/event/create.html:274
#: project/templates/event/update.html:165
#: project/templates/widget/event_suggestion/create.html:240
msgid "Recurring event"
msgstr ""
@ -651,16 +651,16 @@ msgid ""
" course it works without it."
msgstr ""
#: project/forms/event.py:208 project/templates/_macros.html:1246
#: project/forms/event.py:208 project/templates/_macros.html:1262
msgid "The start must be before the end."
msgstr ""
#: project/forms/event.py:214 project/templates/_macros.html:1263
#: project/forms/event.py:214 project/templates/_macros.html:1279
msgid "An event can last a maximum of 14 days."
msgstr ""
#: project/forms/event.py:222 project/templates/_macros.html:419
#: project/templates/_macros.html:575
#: project/templates/_macros.html:582
msgid "Previous start date"
msgstr ""
@ -678,8 +678,8 @@ msgstr ""
#: project/forms/event.py:235 project/forms/reference.py:14
#: project/forms/reference.py:27 project/forms/reference_request.py:76
#: project/templates/event/create.html:366
#: project/templates/event/update.html:223
#: project/templates/event/create.html:390
#: project/templates/event/update.html:246
msgid "Rating"
msgstr ""
@ -690,152 +690,166 @@ msgid ""
"visible and is used for sorting."
msgstr ""
#: project/forms/event.py:247 project/forms/event.py:256
#: project/forms/event.py:325 project/forms/event_suggestion.py:50
#: project/templates/_macros.html:459 project/templates/_macros.html:612
#: project/templates/event/create.html:291
#: project/templates/event/update.html:173
#: project/forms/event.py:244
msgid "Co-organizers"
msgstr ""
#: project/forms/event.py:247
msgid ""
"Select optional co-organizers. You can add and modify organizers at "
"Organization > Organizers."
msgstr ""
#: project/forms/event.py:258
msgid "Invalid co-organizer."
msgstr ""
#: project/forms/event.py:267 project/forms/event.py:276
#: project/forms/event.py:345 project/forms/event_suggestion.py:50
#: project/templates/_macros.html:459 project/templates/_macros.html:619
#: project/templates/event/create.html:315
#: project/templates/event/update.html:196
#: project/templates/event_place/create.html:31
#: project/templates/event_place/delete.html:13
#: project/templates/event_place/update.html:31
msgid "Place"
msgstr ""
#: project/forms/event.py:249
#: project/forms/event.py:269
msgid "Select existing place"
msgstr ""
#: project/forms/event.py:250
#: project/forms/event.py:270
msgid "Enter new place"
msgstr ""
#: project/forms/event.py:263 project/forms/event.py:272
#: project/forms/event.py:333 project/forms/event.py:395
#: project/forms/event_suggestion.py:60 project/templates/_macros.html:497
#: project/templates/_macros.html:649 project/templates/event/create.html:262
#: project/templates/event/update.html:164
#: project/forms/event.py:283 project/forms/event.py:292
#: project/forms/event.py:353 project/forms/event.py:415
#: project/forms/event_suggestion.py:60 project/templates/_macros.html:496
#: project/templates/_macros.html:656 project/templates/event/create.html:284
#: project/templates/event/update.html:186
#: project/templates/organizer/create.html:27
#: project/templates/organizer/delete.html:13
#: project/templates/organizer/update.html:27
msgid "Organizer"
msgstr ""
#: project/forms/event.py:265
#: project/forms/event.py:285
msgid "Select existing organizer"
msgstr ""
#: project/forms/event.py:266
#: project/forms/event.py:286
msgid "Enter new organizer"
msgstr ""
#: project/forms/event.py:278
#: project/forms/event.py:298
msgid "Save as draft"
msgstr ""
#: project/forms/event.py:279
#: project/forms/event.py:299
msgid "Publish event"
msgstr ""
#: project/forms/event.py:309
#: project/forms/event.py:329
msgid "Select existing place or enter new place"
msgstr ""
#: project/forms/event.py:316
#: project/forms/event.py:336
msgid "Select existing organizer or enter new organizer"
msgstr ""
#: project/forms/event.py:328
#: project/forms/event.py:348
msgid ""
"Choose where the event takes place. You can add and modify places at "
"Manage > Places."
"Organization > Places."
msgstr ""
#: project/forms/event.py:336
#: project/forms/event.py:356
msgid ""
"Select the organizer. You can add and modify organizers at Manage > "
"Organizers."
"Select the organizer. You can add and modify organizers at Organization >"
" Organizers."
msgstr ""
#: project/forms/event.py:342 project/templates/event/update.html:153
#: project/forms/event.py:362 project/templates/event/update.html:175
#: project/templates/oauth2_token/list.html:21
msgid "Status"
msgstr ""
#: project/forms/event.py:345
#: project/forms/event.py:365
msgid "EventStatus.scheduled"
msgstr "Scheduled"
#: project/forms/event.py:346 project/templates/layout.html:82
#: project/forms/event.py:366 project/templates/layout.html:82
#: project/templates/layout.html:97
msgid "EventStatus.cancelled"
msgstr "Cancelled"
#: project/forms/event.py:347 project/templates/layout.html:85
#: project/forms/event.py:367 project/templates/layout.html:85
#: project/templates/layout.html:100
msgid "EventStatus.movedOnline"
msgstr "Moved online"
#: project/forms/event.py:348 project/templates/layout.html:88
#: project/forms/event.py:368 project/templates/layout.html:88
#: project/templates/layout.html:103
msgid "EventStatus.postponed"
msgstr "Postponed"
#: project/forms/event.py:349 project/templates/layout.html:91
#: project/forms/event.py:369 project/templates/layout.html:91
#: project/templates/layout.html:106
msgid "EventStatus.rescheduled"
msgstr "Rescheduled"
#: project/forms/event.py:351
#: project/forms/event.py:371
msgid "Select the status of the event."
msgstr ""
#: project/forms/event.py:355
#: project/forms/event.py:375
msgid "Public status"
msgstr ""
#: project/forms/event.py:358
#: project/forms/event.py:378
msgid "PublicStatus.published"
msgstr ""
#: project/forms/event.py:359 project/templates/_macros.html:282
#: project/forms/event.py:379 project/templates/_macros.html:282
msgid "PublicStatus.draft"
msgstr ""
#: project/forms/event.py:361
#: project/forms/event.py:381
msgid "Select the public status of the event."
msgstr ""
#: project/forms/event.py:364 project/templates/event/update.html:5
#: project/templates/event/update.html:119
#: project/forms/event.py:384 project/templates/event/update.html:5
#: project/templates/event/update.html:141
msgid "Update event"
msgstr ""
#: project/forms/event.py:378 project/templates/_macros.html:1218
#: project/forms/event.py:398 project/templates/_macros.html:1234
#: project/templates/event/actions.html:47
#: project/templates/event/delete.html:6
msgid "Delete event"
msgstr ""
#: project/forms/event.py:386 project/forms/event_date.py:15
#: project/forms/event.py:406 project/forms/event_date.py:15
#: project/forms/planing.py:14
msgid "From"
msgstr ""
#: project/forms/event.py:388 project/forms/event_date.py:17
#: project/forms/event.py:408 project/forms/event_date.py:17
#: project/forms/planing.py:16
msgid "to"
msgstr ""
#: project/forms/event.py:390 project/forms/event_date.py:19
#: project/forms/event.py:410 project/forms/event_date.py:19
msgid "Keyword"
msgstr ""
#: project/forms/event.py:392 project/forms/event_date.py:21
#: project/forms/event.py:412 project/forms/event_date.py:21
#: project/forms/planing.py:19 project/templates/_macros.html:392
msgid "Category"
msgstr ""
#: project/forms/event.py:398
#: project/forms/event.py:418
msgid "Find events"
msgstr ""
@ -896,13 +910,13 @@ msgstr ""
msgid "I would like to be notified by email after the review"
msgstr ""
#: project/forms/event_suggestion.py:52 project/templates/event/create.html:296
#: project/forms/event_suggestion.py:52 project/templates/event/create.html:320
msgid ""
"Choose where the event takes place. If the venue is not yet in the list, "
"just enter it."
msgstr ""
#: project/forms/event_suggestion.py:62 project/templates/event/create.html:266
#: project/forms/event_suggestion.py:62 project/templates/event/create.html:288
msgid ""
"Select the organizer. If the organizer is not yet on the list, just enter"
" it."
@ -984,7 +998,7 @@ msgid "Weekdays"
msgstr ""
#: project/forms/reference.py:11 project/forms/reference_request.py:16
#: project/templates/_macros.html:518 project/templates/_macros.html:675
#: project/templates/_macros.html:512 project/templates/_macros.html:672
#: project/templates/admin_unit/create.html:28
#: project/templates/admin_unit/update.html:29
#: project/templates/layout.html:258
@ -1012,7 +1026,7 @@ msgstr ""
msgid "Delete request"
msgstr ""
#: project/forms/reference_request.py:28 project/templates/_macros.html:1401
#: project/forms/reference_request.py:28 project/templates/_macros.html:1417
#: project/templates/event_suggestion/review_status.html:18
#: project/templates/reference_request/review_status.html:12
msgid "Review status"
@ -1079,7 +1093,7 @@ msgid "This field is required."
msgstr ""
#: project/templates/_macros.html:134 project/templates/_macros.html:414
#: project/templates/_macros.html:914
#: project/templates/_macros.html:930
msgid "Date"
msgstr ""
@ -1119,64 +1133,64 @@ msgstr ""
msgid "Last updated at %(updated_at)s."
msgstr ""
#: project/templates/_macros.html:408 project/templates/_macros.html:571
#: project/templates/_macros.html:408 project/templates/_macros.html:578
#: project/templates/event/actions.html:12
#: project/templates/event/create.html:235
#: project/templates/event/create.html:257
#: project/templates/event/delete.html:13
#: project/templates/event/update.html:126
#: project/templates/event/update.html:148
#: project/templates/widget/event_suggestion/create.html:229
msgid "Event"
msgstr ""
#: project/templates/_macros.html:441 project/templates/_macros.html:593
#: project/templates/_macros.html:1470 project/templates/event/actions.html:32
#: project/templates/_macros.html:441 project/templates/_macros.html:600
#: project/templates/_macros.html:1486 project/templates/event/actions.html:32
msgid "Share"
msgstr ""
#: project/templates/_macros.html:445 project/templates/_macros.html:597
#: project/templates/_macros.html:1500
#: project/templates/_macros.html:445 project/templates/_macros.html:604
#: project/templates/_macros.html:1516
msgid "Add to calendar"
msgstr ""
#: project/templates/_macros.html:453 project/templates/_macros.html:605
#: project/templates/_macros.html:453 project/templates/_macros.html:612
#: project/templates/event/report.html:4
msgid "Report event"
msgstr ""
#: project/templates/_macros.html:480 project/templates/_macros.html:631
#: project/templates/_macros.html:480 project/templates/_macros.html:638
msgid "Show directions"
msgstr ""
#: project/templates/_macros.html:485 project/templates/_macros.html:636
#: project/templates/_macros.html:485 project/templates/_macros.html:643
msgid "The event takes place online."
msgstr ""
#: project/templates/_macros.html:487 project/templates/_macros.html:638
#: project/templates/_macros.html:487 project/templates/_macros.html:645
msgid "The event takes place both offline and online."
msgstr ""
#: project/templates/_macros.html:699 project/templates/event_date/list.html:5
#: project/templates/_macros.html:696 project/templates/event_date/list.html:5
#: project/templates/event_date/list.html:300
#: project/templates/event_date/search.html:3
#: project/templates/reference_request/review.html:32
msgid "Event Dates"
msgstr ""
#: project/templates/_macros.html:772
#: project/templates/_macros.html:788
msgid "Search location on Google"
msgstr ""
#: project/templates/_macros.html:838
#: project/templates/_macros.html:854
#, python-format
msgid "%(count)d event dates"
msgstr ""
#: project/templates/_macros.html:854 project/templates/_macros.html:856
#: project/templates/_macros.html:870 project/templates/_macros.html:872
#: project/templates/event_date/list.html:321
msgid "First"
msgstr ""
#: project/templates/_macros.html:859 project/templates/_macros.html:861
#: project/templates/_macros.html:875 project/templates/_macros.html:877
#: project/templates/event_date/list.html:322
#: project/templates/widget/event_suggestion/create.html:193
#: project/templates/widget/event_suggestion/create.html:218
@ -1187,12 +1201,12 @@ msgstr ""
msgid "Previous"
msgstr ""
#: project/templates/_macros.html:863
#: project/templates/_macros.html:879
#, python-format
msgid "Page %(page)d of %(pages)d (%(total)d total)"
msgstr ""
#: project/templates/_macros.html:865 project/templates/_macros.html:867
#: project/templates/_macros.html:881 project/templates/_macros.html:883
#: project/templates/event_date/list.html:324
#: project/templates/widget/event_suggestion/create.html:194
#: project/templates/widget/event_suggestion/create.html:219
@ -1202,73 +1216,73 @@ msgstr ""
msgid "Next"
msgstr ""
#: project/templates/_macros.html:870 project/templates/_macros.html:872
#: project/templates/_macros.html:886 project/templates/_macros.html:888
#: project/templates/event_date/list.html:325
msgid "Last"
msgstr ""
#: project/templates/_macros.html:937
#: project/templates/_macros.html:953
msgid "Radius"
msgstr ""
#: project/templates/_macros.html:1147
#: project/templates/_macros.html:1163
msgid "Edit image"
msgstr ""
#: project/templates/_macros.html:1168
#: project/templates/_macros.html:1184
msgid "Close"
msgstr ""
#: project/templates/_macros.html:1169
#: project/templates/_macros.html:1185
msgid "Okay"
msgstr ""
#: project/templates/_macros.html:1181
#: project/templates/_macros.html:1197
msgid "Choose image file"
msgstr ""
#: project/templates/_macros.html:1217 project/templates/event/actions.html:46
#: project/templates/_macros.html:1233 project/templates/event/actions.html:46
msgid "Edit event"
msgstr ""
#: project/templates/_macros.html:1220 project/templates/manage/events.html:40
#: project/templates/_macros.html:1236 project/templates/manage/events.html:40
msgid "More"
msgstr ""
#: project/templates/_macros.html:1267
#: project/templates/_macros.html:1283
msgid "Please enter a valid time, between 00:00 and 23:59."
msgstr ""
#: project/templates/_macros.html:1295
#: project/templates/_macros.html:1311
#, python-format
msgid "Just use %(term)s"
msgstr ""
#: project/templates/_macros.html:1361
#: project/templates/_macros.html:1377
msgid "Event suggestion"
msgstr ""
#: project/templates/_macros.html:1479
#: project/templates/_macros.html:1495
msgid "Link copied"
msgstr ""
#: project/templates/_macros.html:1479
#: project/templates/_macros.html:1495
msgid "Copy link"
msgstr ""
#: project/templates/_macros.html:1508
#: project/templates/_macros.html:1524
msgid "Google calendar"
msgstr ""
#: project/templates/_macros.html:1509
#: project/templates/_macros.html:1525
msgid "Apple calendar"
msgstr ""
#: project/templates/_macros.html:1510
#: project/templates/_macros.html:1526
msgid "Yahoo calendar"
msgstr ""
#: project/templates/_macros.html:1511
#: project/templates/_macros.html:1527
msgid "Other calendar"
msgstr ""
@ -1328,7 +1342,7 @@ msgid "Show events"
msgstr ""
#: project/templates/event/create.html:5
#: project/templates/event/create.html:228 project/templates/layout.html:226
#: project/templates/event/create.html:250 project/templates/layout.html:226
#: project/templates/manage/events.html:22
#: project/templates/manage/organizers.html:21
msgid "Create event"
@ -1445,8 +1459,8 @@ msgstr ""
#: project/templates/admin_unit/create.html:58
#: project/templates/admin_unit/update.html:59
#: project/templates/event/create.html:354
#: project/templates/event/update.html:211
#: project/templates/event/create.html:378
#: project/templates/event/update.html:234
#: project/templates/event_place/create.html:57
#: project/templates/event_place/update.html:57
#: project/templates/organizer/create.html:56
@ -1571,31 +1585,33 @@ msgid "Enter place or address"
msgstr ""
#: project/templates/event/create.html:183
#: project/templates/event/create.html:240
#: project/templates/event/update.html:106
#: project/templates/event/update.html:132
#: project/templates/widget/event_suggestion/create.html:129
msgid "Enter organizer"
msgstr ""
#: project/templates/event/create.html:245
#: project/templates/event/update.html:136
#: project/templates/event/create.html:267
#: project/templates/event/update.html:158
msgid "Event date"
msgstr ""
#: project/templates/event/create.html:283
#: project/templates/event/create.html:305
msgid "Switch to organizer search"
msgstr ""
#: project/templates/event/create.html:316
#: project/templates/event/create.html:340
msgid "Switch to place search"
msgstr ""
#: project/templates/event/create.html:327
#: project/templates/event/update.html:184
#: project/templates/event/create.html:351
#: project/templates/event/update.html:207
msgid "Access"
msgstr ""
#: project/templates/event/create.html:341
#: project/templates/event/update.html:198
#: project/templates/event/create.html:365
#: project/templates/event/update.html:221
msgid "Target group"
msgstr ""
@ -1901,11 +1917,11 @@ msgstr ""
msgid "Event successfully deleted"
msgstr ""
#: project/views/event.py:397
#: project/views/event.py:404
msgid "Referenced event changed"
msgstr ""
#: project/views/event.py:420
#: project/views/event.py:427
msgid "New event report"
msgstr ""

View File

@ -300,9 +300,16 @@ def prepare_organizer(form):
if organizer:
form.organizer_id.choices = [(organizer.id, organizer.name)]
if form.co_organizer_ids.data and len(form.co_organizer_ids.data) > 0:
co_organizers = EventOrganizer.query.filter(
EventOrganizer.id.in_(form.co_organizer_ids.data)
).all()
form.co_organizer_ids.choices = [(o.id, o.name) for o in co_organizers]
def prepare_event_form(form):
form.category_ids.choices = get_event_category_choices()
form.co_organizer_ids.choices = list()
prepare_organizer(form)
prepare_event_place(form)

View File

@ -48,7 +48,7 @@ def handleSqlError(e: SQLAlchemyError) -> str:
return str(e)
prefix = None
message = str(e.orig)
message = gettext(e.orig.message) if hasattr(e.orig, "message") else str(e.orig)
if e.orig.pgcode == UNIQUE_VIOLATION:
prefix = gettext(

View File

@ -41,6 +41,19 @@ def test_read_myDraft(client, app, db, seeder, utils):
assert response.json["public_status"] == "draft"
def test_read_co_organizers(client, app, db, seeder, utils):
user_id, admin_unit_id = seeder.setup_base()
event_id, organizer_a_id, organizer_b_id = seeder.create_event_with_co_organizers(
admin_unit_id
)
url = utils.get_url("api_v1_event", id=event_id)
response = utils.get_json(url)
utils.assert_response_ok(response)
assert response.json["co_organizers"][0]["id"] == organizer_a_id
assert response.json["co_organizers"][1]["id"] == organizer_b_id
def test_list(client, seeder, utils):
user_id, admin_unit_id = seeder.setup_base()
event_id = seeder.create_event(admin_unit_id)
@ -251,6 +264,53 @@ def test_put_organizerFromAnotherAdminUnit(client, seeder, utils, app):
utils.assert_response_api_error(response, "Check Violation")
def test_put_co_organizers(client, seeder, utils, app):
user_id, admin_unit_id = seeder.setup_api_access()
event_id = seeder.create_event(admin_unit_id)
place_id = seeder.upsert_default_event_place(admin_unit_id)
organizer_id = seeder.upsert_default_event_organizer(admin_unit_id)
organizer_a_id = seeder.upsert_event_organizer(admin_unit_id, "Organizer A")
organizer_b_id = seeder.upsert_event_organizer(admin_unit_id, "Organizer B")
put = create_put(place_id, organizer_id)
put["co_organizers"] = [
{"id": organizer_a_id},
{"id": organizer_b_id},
]
url = utils.get_url("api_v1_event", id=event_id)
response = utils.put_json(url, put)
utils.assert_response_no_content(response)
with app.app_context():
from project.models import Event
event = Event.query.get(event_id)
assert len(event.co_organizers) == 2
assert event.co_organizers[0].id == organizer_a_id
assert event.co_organizers[1].id == organizer_b_id
def test_put_co_organizerFromAnotherAdminUnit(client, seeder, utils, app):
user_id, admin_unit_id = seeder.setup_api_access()
event_id = seeder.create_event(admin_unit_id)
place_id = seeder.upsert_default_event_place(admin_unit_id)
organizer_id = seeder.upsert_default_event_organizer(admin_unit_id)
other_admin_unit_id = seeder.create_admin_unit(user_id, "Other Crew")
organizer_a_id = seeder.upsert_event_organizer(other_admin_unit_id, "Organizer A")
put = create_put(place_id, organizer_id)
put["co_organizers"] = [
{"id": organizer_a_id},
]
url = utils.get_url("api_v1_event", id=event_id)
response = utils.put_json(url, put)
utils.assert_response_bad_request(response)
utils.assert_response_api_error(response, "Check Violation")
def test_put_invalidDateFormat(client, seeder, utils, app):
user_id, admin_unit_id = seeder.setup_api_access()
event_id = seeder.create_event(admin_unit_id)

View File

@ -48,7 +48,10 @@ def test_event_search(client, seeder, utils):
response = utils.get_json(url)
utils.assert_response_ok(response)
assert len(response.json["items"]) == 2
assert response.json["items"][1]["public_status"] == "draft"
assert (
response.json["items"][0]["public_status"] == "draft"
or response.json["items"][1]["public_status"] == "draft"
)
def test_organizers(client, seeder, utils):
@ -142,6 +145,30 @@ def test_events_post(client, seeder, utils, app, allday):
assert event.allday == allday
def test_events_post_co_organizers(client, seeder, utils, app):
url, data, admin_unit_id, place_id, organizer_id = prepare_events_post_data(
seeder, utils
)
organizer_a_id = seeder.upsert_event_organizer(admin_unit_id, "Organizer A")
organizer_b_id = seeder.upsert_event_organizer(admin_unit_id, "Organizer B")
data["co_organizers"] = [
{"id": organizer_a_id},
{"id": organizer_b_id},
]
response = utils.post_json(url, data)
utils.assert_response_created(response)
event_id = int(response.json["id"])
with app.app_context():
from project.models import Event
event = Event.query.get(event_id)
assert len(event.co_organizers) == 2
assert event.co_organizers[0].id == organizer_a_id
assert event.co_organizers[1].id == organizer_b_id
def test_events_post_photo_no_data(client, seeder, utils, app):
url, data, admin_unit_id, place_id, organizer_id = prepare_events_post_data(
seeder, utils

View File

@ -1,6 +1,7 @@
def test_all(client, seeder, app, utils):
user_id, admin_unit_id = seeder.setup_base()
seeder.create_event(admin_unit_id, "RRULE:FREQ=DAILY;COUNT=7")
seeder.create_event_with_co_organizers(admin_unit_id)
runner = app.test_cli_runner()
result = runner.invoke(args=["dump", "all"])

View File

@ -33,12 +33,15 @@ def app():
@pytest.fixture
def db(app):
from flask_migrate import stamp
from project import db
from project.init_data import create_initial_data
with app.app_context():
db.drop_all()
db.create_all()
stamp()
create_initial_data()
return db

View File

@ -115,7 +115,7 @@ class Form:
# Override any form values with our input
for key, value in values.items():
if key in filled:
filled.pop(key)
del filled[key]
if type(value) is list:
filled.setlist(key, value)
else:

View File

@ -199,8 +199,14 @@ class Seeder(object):
name="Name",
start=None,
allday=False,
co_organizer_ids=None,
):
from project.models import Event, EventAttendanceMode, PublicStatus
from project.models import (
Event,
EventAttendanceMode,
EventOrganizer,
PublicStatus,
)
from project.services.event import insert_event, upsert_event_category
with self._app.app_context():
@ -224,11 +230,25 @@ class Seeder(object):
if draft:
event.public_status = PublicStatus.draft
if co_organizer_ids:
co_organizers = EventOrganizer.query.filter(
EventOrganizer.id.in_(co_organizer_ids)
).all()
event.co_organizers = co_organizers
insert_event(event)
self._db.session.commit()
event_id = event.id
return event_id
def create_event_with_co_organizers(self, admin_unit_id):
organizer_a_id = self.upsert_event_organizer(admin_unit_id, "Organizer A")
organizer_b_id = self.upsert_event_organizer(admin_unit_id, "Organizer B")
event_id = self.create_event(
admin_unit_id, co_organizer_ids=[organizer_a_id, organizer_b_id]
)
return (event_id, organizer_a_id, organizer_b_id)
def create_event_via_form(self, admin_unit_id: int) -> str:
place_id = self.upsert_default_event_place(admin_unit_id)
organizer_id = self.upsert_default_event_organizer(admin_unit_id)

View File

@ -166,6 +166,25 @@ def test_get_sd_for_event_date_allday(client, app, db, seeder, utils):
assert '"endDate": "2030-12-31"' in structured_data
def test_get_sd_for_event_date_with_co_organizer(client, app, db, seeder, utils):
user_id, admin_unit_id = seeder.setup_base()
event_id, organizer_a_id, organizer_b_id = seeder.create_event_with_co_organizers(
admin_unit_id
)
with app.app_context():
from project.jsonld import get_sd_for_event_date
from project.models import Event
event = Event.query.get(event_id)
event_date = event.dates[0]
with app.test_request_context():
data = get_sd_for_event_date(event_date)
assert len(data["organizer"]) == 4
@pytest.mark.parametrize(
"age_from, age_to, typicalAgeRange",
[(18, None, "18-"), (None, 14, "-14"), (9, 99, "9-99")],

View File

@ -158,3 +158,28 @@ def test_admin_unit_deletion(client, app, db, seeder):
assert AdminUnit.query.get(other_admin_unit_id) is not None
assert Event.query.get(other_event_id) is not None
def test_event_co_organizers_deletion(client, app, db, seeder):
user_id, admin_unit_id = seeder.setup_base(log_in=False)
event_id, organizer_a_id, organizer_b_id = seeder.create_event_with_co_organizers(
admin_unit_id
)
with app.app_context():
from project.models import Event, EventOrganizer
event = Event.query.get(event_id)
assert len(event.co_organizers) == 2
assert event.co_organizers[0].id == organizer_a_id
assert event.co_organizers[1].id == organizer_b_id
organizer_a = EventOrganizer.query.get(organizer_a_id)
db.session.delete(organizer_a)
db.session.commit()
assert len(event.co_organizers) == 1
assert event.co_organizers[0].id == organizer_b_id
db.session.delete(event)
db.session.commit()
assert EventOrganizer.query.get(organizer_b_id).id is not None

View File

@ -34,6 +34,18 @@ def test_read_containsActionLink(seeder, utils):
assert action_url in str(response.data)
def test_read_co_organizers(seeder, utils):
user_id, admin_unit_id = seeder.setup_base()
event_id, organizer_a_id, organizer_b_id = seeder.create_event_with_co_organizers(
admin_unit_id
)
url = utils.get_url("event", event_id=event_id)
response = utils.get_ok(url)
utils.assert_response_contains(response, "Organizer A")
utils.assert_response_contains(response, "Organizer B")
@pytest.mark.parametrize("db_error", [True, False])
def test_create(client, app, utils, seeder, mocker, db_error):
user_id, admin_unit_id = seeder.setup_base()
@ -182,6 +194,27 @@ def test_create_missingPlace(client, app, utils, seeder, mocker):
def test_create_missingOrganizer(client, app, utils, seeder, mocker):
user_id, admin_unit_id = seeder.setup_base()
place_id = seeder.upsert_default_event_place(admin_unit_id)
url = utils.get_url("event_create_for_admin_unit_id", id=admin_unit_id)
response = utils.get_ok(url)
response = utils.post_form(
url,
response,
{
"name": "Name",
"description": "Beschreibung",
"start": ["2030-12-31", "23:59"],
"event_place_id": place_id,
},
)
utils.assert_response_error_message(response)
def test_create_invalidOrganizer(client, app, utils, seeder, mocker):
user_id, admin_unit_id = seeder.setup_base()
place_id = seeder.upsert_default_event_place(admin_unit_id)
organizer_id = seeder.upsert_default_event_organizer(admin_unit_id)
url = utils.get_url("event_create_for_admin_unit_id", id=admin_unit_id)
@ -193,13 +226,15 @@ def test_create_missingOrganizer(client, app, utils, seeder, mocker):
{
"name": "Name",
"description": "Beschreibung",
"start": ["31.12.2030", "23:59"],
"start": ["2030-12-31", "23:59"],
"event_place_id": place_id,
"organizer_id": organizer_id,
"co_organizer_ids": [organizer_id],
},
)
utils.assert_response_error_message(response)
utils.assert_response_contains(response, "Ungültiger Mitveranstalter")
def test_create_invalidDateFormat(client, app, utils, seeder, mocker):
@ -223,6 +258,27 @@ def test_create_invalidDateFormat(client, app, utils, seeder, mocker):
utils.assert_response_error_message(response)
def test_create_startInvalid(client, app, utils, seeder, mocker):
user_id, admin_unit_id = seeder.setup_base()
place_id = seeder.upsert_default_event_place(admin_unit_id)
url = utils.get_url("event_create_for_admin_unit_id", id=admin_unit_id)
response = utils.get_ok(url)
response = utils.post_form(
url,
response,
{
"name": "Name",
"start": ["31.12.2030", "23:59"],
"end": ["2030-12-31", "23:58"],
"event_place_id": place_id,
},
)
utils.assert_response_error_message(response)
def test_create_startAfterEnd(client, app, utils, seeder, mocker):
user_id, admin_unit_id = seeder.setup_base()
place_id = seeder.upsert_default_event_place(admin_unit_id)
@ -445,6 +501,28 @@ def test_update(client, seeder, utils, app, mocker, db_error):
assert event is not None
def test_update_co_organizers(client, seeder, utils, app):
user_id, admin_unit_id = seeder.setup_base()
event_id, organizer_a_id, organizer_b_id = seeder.create_event_with_co_organizers(
admin_unit_id
)
url = utils.get_url("event_update", event_id=event_id)
response = utils.get_ok(url)
response = utils.post_form(
url,
response,
{
"name": "Neuer Name",
},
)
utils.assert_response_redirect(
response, "manage_admin_unit_events", id=admin_unit_id
)
@pytest.mark.parametrize("db_error", [True, False])
def test_delete(client, seeder, utils, app, mocker, db_error):
user_id, admin_unit_id = seeder.setup_base()

View File

@ -90,6 +90,20 @@ def test_event_date(client, seeder, utils, app, db):
utils.assert_response_unauthorized(response)
def test_event_date_co_organizers(client, seeder, utils, app, db):
user_id, admin_unit_id = seeder.setup_base(log_in=False)
event_id, organizer_a_id, organizer_b_id = seeder.create_event_with_co_organizers(
admin_unit_id
)
au_short_name = "meinecrew"
url = utils.get_url("widget_event_date", au_short_name=au_short_name, id=event_id)
response = utils.get(url)
response = utils.get_ok(url)
utils.assert_response_contains(response, "Organizer A")
utils.assert_response_contains(response, "Organizer B")
def get_create_data():
return {
"accept_tos": "y",