Add newsletter functionality #391

This commit is contained in:
Daniel Grams 2023-03-28 22:50:07 +02:00
parent 0547f08528
commit a6d452c20b
25 changed files with 754 additions and 253 deletions

View File

@ -1,5 +1,5 @@
[flake8] [flake8]
extend-ignore = E501, E203 extend-ignore = E501, E203, E711
exclude = exclude =
.git, .git,
.github, .github,

View File

@ -35,6 +35,19 @@ jobs:
# Maps tcp port 5432 on service container to the host # Maps tcp port 5432 on service container to the host
- 5432:5432 - 5432:5432
redis:
# Docker Hub image
image: redis
# Set health checks to wait until redis has started
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
# Maps port 6379 on service container to the host
- 6379:6379
steps: steps:
- name: Check out repository code - name: Check out repository code
uses: actions/checkout@v2 uses: actions/checkout@v2
@ -53,6 +66,7 @@ jobs:
run: pytest --cov=project --splits 4 --group ${{ matrix.group }} run: pytest --cov=project --splits 4 --group ${{ matrix.group }}
env: env:
TEST_DATABASE_URL: postgresql://postgres:postgres@localhost/eventcally_tests TEST_DATABASE_URL: postgresql://postgres:postgres@localhost/eventcally_tests
TEST_REDIS_URL: redis://redis:6379
- name: Upload coverage - name: Upload coverage
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2023-03-24 21:24+0100\n" "POT-Creation-Date: 2023-03-28 17:04+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -208,7 +208,7 @@ msgstr ""
msgid "Legal notice" msgid "Legal notice"
msgstr "" msgstr ""
#: project/forms/admin.py:13 project/templates/_macros.html:1395 #: project/forms/admin.py:13 project/templates/_macros.html:1397
#: project/templates/layout.html:302 #: project/templates/layout.html:302
#: project/templates/widget/event_suggestion/create.html:204 #: project/templates/widget/event_suggestion/create.html:204
#: project/views/admin_unit.py:73 project/views/root.py:69 #: project/views/admin_unit.py:73 project/views/root.py:69
@ -225,6 +225,7 @@ msgid "Start page"
msgstr "" msgstr ""
#: project/forms/admin.py:17 project/forms/oauth2_client.py:24 #: project/forms/admin.py:17 project/forms/oauth2_client.py:24
#: project/forms/user.py:13
msgid "Save" msgid "Save"
msgstr "" msgstr ""
@ -285,7 +286,7 @@ msgstr ""
msgid "Update organization" msgid "Update organization"
msgstr "" msgstr ""
#: project/forms/admin.py:63 #: project/forms/admin.py:63 project/forms/admin.py:70
msgid "Recipient" msgid "Recipient"
msgstr "" msgstr ""
@ -293,6 +294,22 @@ msgstr ""
msgid "Send test mail synchronously" msgid "Send test mail synchronously"
msgstr "" msgstr ""
#: project/forms/admin.py:72 project/forms/admin.py:78
msgid "Test recipient"
msgstr ""
#: project/forms/admin.py:73
msgid "All users with enabled newsletter setting"
msgstr ""
#: project/forms/admin.py:79
msgid "Message"
msgstr ""
#: project/forms/admin.py:80
msgid "Send newsletter"
msgstr ""
#: project/forms/admin_unit.py:15 project/forms/event_place.py:12 #: project/forms/admin_unit.py:15 project/forms/event_place.py:12
#: project/forms/organizer.py:12 #: project/forms/organizer.py:12
msgid "Street" msgid "Street"
@ -342,7 +359,7 @@ msgstr ""
msgid "The short name is used to create a unique identifier for your events" msgid "The short name is used to create a unique identifier for your events"
msgstr "" msgstr ""
#: project/forms/admin_unit.py:41 project/templates/_macros.html:1531 #: project/forms/admin_unit.py:41 project/templates/_macros.html:1533
msgid "Short name must contain only letters numbers or underscore" msgid "Short name must contain only letters numbers or underscore"
msgstr "" msgstr ""
@ -355,20 +372,21 @@ msgstr ""
#: project/forms/admin_unit.py:48 project/forms/admin_unit_member.py:11 #: project/forms/admin_unit.py:48 project/forms/admin_unit_member.py:11
#: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28 #: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28
#: project/forms/event.py:107 project/forms/event_suggestion.py:38 #: project/forms/event.py:107 project/forms/event_suggestion.py:38
#: project/forms/organizer.py:27 project/templates/_macros.html:235 #: project/forms/organizer.py:27 project/templates/_macros.html:237
#: project/templates/_macros.html:1491 project/templates/admin/admin.html:27 #: project/templates/_macros.html:1493 project/templates/admin/admin.html:27
#: project/templates/admin/email.html:4 project/templates/admin/email.html:66
#: project/templates/admin/users.html:19 #: project/templates/admin/users.html:19
msgid "Email" msgid "Email"
msgstr "" msgstr ""
#: project/forms/admin_unit.py:49 project/forms/event.py:108 #: project/forms/admin_unit.py:49 project/forms/event.py:108
#: project/forms/event_suggestion.py:31 project/forms/organizer.py:28 #: project/forms/event_suggestion.py:31 project/forms/organizer.py:28
#: project/templates/_macros.html:288 #: project/templates/_macros.html:290
msgid "Phone" msgid "Phone"
msgstr "" msgstr ""
#: project/forms/admin_unit.py:50 project/forms/event.py:109 #: project/forms/admin_unit.py:50 project/forms/event.py:109
#: project/forms/organizer.py:29 project/templates/_macros.html:296 #: project/forms/organizer.py:29 project/templates/_macros.html:298
msgid "Fax" msgid "Fax"
msgstr "" msgstr ""
@ -566,16 +584,16 @@ msgstr ""
msgid "All-day" msgid "All-day"
msgstr "" msgstr ""
#: project/forms/event.py:54 project/templates/_macros.html:1711 #: project/forms/event.py:54 project/templates/_macros.html:1713
#: project/templates/widget/event_suggestion/create.html:240 #: project/templates/widget/event_suggestion/create.html:240
msgid "Recurring event" msgid "Recurring event"
msgstr "" msgstr ""
#: project/forms/event.py:61 project/templates/_macros.html:1252 #: project/forms/event.py:61 project/templates/_macros.html:1254
msgid "The start must be before the end." msgid "The start must be before the end."
msgstr "" msgstr ""
#: project/forms/event.py:67 project/templates/_macros.html:1269 #: project/forms/event.py:67 project/templates/_macros.html:1271
msgid "An event can last a maximum of 14 days." msgid "An event can last a maximum of 14 days."
msgstr "" msgstr ""
@ -609,7 +627,7 @@ msgstr ""
msgid "Enter a link where tickets can be purchased." msgid "Enter a link where tickets can be purchased."
msgstr "" msgstr ""
#: project/forms/event.py:136 project/templates/_macros.html:217 #: project/forms/event.py:136 project/templates/_macros.html:219
msgid "Tags" msgid "Tags"
msgstr "" msgstr ""
@ -659,7 +677,7 @@ msgstr ""
msgid "If the participants needs to register for the event." msgid "If the participants needs to register for the event."
msgstr "" msgstr ""
#: project/forms/event.py:170 project/templates/_macros.html:249 #: project/forms/event.py:170 project/templates/_macros.html:251
#: project/templates/layout.html:110 #: project/templates/layout.html:110
msgid "Booked up" msgid "Booked up"
msgstr "" msgstr ""
@ -739,8 +757,8 @@ msgid ""
" course it works without it." " course it works without it."
msgstr "" msgstr ""
#: project/forms/event.py:242 project/templates/_macros.html:396 #: project/forms/event.py:242 project/templates/_macros.html:398
#: project/templates/_macros.html:559 #: project/templates/_macros.html:561
msgid "Previous start date" msgid "Previous start date"
msgstr "" msgstr ""
@ -786,7 +804,7 @@ msgstr ""
#: project/forms/event.py:286 project/forms/event.py:295 #: project/forms/event.py:286 project/forms/event.py:295
#: project/forms/event.py:368 project/forms/event_suggestion.py:50 #: project/forms/event.py:368 project/forms/event_suggestion.py:50
#: project/templates/_macros.html:436 project/templates/_macros.html:599 #: project/templates/_macros.html:438 project/templates/_macros.html:601
#: project/templates/event/create.html:284 #: project/templates/event/create.html:284
#: project/templates/event/update.html:166 #: project/templates/event/update.html:166
#: project/templates/event_place/create.html:31 #: project/templates/event_place/create.html:31
@ -805,8 +823,8 @@ msgstr ""
#: project/forms/event.py:302 project/forms/event.py:311 #: project/forms/event.py:302 project/forms/event.py:311
#: project/forms/event.py:376 project/forms/event.py:439 #: project/forms/event.py:376 project/forms/event.py:439
#: project/forms/event_suggestion.py:60 project/templates/_macros.html:473 #: project/forms/event_suggestion.py:60 project/templates/_macros.html:475
#: project/templates/_macros.html:636 project/templates/event/create.html:253 #: project/templates/_macros.html:638 project/templates/event/create.html:253
#: project/templates/event/update.html:156 #: project/templates/event/update.html:156
#: project/templates/organizer/create.html:27 #: project/templates/organizer/create.html:27
#: project/templates/organizer/delete.html:13 #: project/templates/organizer/delete.html:13
@ -891,7 +909,7 @@ msgstr ""
msgid "PublicStatus.published" msgid "PublicStatus.published"
msgstr "" msgstr ""
#: project/forms/event.py:402 project/templates/_macros.html:255 #: project/forms/event.py:402 project/templates/_macros.html:257
msgid "PublicStatus.draft" msgid "PublicStatus.draft"
msgstr "" msgstr ""
@ -904,7 +922,7 @@ msgstr ""
msgid "Update event" msgid "Update event"
msgstr "" msgstr ""
#: project/forms/event.py:423 project/templates/_macros.html:1224 #: project/forms/event.py:423 project/templates/_macros.html:1226
#: project/templates/event/actions.html:66 #: project/templates/event/actions.html:66
#: project/templates/event/delete.html:6 #: project/templates/event/delete.html:6
msgid "Delete event" msgid "Delete event"
@ -925,7 +943,7 @@ msgid "Keyword"
msgstr "" msgstr ""
#: project/forms/event.py:436 project/forms/event_date.py:21 #: project/forms/event.py:436 project/forms/event_date.py:21
#: project/forms/planing.py:19 project/templates/_macros.html:369 #: project/forms/planing.py:19 project/templates/_macros.html:371
msgid "Category" msgid "Category"
msgstr "" msgstr ""
@ -934,7 +952,7 @@ msgid "Find events"
msgstr "" msgstr ""
#: project/forms/event_date.py:24 project/forms/planing.py:22 #: project/forms/event_date.py:24 project/forms/planing.py:22
#: project/templates/_macros.html:303 #: project/templates/_macros.html:305
#: project/templates/admin_unit/create.html:38 #: project/templates/admin_unit/create.html:38
#: project/templates/admin_unit/update.html:39 #: project/templates/admin_unit/update.html:39
#: project/templates/event_place/create.html:40 #: project/templates/event_place/create.html:40
@ -1077,7 +1095,7 @@ msgid "Weekdays"
msgstr "" msgstr ""
#: project/forms/reference.py:11 project/forms/reference_request.py:16 #: project/forms/reference.py:11 project/forms/reference_request.py:16
#: project/templates/_macros.html:489 project/templates/_macros.html:652 #: project/templates/_macros.html:491 project/templates/_macros.html:654
#: project/templates/admin_unit/create.html:28 #: project/templates/admin_unit/create.html:28
#: project/templates/admin_unit/update.html:29 #: project/templates/admin_unit/update.html:29
#: project/templates/layout.html:242 #: project/templates/layout.html:242
@ -1105,7 +1123,7 @@ msgstr ""
msgid "Delete request" msgid "Delete request"
msgstr "" msgstr ""
#: project/forms/reference_request.py:28 project/templates/_macros.html:1407 #: project/forms/reference_request.py:28 project/templates/_macros.html:1409
#: project/templates/event_suggestion/review_status.html:18 #: project/templates/event_suggestion/review_status.html:18
#: project/templates/reference_request/review_status.html:12 #: project/templates/reference_request/review_status.html:12
msgid "Review status" msgid "Review status"
@ -1163,43 +1181,53 @@ msgstr ""
msgid "Deny" msgid "Deny"
msgstr "" msgstr ""
#: project/forms/user.py:9 project/templates/admin/admin.html:31
#: project/templates/admin/newsletter.html:4
#: project/templates/admin/newsletter.html:93
msgid "Newsletter"
msgstr ""
#: project/forms/user.py:10
msgid "Information about new features and improvements."
msgstr ""
#: project/forms/widgets.py:154 #: project/forms/widgets.py:154
msgid "This field is required." msgid "This field is required."
msgstr "" msgstr ""
#: project/templates/_macros.html:147 #: project/templates/_macros.html:149
msgid "Show on Google Maps" msgid "Show on Google Maps"
msgstr "" msgstr ""
#: project/templates/_macros.html:226 #: project/templates/_macros.html:228
msgid "Link" msgid "Link"
msgstr "" msgstr ""
#: project/templates/_macros.html:282 #: project/templates/_macros.html:284
msgid "Verified" msgid "Verified"
msgstr "" msgstr ""
#: project/templates/_macros.html:346
#, python-format
msgid "Created at %(created_at)s by %(created_by)s."
msgstr ""
#: project/templates/_macros.html:348 #: project/templates/_macros.html:348
#, python-format #, python-format
msgid "Created at %(created_at)s." msgid "Created at %(created_at)s by %(created_by)s."
msgstr "" msgstr ""
#: project/templates/_macros.html:353 #: project/templates/_macros.html:350
#, python-format #, python-format
msgid "Last updated at %(updated_at)s by %(updated_by)s." msgid "Created at %(created_at)s."
msgstr "" msgstr ""
#: project/templates/_macros.html:355 #: project/templates/_macros.html:355
#, python-format #, python-format
msgid "Last updated at %(updated_at)s by %(updated_by)s."
msgstr ""
#: project/templates/_macros.html:357
#, python-format
msgid "Last updated at %(updated_at)s." msgid "Last updated at %(updated_at)s."
msgstr "" msgstr ""
#: project/templates/_macros.html:385 project/templates/_macros.html:555 #: project/templates/_macros.html:387 project/templates/_macros.html:557
#: project/templates/event/actions.html:25 #: project/templates/event/actions.html:25
#: project/templates/event/create.html:230 #: project/templates/event/create.html:230
#: project/templates/event/update.html:122 #: project/templates/event/update.html:122
@ -1207,63 +1235,63 @@ msgstr ""
msgid "Event" msgid "Event"
msgstr "" msgstr ""
#: project/templates/_macros.html:391 project/templates/_macros.html:920 #: project/templates/_macros.html:393 project/templates/_macros.html:922
msgid "Date" msgid "Date"
msgstr "" msgstr ""
#: project/templates/_macros.html:418 project/templates/_macros.html:577 #: project/templates/_macros.html:420 project/templates/_macros.html:579
#: project/templates/_macros.html:1476 project/templates/event/actions.html:51 #: project/templates/_macros.html:1478 project/templates/event/actions.html:51
msgid "Share" msgid "Share"
msgstr "" msgstr ""
#: project/templates/_macros.html:422 project/templates/_macros.html:581 #: project/templates/_macros.html:424 project/templates/_macros.html:583
#: project/templates/_macros.html:1506 #: project/templates/_macros.html:1508
msgid "Add to calendar" msgid "Add to calendar"
msgstr "" msgstr ""
#: project/templates/_macros.html:430 project/templates/_macros.html:592 #: project/templates/_macros.html:432 project/templates/_macros.html:594
#: project/templates/event/report.html:4 #: project/templates/event/report.html:4
msgid "Report event" msgid "Report event"
msgstr "" msgstr ""
#: project/templates/_macros.html:457 project/templates/_macros.html:618 #: project/templates/_macros.html:459 project/templates/_macros.html:620
msgid "Show directions" msgid "Show directions"
msgstr "" msgstr ""
#: project/templates/_macros.html:462 project/templates/_macros.html:623 #: project/templates/_macros.html:464 project/templates/_macros.html:625
msgid "The event takes place online." msgid "The event takes place online."
msgstr "" msgstr ""
#: project/templates/_macros.html:464 project/templates/_macros.html:625 #: project/templates/_macros.html:466 project/templates/_macros.html:627
msgid "The event takes place both offline and online." msgid "The event takes place both offline and online."
msgstr "" msgstr ""
#: project/templates/_macros.html:585 project/templates/layout.html:168 #: project/templates/_macros.html:587 project/templates/layout.html:168
#: project/templates/user/favorite_events.html:4 #: project/templates/user/favorite_events.html:4
msgid "Favorite events" msgid "Favorite events"
msgstr "" msgstr ""
#: project/templates/_macros.html:679 project/templates/event_date/list.html:5 #: project/templates/_macros.html:681 project/templates/event_date/list.html:5
#: project/templates/event_date/list.html:299 #: project/templates/event_date/list.html:299
#: project/templates/reference_request/review.html:32 #: project/templates/reference_request/review.html:32
msgid "Event Dates" msgid "Event Dates"
msgstr "" msgstr ""
#: project/templates/_macros.html:771 #: project/templates/_macros.html:773
msgid "Search location on Google" msgid "Search location on Google"
msgstr "" msgstr ""
#: project/templates/_macros.html:837 #: project/templates/_macros.html:839
#, python-format #, python-format
msgid "%(count)d event dates" msgid "%(count)d event dates"
msgstr "" msgstr ""
#: project/templates/_macros.html:860 project/templates/_macros.html:862 #: project/templates/_macros.html:862 project/templates/_macros.html:864
#: project/templates/event_date/list.html:321 #: project/templates/event_date/list.html:321
msgid "First" msgid "First"
msgstr "" msgstr ""
#: project/templates/_macros.html:865 project/templates/_macros.html:867 #: project/templates/_macros.html:867 project/templates/_macros.html:869
#: project/templates/event_date/list.html:322 #: project/templates/event_date/list.html:322
#: project/templates/widget/event_suggestion/create.html:193 #: project/templates/widget/event_suggestion/create.html:193
#: project/templates/widget/event_suggestion/create.html:218 #: project/templates/widget/event_suggestion/create.html:218
@ -1274,12 +1302,12 @@ msgstr ""
msgid "Previous" msgid "Previous"
msgstr "" msgstr ""
#: project/templates/_macros.html:869 #: project/templates/_macros.html:871
#, python-format #, python-format
msgid "Page %(page)d of %(pages)d (%(total)d total)" msgid "Page %(page)d of %(pages)d (%(total)d total)"
msgstr "" msgstr ""
#: project/templates/_macros.html:871 project/templates/_macros.html:873 #: project/templates/_macros.html:873 project/templates/_macros.html:875
#: project/templates/event_date/list.html:324 #: project/templates/event_date/list.html:324
#: project/templates/widget/event_suggestion/create.html:194 #: project/templates/widget/event_suggestion/create.html:194
#: project/templates/widget/event_suggestion/create.html:219 #: project/templates/widget/event_suggestion/create.html:219
@ -1289,88 +1317,88 @@ msgstr ""
msgid "Next" msgid "Next"
msgstr "" msgstr ""
#: project/templates/_macros.html:876 project/templates/_macros.html:878 #: project/templates/_macros.html:878 project/templates/_macros.html:880
#: project/templates/event_date/list.html:325 #: project/templates/event_date/list.html:325
msgid "Last" msgid "Last"
msgstr "" msgstr ""
#: project/templates/_macros.html:943 #: project/templates/_macros.html:945
msgid "Radius" msgid "Radius"
msgstr "" msgstr ""
#: project/templates/_macros.html:1153 #: project/templates/_macros.html:1155
msgid "Edit image" msgid "Edit image"
msgstr "" msgstr ""
#: project/templates/_macros.html:1174 #: project/templates/_macros.html:1176
msgid "Close" msgid "Close"
msgstr "" msgstr ""
#: project/templates/_macros.html:1175 #: project/templates/_macros.html:1177
msgid "Okay" msgid "Okay"
msgstr "" msgstr ""
#: project/templates/_macros.html:1187 #: project/templates/_macros.html:1189
msgid "Choose image file" msgid "Choose image file"
msgstr "" msgstr ""
#: project/templates/_macros.html:1223 project/templates/event/actions.html:65 #: project/templates/_macros.html:1225 project/templates/event/actions.html:65
#: project/templates/event/delete.html:12 #: project/templates/event/delete.html:12
msgid "Edit event" msgid "Edit event"
msgstr "" msgstr ""
#: project/templates/_macros.html:1226 project/templates/manage/events.html:66 #: project/templates/_macros.html:1228 project/templates/manage/events.html:66
msgid "More" msgid "More"
msgstr "" msgstr ""
#: project/templates/_macros.html:1273 #: project/templates/_macros.html:1275
msgid "Please enter a valid time, between 00:00 and 23:59." msgid "Please enter a valid time, between 00:00 and 23:59."
msgstr "" msgstr ""
#: project/templates/_macros.html:1301 #: project/templates/_macros.html:1303
#, python-format #, python-format
msgid "Just use %(term)s" msgid "Just use %(term)s"
msgstr "" msgstr ""
#: project/templates/_macros.html:1367 #: project/templates/_macros.html:1369
msgid "Event suggestion" msgid "Event suggestion"
msgstr "" msgstr ""
#: project/templates/_macros.html:1485 #: project/templates/_macros.html:1487
msgid "Link copied" msgid "Link copied"
msgstr "" msgstr ""
#: project/templates/_macros.html:1485 #: project/templates/_macros.html:1487
msgid "Copy link" msgid "Copy link"
msgstr "" msgstr ""
#: project/templates/_macros.html:1514 #: project/templates/_macros.html:1516
msgid "Google calendar" msgid "Google calendar"
msgstr "" msgstr ""
#: project/templates/_macros.html:1515 #: project/templates/_macros.html:1517
msgid "Apple calendar" msgid "Apple calendar"
msgstr "" msgstr ""
#: project/templates/_macros.html:1516 #: project/templates/_macros.html:1518
msgid "Yahoo calendar" msgid "Yahoo calendar"
msgstr "" msgstr ""
#: project/templates/_macros.html:1517 #: project/templates/_macros.html:1519
msgid "Other calendar" msgid "Other calendar"
msgstr "" msgstr ""
#: project/templates/_macros.html:1712 #: project/templates/_macros.html:1714
msgid "Remove event date" msgid "Remove event date"
msgstr "" msgstr ""
#: project/templates/_macros.html:1741 project/templates/event/create.html:176 #: project/templates/_macros.html:1743 project/templates/event/create.html:176
#: project/templates/event/update.html:99 #: project/templates/event/update.html:99
#: project/templates/widget/event_suggestion/create.html:129 #: project/templates/widget/event_suggestion/create.html:129
msgid "Enter organizer" msgid "Enter organizer"
msgstr "" msgstr ""
#: project/templates/_macros.html:1765 #: project/templates/_macros.html:1767
msgid "Enter list name" msgid "Enter list name"
msgstr "" msgstr ""
@ -1414,6 +1442,7 @@ msgstr ""
#: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9 #: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9
#: project/templates/admin/admin_units.html:10 #: project/templates/admin/admin_units.html:10
#: project/templates/admin/email.html:65 #: project/templates/admin/email.html:65
#: project/templates/admin/newsletter.html:92
#: project/templates/admin/settings.html:10 #: project/templates/admin/settings.html:10
#: project/templates/admin/users.html:10 project/templates/layout.html:171 #: project/templates/admin/users.html:10 project/templates/layout.html:171
msgid "Admin" msgid "Admin"
@ -1501,8 +1530,7 @@ msgstr ""
msgid "Organization invitations" msgid "Organization invitations"
msgstr "" msgstr ""
#: project/templates/admin/admin.html:15 project/templates/admin/email.html:4 #: project/templates/admin/admin.html:15
#: project/templates/admin/email.html:66
#: project/templates/admin/settings.html:4 #: project/templates/admin/settings.html:4
#: project/templates/admin/settings.html:11 #: project/templates/admin/settings.html:11
#: project/templates/admin_unit/update.html:6 #: project/templates/admin_unit/update.html:6
@ -1528,18 +1556,24 @@ msgid "Switch organization"
msgstr "" msgstr ""
#: project/templates/developer/read.html:4 project/templates/layout.html:310 #: project/templates/developer/read.html:4 project/templates/layout.html:310
#: project/templates/profile.html:29 #: project/templates/profile.html:33
msgid "Developer" msgid "Developer"
msgstr "" msgstr ""
#: project/templates/profile.html:23 #: project/templates/profile.html:23
#: project/templates/user/notifications.html:4
#: project/templates/user/notifications.html:8
msgid "Notifications"
msgstr ""
#: project/templates/profile.html:27
msgid "Applications" msgid "Applications"
msgstr "" msgstr ""
#: project/templates/oauth2_client/list.html:4 #: project/templates/oauth2_client/list.html:4
#: project/templates/oauth2_client/list.html:11 #: project/templates/oauth2_client/list.html:11
#: project/templates/oauth2_client/read.html:11 #: project/templates/oauth2_client/read.html:11
#: project/templates/profile.html:33 #: project/templates/profile.html:37
msgid "OAuth2 clients" msgid "OAuth2 clients"
msgstr "" msgstr ""
@ -1560,7 +1594,7 @@ msgstr ""
msgid "Edit" msgid "Edit"
msgstr "" msgstr ""
#: project/templates/admin/email.html:47 project/views/admin.py:119 #: project/templates/admin/email.html:47 project/views/admin.py:122
msgid "Mail sent successfully" msgid "Mail sent successfully"
msgstr "" msgstr ""
@ -1572,6 +1606,10 @@ msgstr ""
msgid "Send test mail asynchronously" msgid "Send test mail asynchronously"
msgstr "" msgstr ""
#: project/templates/admin/newsletter.html:59
msgid "Mails sent successfully"
msgstr ""
#: project/templates/admin_unit/create.html:58 #: project/templates/admin_unit/create.html:58
#: project/templates/admin_unit/update.html:59 #: project/templates/admin_unit/update.html:59
#: project/templates/event/create.html:347 #: project/templates/event/create.html:347
@ -1626,6 +1664,10 @@ msgstr ""
msgid "this is a message from %(site_name)s." msgid "this is a message from %(site_name)s."
msgstr "" msgstr ""
#: project/templates/email/newsletter.html:7
msgid "Notification settings"
msgstr ""
#: project/templates/email/organization_invitation_accepted_notice.html:4 #: project/templates/email/organization_invitation_accepted_notice.html:4
#, python-format #, python-format
msgid "" msgid ""
@ -2035,20 +2077,26 @@ msgstr ""
msgid "Preview" msgid "Preview"
msgstr "" msgstr ""
#: project/views/admin.py:55 #: project/views/admin.py:58
msgid "Organization successfully updated" msgid "Organization successfully updated"
msgstr "" msgstr ""
#: project/views/admin.py:79 project/views/manage.py:361 #: project/views/admin.py:82 project/views/manage.py:361
#: project/views/user.py:27
msgid "Settings successfully updated" msgid "Settings successfully updated"
msgstr "" msgstr ""
#: project/views/admin.py:108 #: project/views/admin.py:111
#, python-format #, python-format
msgid "Test mail from %(site_name)s" msgid "Test mail from %(site_name)s"
msgstr "" msgstr ""
#: project/views/admin.py:152 #: project/views/admin.py:150
#, python-format
msgid "Newsletter from %(site_name)s"
msgstr ""
#: project/views/admin.py:200
msgid "User successfully updated" msgid "User successfully updated"
msgstr "" msgstr ""

View File

@ -0,0 +1,31 @@
"""empty message
Revision ID: 47c334ba5b86
Revises: 3f77c8693ae3
Create Date: 2023-03-26 23:03:44.678745
"""
import sqlalchemy as sa
import sqlalchemy_utils
from alembic import op
from project import dbtypes
# revision identifiers, used by Alembic.
revision = "47c334ba5b86"
down_revision = "3f77c8693ae3"
branch_labels = None
depends_on = None
def upgrade():
op.add_column(
"user",
sa.Column(
"newsletter_enabled", sa.Boolean(), server_default="1", nullable=False
),
)
def downgrade():
op.drop_column("user", "newsletter_enabled")

View File

@ -7,6 +7,6 @@ from project.views.utils import send_mail
base=getattr(app, "celery_http_task_cls"), base=getattr(app, "celery_http_task_cls"),
priority=0, priority=0,
) )
def send_mail_task(recipient, subject, template): def send_mail_task(recipient, subject, template, **context):
with force_locale(): with force_locale():
send_mail(recipient, subject, template) send_mail(recipient, subject, template, **context)

View File

@ -1,6 +1,6 @@
from flask_babelex import lazy_gettext from flask_babelex import lazy_gettext
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import BooleanField, SubmitField, TextAreaField from wtforms import BooleanField, RadioField, SubmitField, TextAreaField
from wtforms.fields.html5 import EmailField from wtforms.fields.html5 import EmailField
from wtforms.validators import DataRequired, Optional from wtforms.validators import DataRequired, Optional
@ -63,3 +63,18 @@ class AdminTestEmailForm(FlaskForm):
recipient = EmailField(lazy_gettext("Recipient"), validators=[DataRequired()]) recipient = EmailField(lazy_gettext("Recipient"), validators=[DataRequired()])
submit = SubmitField(lazy_gettext("Send test mail synchronously")) submit = SubmitField(lazy_gettext("Send test mail synchronously"))
class AdminNewsletterForm(FlaskForm):
recipient_choice = RadioField(
lazy_gettext("Recipient"),
choices=[
(1, lazy_gettext("Test recipient")),
(2, lazy_gettext("All users with enabled newsletter setting")),
],
default=1,
coerce=int,
)
test_recipient = EmailField(lazy_gettext("Test recipient"), validators=[Optional()])
message = TextAreaField(lazy_gettext("Message"), validators=[DataRequired()])
submit = SubmitField(lazy_gettext("Send newsletter"))

13
project/forms/user.py Normal file
View File

@ -0,0 +1,13 @@
from flask_babelex import lazy_gettext
from flask_wtf import FlaskForm
from wtforms import BooleanField, SubmitField
from wtforms.validators import Optional
class NotificationForm(FlaskForm):
newsletter_enabled = BooleanField(
lazy_gettext("Newsletter"),
description=lazy_gettext("Information about new features and improvements."),
validators=[Optional()],
)
submit = SubmitField(lazy_gettext("Save"))

View File

@ -199,6 +199,14 @@ class User(db.Model, UserMixin):
secondary="user_favoriteevents", secondary="user_favoriteevents",
backref=backref("favored_by_users", lazy=True), backref=backref("favored_by_users", lazy=True),
) )
newsletter_enabled = deferred(
Column(
Boolean(),
nullable=True,
default=True,
server_default="1",
)
)
def get_user_id(self): def get_user_id(self):
return self.id return self.id

View File

@ -70,6 +70,8 @@
</label> </label>
{% endfor %} {% endfor %}
</div> </div>
{% elif 'ri' in kwargs and kwargs['ri'] == 'radio' %}
{{ render_radio_buttons(field) }}
{% else %} {% else %}
{% if 'class' in kwargs %} {% if 'class' in kwargs %}
{% set _dummy=kwargs.pop('class') %} {% set _dummy=kwargs.pop('class') %}

View File

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

View File

@ -1,7 +1,7 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% from "_macros.html" import render_field, render_field_with_errors %} {% from "_macros.html" import render_field, render_field_with_errors %}
{%- block title -%} {%- block title -%}
{{ _('Settings') }} {{ _('Email') }}
{%- endblock -%} {%- endblock -%}
{% block header %} {% block header %}
<script> <script>
@ -63,7 +63,7 @@
<nav aria-label="breadcrumb"> <nav aria-label="breadcrumb">
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ url_for('admin') }}">{{ _('Admin') }}</a></li> <li class="breadcrumb-item"><a href="{{ url_for('admin') }}">{{ _('Admin') }}</a></li>
<li class="breadcrumb-item active" aria-current="page">{{ _('Settings') }}</li> <li class="breadcrumb-item active" aria-current="page">{{ _('Email') }}</li>
</ol> </ol>
</nav> </nav>

View File

@ -0,0 +1,123 @@
{% extends "layout.html" %}
{% from "_macros.html" import render_field, render_field_with_errors, render_radio_buttons %}
{%- block title -%}
{{ _('Newsletter') }}
{%- endblock -%}
{% block header %}
<script>
function update_progress_bar(completed, count, progressbar_id='#progressbar') {
var progress = count > 0 ? Math.round((completed/count)*100) : 0;
console.log('' + progress + '%');
var progressbar = $(progressbar_id);
progressbar.css('width', '' + progress + '%');
progressbar.attr("ariaValueNow", progress);
progressbar.html("" + progress + '%');
}
function submit_async() {
update_progress_bar(0, 0);
handle_request_start();
$.ajax({
url: "{{ url_for('admin_newsletter', async=1) }}",
type: "post",
dataType: "json",
data: $("#newsletter_form").serialize(),
error: function(xhr, status, error) {
handle_request_error(xhr, status, error);
},
success: function (data) {
poll(data["result_id"]);
}
});
}
function poll(result_id) {
$.ajax({
url: "{{ url_for('admin_newsletter') }}",
type: "get",
dataType: "json",
data: "poll=" + result_id,
error: function(xhr, status, error) {
handle_request_error(xhr, status, error);
},
success: function (data) {
update_progress_bar(data["completed"], data["count"]);
if (!data["ready"]) {
setTimeout(function() {
poll(result_id);
}, 500);
return;
}
if (!data["successful"]) {
console.error(data);
handle_request_error(null, JSON.stringify(data), data);
return;
}
$("#success_message").text("{{ _('Mails sent successfully') }} (" + data["completed"] + ")");
handle_request_success();
}
});
}
$( function() {
$("#newsletter_form").submit(function(e){
e.stopPropagation();
submit_async();
return false;
});
$('label[for=test_recipient]').append(' *');
$('input[name=recipient_choice]').on('change', function() {
switch ($(this).val()) {
case '1':
$('#test_recipient').attr("required", true);
$('#test_recipient_container').show();
break;
case '2':
$('#test_recipient').attr("required", false);
$('#test_recipient_container').hide();
break;
}
});
});
</script>
{% endblock %}
{% block content %}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ url_for('admin') }}">{{ _('Admin') }}</a></li>
<li class="breadcrumb-item active" aria-current="page">{{ _('Newsletter') }}</li>
</ol>
</nav>
<form id="newsletter_form" action="" method="POST">
{{ form.hidden_tag() }}
<div class="my-4">
{{ render_field_with_errors(form.recipient_choice, ri='radio') }}
</div>
<div id="test_recipient_container">
{{ render_field_with_errors(form.test_recipient) }}
</div>
{{ render_field_with_errors(form.message) }}
{{ render_field(form.submit) }}
</form>
<p>
<div id="result_container" style="display: none;">
<div id="success_message" class="alert alert-success"></div>
</div>
<div id="spinner" style="display: none;">
<div class="progress">
<div id="progressbar" class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="alert alert-danger m-3" role="alert" id="error_alert" style="display: none;"></div>
</p>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "email/layout.html" %}
{% block content %}
<p>
{{ message|safe }}
</p>
<p>
<a href="{{ url_for('user_notifications', _external=True) }}" target="_blank" rel="noopener noreferrer">{{ _('Notification settings') }}</a>
</p>
{% endblock %}

View File

@ -0,0 +1,3 @@
{{ message|safe }}
{{ _('Notification settings') }}: {{ url_for('user_notifications', _external=True) }}

View File

@ -19,6 +19,10 @@
<h2>{{ _('Settings') }}</h2> <h2>{{ _('Settings') }}</h2>
<div class="list-group"> <div class="list-group">
<a href="{{ url_for('user_notifications') }}" class="list-group-item">
{{ _('Notifications') }}
<i class="fa fa-caret-right"></i>
</a>
<a href="{{ url_for('oauth2_tokens') }}" class="list-group-item"> <a href="{{ url_for('oauth2_tokens') }}" class="list-group-item">
{{ _('Applications') }} {{ _('Applications') }}
<i class="fa fa-caret-right"></i> <i class="fa fa-caret-right"></i>

View File

@ -0,0 +1,16 @@
{% extends "layout.html" %}
{% from "_macros.html" import render_field_with_errors, render_field %}
{%- block title -%}
{{ _('Notifications') }}
{%- endblock -%}
{% block content %}
<h1>{{ _('Notifications') }}</h1>
<form action="" method="POST">
{{ form.hidden_tag() }}
{{ render_field_with_errors(form.newsletter_enabled, ri="switch") }}
{{ render_field(form.submit) }}
</form>
{% endblock %}

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2023-03-24 21:24+0100\n" "POT-Creation-Date: 2023-03-28 17:04+0200\n"
"PO-Revision-Date: 2020-06-07 18:51+0200\n" "PO-Revision-Date: 2020-06-07 18:51+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: de\n" "Language: de\n"
@ -209,7 +209,7 @@ msgstr "Nutzungsbedingungen"
msgid "Legal notice" msgid "Legal notice"
msgstr "Impressum" msgstr "Impressum"
#: project/forms/admin.py:13 project/templates/_macros.html:1395 #: project/forms/admin.py:13 project/templates/_macros.html:1397
#: project/templates/layout.html:302 #: project/templates/layout.html:302
#: project/templates/widget/event_suggestion/create.html:204 #: project/templates/widget/event_suggestion/create.html:204
#: project/views/admin_unit.py:73 project/views/root.py:69 #: project/views/admin_unit.py:73 project/views/root.py:69
@ -226,6 +226,7 @@ msgid "Start page"
msgstr "Startseite" msgstr "Startseite"
#: project/forms/admin.py:17 project/forms/oauth2_client.py:24 #: project/forms/admin.py:17 project/forms/oauth2_client.py:24
#: project/forms/user.py:13
msgid "Save" msgid "Save"
msgstr "Speichern" msgstr "Speichern"
@ -294,7 +295,7 @@ msgstr ""
msgid "Update organization" msgid "Update organization"
msgstr "Organisation aktualisieren" msgstr "Organisation aktualisieren"
#: project/forms/admin.py:63 #: project/forms/admin.py:63 project/forms/admin.py:70
msgid "Recipient" msgid "Recipient"
msgstr "Empfänger" msgstr "Empfänger"
@ -302,6 +303,22 @@ msgstr "Empfänger"
msgid "Send test mail synchronously" msgid "Send test mail synchronously"
msgstr "Test-Mail synchron senden" msgstr "Test-Mail synchron senden"
#: project/forms/admin.py:72 project/forms/admin.py:78
msgid "Test recipient"
msgstr "Test-Empfänger"
#: project/forms/admin.py:73
msgid "All users with enabled newsletter setting"
msgstr "Alle Nutzer mit aktiviertem Newsletter"
#: project/forms/admin.py:79
msgid "Message"
msgstr "Nachricht"
#: project/forms/admin.py:80
msgid "Send newsletter"
msgstr "Newsletter senden"
#: project/forms/admin_unit.py:15 project/forms/event_place.py:12 #: project/forms/admin_unit.py:15 project/forms/event_place.py:12
#: project/forms/organizer.py:12 #: project/forms/organizer.py:12
msgid "Street" msgid "Street"
@ -354,7 +371,7 @@ msgstr ""
"eindeutig zu identifizieren. Der Kurzname darf nur Buchstaben, Nummern " "eindeutig zu identifizieren. Der Kurzname darf nur Buchstaben, Nummern "
"und Unterstriche enthalten." "und Unterstriche enthalten."
#: project/forms/admin_unit.py:41 project/templates/_macros.html:1531 #: project/forms/admin_unit.py:41 project/templates/_macros.html:1533
msgid "Short name must contain only letters numbers or underscore" msgid "Short name must contain only letters numbers or underscore"
msgstr "Der Kurzname darf nur Buchstaben, Nummern und Unterstriche enthalten" msgstr "Der Kurzname darf nur Buchstaben, Nummern und Unterstriche enthalten"
@ -367,20 +384,21 @@ msgstr "Link URL"
#: project/forms/admin_unit.py:48 project/forms/admin_unit_member.py:11 #: project/forms/admin_unit.py:48 project/forms/admin_unit_member.py:11
#: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28 #: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28
#: project/forms/event.py:107 project/forms/event_suggestion.py:38 #: project/forms/event.py:107 project/forms/event_suggestion.py:38
#: project/forms/organizer.py:27 project/templates/_macros.html:235 #: project/forms/organizer.py:27 project/templates/_macros.html:237
#: project/templates/_macros.html:1491 project/templates/admin/admin.html:27 #: project/templates/_macros.html:1493 project/templates/admin/admin.html:27
#: project/templates/admin/email.html:4 project/templates/admin/email.html:66
#: project/templates/admin/users.html:19 #: project/templates/admin/users.html:19
msgid "Email" msgid "Email"
msgstr "Email" msgstr "Email"
#: project/forms/admin_unit.py:49 project/forms/event.py:108 #: project/forms/admin_unit.py:49 project/forms/event.py:108
#: project/forms/event_suggestion.py:31 project/forms/organizer.py:28 #: project/forms/event_suggestion.py:31 project/forms/organizer.py:28
#: project/templates/_macros.html:288 #: project/templates/_macros.html:290
msgid "Phone" msgid "Phone"
msgstr "Telefon" msgstr "Telefon"
#: project/forms/admin_unit.py:50 project/forms/event.py:109 #: project/forms/admin_unit.py:50 project/forms/event.py:109
#: project/forms/organizer.py:29 project/templates/_macros.html:296 #: project/forms/organizer.py:29 project/templates/_macros.html:298
msgid "Fax" msgid "Fax"
msgstr "Fax" msgstr "Fax"
@ -589,16 +607,16 @@ msgstr "Gib an, wann der Termin endet. Ein Termin darf maximal 14 Tage dauern."
msgid "All-day" msgid "All-day"
msgstr "Ganztägig" msgstr "Ganztägig"
#: project/forms/event.py:54 project/templates/_macros.html:1711 #: project/forms/event.py:54 project/templates/_macros.html:1713
#: project/templates/widget/event_suggestion/create.html:240 #: project/templates/widget/event_suggestion/create.html:240
msgid "Recurring event" msgid "Recurring event"
msgstr "Serientermin" msgstr "Serientermin"
#: project/forms/event.py:61 project/templates/_macros.html:1252 #: project/forms/event.py:61 project/templates/_macros.html:1254
msgid "The start must be before the end." msgid "The start must be before the end."
msgstr "Der Start muss vor dem Ende sein." msgstr "Der Start muss vor dem Ende sein."
#: project/forms/event.py:67 project/templates/_macros.html:1269 #: project/forms/event.py:67 project/templates/_macros.html:1271
msgid "An event can last a maximum of 14 days." msgid "An event can last a maximum of 14 days."
msgstr "Eine Veranstaltung darf maximal 14 Tage dauern." msgstr "Eine Veranstaltung darf maximal 14 Tage dauern."
@ -634,7 +652,7 @@ msgstr "Ticket Link"
msgid "Enter a link where tickets can be purchased." msgid "Enter a link where tickets can be purchased."
msgstr "Gib einen Link ein, über den Tickets gekauft werden können." msgstr "Gib einen Link ein, über den Tickets gekauft werden können."
#: project/forms/event.py:136 project/templates/_macros.html:217 #: project/forms/event.py:136 project/templates/_macros.html:219
msgid "Tags" msgid "Tags"
msgstr "Stichworte" msgstr "Stichworte"
@ -687,7 +705,7 @@ msgstr "Anmeldung erforderlich"
msgid "If the participants needs to register for the event." msgid "If the participants needs to register for the event."
msgstr "Wenn sich die Teilnehmer für die Veranstaltung anmelden müssen." msgstr "Wenn sich die Teilnehmer für die Veranstaltung anmelden müssen."
#: project/forms/event.py:170 project/templates/_macros.html:249 #: project/forms/event.py:170 project/templates/_macros.html:251
#: project/templates/layout.html:110 #: project/templates/layout.html:110
msgid "Booked up" msgid "Booked up"
msgstr "Ausgebucht" msgstr "Ausgebucht"
@ -773,8 +791,8 @@ msgstr ""
"Wir empfehlen dir, ein Foto für die Veranstaltung hochzuladen. Es macht " "Wir empfehlen dir, ein Foto für die Veranstaltung hochzuladen. Es macht "
"schon deutlich mehr her, aber es geht natürlich auch ohne." "schon deutlich mehr her, aber es geht natürlich auch ohne."
#: project/forms/event.py:242 project/templates/_macros.html:396 #: project/forms/event.py:242 project/templates/_macros.html:398
#: project/templates/_macros.html:559 #: project/templates/_macros.html:561
msgid "Previous start date" msgid "Previous start date"
msgstr "Vorheriges Startdatum" msgstr "Vorheriges Startdatum"
@ -826,7 +844,7 @@ msgstr "Ungültiger Mitveranstalter."
#: project/forms/event.py:286 project/forms/event.py:295 #: project/forms/event.py:286 project/forms/event.py:295
#: project/forms/event.py:368 project/forms/event_suggestion.py:50 #: project/forms/event.py:368 project/forms/event_suggestion.py:50
#: project/templates/_macros.html:436 project/templates/_macros.html:599 #: project/templates/_macros.html:438 project/templates/_macros.html:601
#: project/templates/event/create.html:284 #: project/templates/event/create.html:284
#: project/templates/event/update.html:166 #: project/templates/event/update.html:166
#: project/templates/event_place/create.html:31 #: project/templates/event_place/create.html:31
@ -845,8 +863,8 @@ msgstr "Neuen Ort eingeben"
#: project/forms/event.py:302 project/forms/event.py:311 #: project/forms/event.py:302 project/forms/event.py:311
#: project/forms/event.py:376 project/forms/event.py:439 #: project/forms/event.py:376 project/forms/event.py:439
#: project/forms/event_suggestion.py:60 project/templates/_macros.html:473 #: project/forms/event_suggestion.py:60 project/templates/_macros.html:475
#: project/templates/_macros.html:636 project/templates/event/create.html:253 #: project/templates/_macros.html:638 project/templates/event/create.html:253
#: project/templates/event/update.html:156 #: project/templates/event/update.html:156
#: project/templates/organizer/create.html:27 #: project/templates/organizer/create.html:27
#: project/templates/organizer/delete.html:13 #: project/templates/organizer/delete.html:13
@ -935,7 +953,7 @@ msgstr "Öffentlicher Status"
msgid "PublicStatus.published" msgid "PublicStatus.published"
msgstr "Veröffentlicht" msgstr "Veröffentlicht"
#: project/forms/event.py:402 project/templates/_macros.html:255 #: project/forms/event.py:402 project/templates/_macros.html:257
msgid "PublicStatus.draft" msgid "PublicStatus.draft"
msgstr "Entwurf" msgstr "Entwurf"
@ -948,7 +966,7 @@ msgstr "Wähle den öffentlichen Status der Veranstaltung."
msgid "Update event" msgid "Update event"
msgstr "Veranstaltung aktualisieren" msgstr "Veranstaltung aktualisieren"
#: project/forms/event.py:423 project/templates/_macros.html:1224 #: project/forms/event.py:423 project/templates/_macros.html:1226
#: project/templates/event/actions.html:66 #: project/templates/event/actions.html:66
#: project/templates/event/delete.html:6 #: project/templates/event/delete.html:6
msgid "Delete event" msgid "Delete event"
@ -969,7 +987,7 @@ msgid "Keyword"
msgstr "Stichwort" msgstr "Stichwort"
#: project/forms/event.py:436 project/forms/event_date.py:21 #: project/forms/event.py:436 project/forms/event_date.py:21
#: project/forms/planing.py:19 project/templates/_macros.html:369 #: project/forms/planing.py:19 project/templates/_macros.html:371
msgid "Category" msgid "Category"
msgstr "Kategorie" msgstr "Kategorie"
@ -978,7 +996,7 @@ msgid "Find events"
msgstr "Veranstaltungen finden" msgstr "Veranstaltungen finden"
#: project/forms/event_date.py:24 project/forms/planing.py:22 #: project/forms/event_date.py:24 project/forms/planing.py:22
#: project/templates/_macros.html:303 #: project/templates/_macros.html:305
#: project/templates/admin_unit/create.html:38 #: project/templates/admin_unit/create.html:38
#: project/templates/admin_unit/update.html:39 #: project/templates/admin_unit/update.html:39
#: project/templates/event_place/create.html:40 #: project/templates/event_place/create.html:40
@ -1125,7 +1143,7 @@ msgid "Weekdays"
msgstr "Wochentage" msgstr "Wochentage"
#: project/forms/reference.py:11 project/forms/reference_request.py:16 #: project/forms/reference.py:11 project/forms/reference_request.py:16
#: project/templates/_macros.html:489 project/templates/_macros.html:652 #: project/templates/_macros.html:491 project/templates/_macros.html:654
#: project/templates/admin_unit/create.html:28 #: project/templates/admin_unit/create.html:28
#: project/templates/admin_unit/update.html:29 #: project/templates/admin_unit/update.html:29
#: project/templates/layout.html:242 #: project/templates/layout.html:242
@ -1153,7 +1171,7 @@ msgstr "Anfrage speichern"
msgid "Delete request" msgid "Delete request"
msgstr "Anfrage löschen" msgstr "Anfrage löschen"
#: project/forms/reference_request.py:28 project/templates/_macros.html:1407 #: project/forms/reference_request.py:28 project/templates/_macros.html:1409
#: project/templates/event_suggestion/review_status.html:18 #: project/templates/event_suggestion/review_status.html:18
#: project/templates/reference_request/review_status.html:12 #: project/templates/reference_request/review_status.html:12
msgid "Review status" msgid "Review status"
@ -1211,43 +1229,53 @@ msgstr "Erlauben"
msgid "Deny" msgid "Deny"
msgstr "Ablehnen" msgstr "Ablehnen"
#: project/forms/user.py:9 project/templates/admin/admin.html:31
#: project/templates/admin/newsletter.html:4
#: project/templates/admin/newsletter.html:93
msgid "Newsletter"
msgstr "Newsletter"
#: project/forms/user.py:10
msgid "Information about new features and improvements."
msgstr "Informationen über neue Features und Verbesserungen."
#: project/forms/widgets.py:154 #: project/forms/widgets.py:154
msgid "This field is required." msgid "This field is required."
msgstr "Dieses Feld ist erforderlich." msgstr "Dieses Feld ist erforderlich."
#: project/templates/_macros.html:147 #: project/templates/_macros.html:149
msgid "Show on Google Maps" msgid "Show on Google Maps"
msgstr "Auf Google Maps anzeigen" msgstr "Auf Google Maps anzeigen"
#: project/templates/_macros.html:226 #: project/templates/_macros.html:228
msgid "Link" msgid "Link"
msgstr "Link" msgstr "Link"
#: project/templates/_macros.html:282 #: project/templates/_macros.html:284
msgid "Verified" msgid "Verified"
msgstr "Verifiziert" msgstr "Verifiziert"
#: project/templates/_macros.html:346 #: project/templates/_macros.html:348
#, python-format #, python-format
msgid "Created at %(created_at)s by %(created_by)s." msgid "Created at %(created_at)s by %(created_by)s."
msgstr "Erstellt am %(created_at)s von %(created_by)s." msgstr "Erstellt am %(created_at)s von %(created_by)s."
#: project/templates/_macros.html:348 #: project/templates/_macros.html:350
#, python-format #, python-format
msgid "Created at %(created_at)s." msgid "Created at %(created_at)s."
msgstr "Erstellt am %(created_at)s." msgstr "Erstellt am %(created_at)s."
#: project/templates/_macros.html:353 #: project/templates/_macros.html:355
#, python-format #, python-format
msgid "Last updated at %(updated_at)s by %(updated_by)s." msgid "Last updated at %(updated_at)s by %(updated_by)s."
msgstr "Zuletzt aktualisiert am %(updated_at)s von %(updated_by)s." msgstr "Zuletzt aktualisiert am %(updated_at)s von %(updated_by)s."
#: project/templates/_macros.html:355 #: project/templates/_macros.html:357
#, python-format #, python-format
msgid "Last updated at %(updated_at)s." msgid "Last updated at %(updated_at)s."
msgstr "Zuletzt aktualisiert am %(updated_at)s." msgstr "Zuletzt aktualisiert am %(updated_at)s."
#: project/templates/_macros.html:385 project/templates/_macros.html:555 #: project/templates/_macros.html:387 project/templates/_macros.html:557
#: project/templates/event/actions.html:25 #: project/templates/event/actions.html:25
#: project/templates/event/create.html:230 #: project/templates/event/create.html:230
#: project/templates/event/update.html:122 #: project/templates/event/update.html:122
@ -1255,65 +1283,65 @@ msgstr "Zuletzt aktualisiert am %(updated_at)s."
msgid "Event" msgid "Event"
msgstr "Veranstaltung" msgstr "Veranstaltung"
#: project/templates/_macros.html:391 project/templates/_macros.html:920 #: project/templates/_macros.html:393 project/templates/_macros.html:922
msgid "Date" msgid "Date"
msgstr "Datum" msgstr "Datum"
#: project/templates/_macros.html:418 project/templates/_macros.html:577 #: project/templates/_macros.html:420 project/templates/_macros.html:579
#: project/templates/_macros.html:1476 project/templates/event/actions.html:51 #: project/templates/_macros.html:1478 project/templates/event/actions.html:51
msgid "Share" msgid "Share"
msgstr "Teilen" msgstr "Teilen"
#: project/templates/_macros.html:422 project/templates/_macros.html:581 #: project/templates/_macros.html:424 project/templates/_macros.html:583
#: project/templates/_macros.html:1506 #: project/templates/_macros.html:1508
msgid "Add to calendar" msgid "Add to calendar"
msgstr "Zum Kalender" msgstr "Zum Kalender"
#: project/templates/_macros.html:430 project/templates/_macros.html:592 #: project/templates/_macros.html:432 project/templates/_macros.html:594
#: project/templates/event/report.html:4 #: project/templates/event/report.html:4
msgid "Report event" msgid "Report event"
msgstr "Veranstaltung melden" msgstr "Veranstaltung melden"
#: project/templates/_macros.html:457 project/templates/_macros.html:618 #: project/templates/_macros.html:459 project/templates/_macros.html:620
msgid "Show directions" msgid "Show directions"
msgstr "Anreise planen" msgstr "Anreise planen"
#: project/templates/_macros.html:462 project/templates/_macros.html:623 #: project/templates/_macros.html:464 project/templates/_macros.html:625
msgid "The event takes place online." msgid "The event takes place online."
msgstr "Die Veranstaltung findet online statt." msgstr "Die Veranstaltung findet online statt."
#: project/templates/_macros.html:464 project/templates/_macros.html:625 #: project/templates/_macros.html:466 project/templates/_macros.html:627
msgid "The event takes place both offline and online." msgid "The event takes place both offline and online."
msgstr "" msgstr ""
"Die Veranstaltung findet sowohl als Präsenzveranstaltung als auch online " "Die Veranstaltung findet sowohl als Präsenzveranstaltung als auch online "
"statt." "statt."
#: project/templates/_macros.html:585 project/templates/layout.html:168 #: project/templates/_macros.html:587 project/templates/layout.html:168
#: project/templates/user/favorite_events.html:4 #: project/templates/user/favorite_events.html:4
msgid "Favorite events" msgid "Favorite events"
msgstr "Merkzettel" msgstr "Merkzettel"
#: project/templates/_macros.html:679 project/templates/event_date/list.html:5 #: project/templates/_macros.html:681 project/templates/event_date/list.html:5
#: project/templates/event_date/list.html:299 #: project/templates/event_date/list.html:299
#: project/templates/reference_request/review.html:32 #: project/templates/reference_request/review.html:32
msgid "Event Dates" msgid "Event Dates"
msgstr "Termine" msgstr "Termine"
#: project/templates/_macros.html:771 #: project/templates/_macros.html:773
msgid "Search location on Google" msgid "Search location on Google"
msgstr "Ort bei Google suchen" msgstr "Ort bei Google suchen"
#: project/templates/_macros.html:837 #: project/templates/_macros.html:839
#, python-format #, python-format
msgid "%(count)d event dates" msgid "%(count)d event dates"
msgstr "%(count)d Termine" msgstr "%(count)d Termine"
#: project/templates/_macros.html:860 project/templates/_macros.html:862 #: project/templates/_macros.html:862 project/templates/_macros.html:864
#: project/templates/event_date/list.html:321 #: project/templates/event_date/list.html:321
msgid "First" msgid "First"
msgstr "Letzte" msgstr "Letzte"
#: project/templates/_macros.html:865 project/templates/_macros.html:867 #: project/templates/_macros.html:867 project/templates/_macros.html:869
#: project/templates/event_date/list.html:322 #: project/templates/event_date/list.html:322
#: project/templates/widget/event_suggestion/create.html:193 #: project/templates/widget/event_suggestion/create.html:193
#: project/templates/widget/event_suggestion/create.html:218 #: project/templates/widget/event_suggestion/create.html:218
@ -1324,12 +1352,12 @@ msgstr "Letzte"
msgid "Previous" msgid "Previous"
msgstr "Zurück" msgstr "Zurück"
#: project/templates/_macros.html:869 #: project/templates/_macros.html:871
#, python-format #, python-format
msgid "Page %(page)d of %(pages)d (%(total)d total)" msgid "Page %(page)d of %(pages)d (%(total)d total)"
msgstr "Seite %(page)d von %(pages)d (%(total)d insgesamt)" msgstr "Seite %(page)d von %(pages)d (%(total)d insgesamt)"
#: project/templates/_macros.html:871 project/templates/_macros.html:873 #: project/templates/_macros.html:873 project/templates/_macros.html:875
#: project/templates/event_date/list.html:324 #: project/templates/event_date/list.html:324
#: project/templates/widget/event_suggestion/create.html:194 #: project/templates/widget/event_suggestion/create.html:194
#: project/templates/widget/event_suggestion/create.html:219 #: project/templates/widget/event_suggestion/create.html:219
@ -1339,88 +1367,88 @@ msgstr "Seite %(page)d von %(pages)d (%(total)d insgesamt)"
msgid "Next" msgid "Next"
msgstr "Weiter" msgstr "Weiter"
#: project/templates/_macros.html:876 project/templates/_macros.html:878 #: project/templates/_macros.html:878 project/templates/_macros.html:880
#: project/templates/event_date/list.html:325 #: project/templates/event_date/list.html:325
msgid "Last" msgid "Last"
msgstr "Erste" msgstr "Erste"
#: project/templates/_macros.html:943 #: project/templates/_macros.html:945
msgid "Radius" msgid "Radius"
msgstr "Umkreis" msgstr "Umkreis"
#: project/templates/_macros.html:1153 #: project/templates/_macros.html:1155
msgid "Edit image" msgid "Edit image"
msgstr "Bild bearbeiten" msgstr "Bild bearbeiten"
#: project/templates/_macros.html:1174 #: project/templates/_macros.html:1176
msgid "Close" msgid "Close"
msgstr "Schließen" msgstr "Schließen"
#: project/templates/_macros.html:1175 #: project/templates/_macros.html:1177
msgid "Okay" msgid "Okay"
msgstr "OK" msgstr "OK"
#: project/templates/_macros.html:1187 #: project/templates/_macros.html:1189
msgid "Choose image file" msgid "Choose image file"
msgstr "Bild-Datei auswählen" msgstr "Bild-Datei auswählen"
#: project/templates/_macros.html:1223 project/templates/event/actions.html:65 #: project/templates/_macros.html:1225 project/templates/event/actions.html:65
#: project/templates/event/delete.html:12 #: project/templates/event/delete.html:12
msgid "Edit event" msgid "Edit event"
msgstr "Veranstaltung bearbeiten" msgstr "Veranstaltung bearbeiten"
#: project/templates/_macros.html:1226 project/templates/manage/events.html:66 #: project/templates/_macros.html:1228 project/templates/manage/events.html:66
msgid "More" msgid "More"
msgstr "Mehr" msgstr "Mehr"
#: project/templates/_macros.html:1273 #: project/templates/_macros.html:1275
msgid "Please enter a valid time, between 00:00 and 23:59." 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." msgstr "Bitte gib eine gültige Uhrzeit zwischen 00:00 und 23:59 ein."
#: project/templates/_macros.html:1301 #: project/templates/_macros.html:1303
#, python-format #, python-format
msgid "Just use %(term)s" msgid "Just use %(term)s"
msgstr "Verwende einfach %(term)s" msgstr "Verwende einfach %(term)s"
#: project/templates/_macros.html:1367 #: project/templates/_macros.html:1369
msgid "Event suggestion" msgid "Event suggestion"
msgstr "Veranstaltungsvorschlag" msgstr "Veranstaltungsvorschlag"
#: project/templates/_macros.html:1485 #: project/templates/_macros.html:1487
msgid "Link copied" msgid "Link copied"
msgstr "Link kopiert" msgstr "Link kopiert"
#: project/templates/_macros.html:1485 #: project/templates/_macros.html:1487
msgid "Copy link" msgid "Copy link"
msgstr "Link kopieren" msgstr "Link kopieren"
#: project/templates/_macros.html:1514 #: project/templates/_macros.html:1516
msgid "Google calendar" msgid "Google calendar"
msgstr "Google Kalender" msgstr "Google Kalender"
#: project/templates/_macros.html:1515 #: project/templates/_macros.html:1517
msgid "Apple calendar" msgid "Apple calendar"
msgstr "Apple Kalender" msgstr "Apple Kalender"
#: project/templates/_macros.html:1516 #: project/templates/_macros.html:1518
msgid "Yahoo calendar" msgid "Yahoo calendar"
msgstr "Yahoo Kalender" msgstr "Yahoo Kalender"
#: project/templates/_macros.html:1517 #: project/templates/_macros.html:1519
msgid "Other calendar" msgid "Other calendar"
msgstr "Anderer Kalender" msgstr "Anderer Kalender"
#: project/templates/_macros.html:1712 #: project/templates/_macros.html:1714
msgid "Remove event date" msgid "Remove event date"
msgstr "Termin entfernen" msgstr "Termin entfernen"
#: project/templates/_macros.html:1741 project/templates/event/create.html:176 #: project/templates/_macros.html:1743 project/templates/event/create.html:176
#: project/templates/event/update.html:99 #: project/templates/event/update.html:99
#: project/templates/widget/event_suggestion/create.html:129 #: project/templates/widget/event_suggestion/create.html:129
msgid "Enter organizer" msgid "Enter organizer"
msgstr "Veranstalter eingeben" msgstr "Veranstalter eingeben"
#: project/templates/_macros.html:1765 #: project/templates/_macros.html:1767
msgid "Enter list name" msgid "Enter list name"
msgstr "Listenname eingeben" msgstr "Listenname eingeben"
@ -1464,6 +1492,7 @@ msgstr "Profil"
#: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9 #: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9
#: project/templates/admin/admin_units.html:10 #: project/templates/admin/admin_units.html:10
#: project/templates/admin/email.html:65 #: project/templates/admin/email.html:65
#: project/templates/admin/newsletter.html:92
#: project/templates/admin/settings.html:10 #: project/templates/admin/settings.html:10
#: project/templates/admin/users.html:10 project/templates/layout.html:171 #: project/templates/admin/users.html:10 project/templates/layout.html:171
msgid "Admin" msgid "Admin"
@ -1551,8 +1580,7 @@ msgstr "Beziehungen"
msgid "Organization invitations" msgid "Organization invitations"
msgstr "Organisationseinladungen" msgstr "Organisationseinladungen"
#: project/templates/admin/admin.html:15 project/templates/admin/email.html:4 #: project/templates/admin/admin.html:15
#: project/templates/admin/email.html:66
#: project/templates/admin/settings.html:4 #: project/templates/admin/settings.html:4
#: project/templates/admin/settings.html:11 #: project/templates/admin/settings.html:11
#: project/templates/admin_unit/update.html:6 #: project/templates/admin_unit/update.html:6
@ -1578,18 +1606,24 @@ msgid "Switch organization"
msgstr "Organisation wechseln" msgstr "Organisation wechseln"
#: project/templates/developer/read.html:4 project/templates/layout.html:310 #: project/templates/developer/read.html:4 project/templates/layout.html:310
#: project/templates/profile.html:29 #: project/templates/profile.html:33
msgid "Developer" msgid "Developer"
msgstr "Entwickler" msgstr "Entwickler"
#: project/templates/profile.html:23 #: project/templates/profile.html:23
#: project/templates/user/notifications.html:4
#: project/templates/user/notifications.html:8
msgid "Notifications"
msgstr "Benachrichtigungen"
#: project/templates/profile.html:27
msgid "Applications" msgid "Applications"
msgstr "Apps" msgstr "Apps"
#: project/templates/oauth2_client/list.html:4 #: project/templates/oauth2_client/list.html:4
#: project/templates/oauth2_client/list.html:11 #: project/templates/oauth2_client/list.html:11
#: project/templates/oauth2_client/read.html:11 #: project/templates/oauth2_client/read.html:11
#: project/templates/profile.html:33 #: project/templates/profile.html:37
msgid "OAuth2 clients" msgid "OAuth2 clients"
msgstr "OAuth2 Clients" msgstr "OAuth2 Clients"
@ -1610,7 +1644,7 @@ msgstr "Benutzer"
msgid "Edit" msgid "Edit"
msgstr "Bearbeiten" msgstr "Bearbeiten"
#: project/templates/admin/email.html:47 project/views/admin.py:119 #: project/templates/admin/email.html:47 project/views/admin.py:122
msgid "Mail sent successfully" msgid "Mail sent successfully"
msgstr "Mail erfolgreich gesendet" msgstr "Mail erfolgreich gesendet"
@ -1622,6 +1656,10 @@ msgstr "Test-Mail"
msgid "Send test mail asynchronously" msgid "Send test mail asynchronously"
msgstr "Test-Mail asynchron senden" msgstr "Test-Mail asynchron senden"
#: project/templates/admin/newsletter.html:59
msgid "Mails sent successfully"
msgstr "Mails erfolgreich gesendet"
#: project/templates/admin_unit/create.html:58 #: project/templates/admin_unit/create.html:58
#: project/templates/admin_unit/update.html:59 #: project/templates/admin_unit/update.html:59
#: project/templates/event/create.html:347 #: project/templates/event/create.html:347
@ -1676,6 +1714,10 @@ msgstr "Moin"
msgid "this is a message from %(site_name)s." msgid "this is a message from %(site_name)s."
msgstr "das ist eine Nachricht von %(site_name)s." msgstr "das ist eine Nachricht von %(site_name)s."
#: project/templates/email/newsletter.html:7
msgid "Notification settings"
msgstr "Benachrichtigungseinstellungen"
#: project/templates/email/organization_invitation_accepted_notice.html:4 #: project/templates/email/organization_invitation_accepted_notice.html:4
#, python-format #, python-format
msgid "" msgid ""
@ -2096,20 +2138,26 @@ msgstr "Optionale Details"
msgid "Preview" msgid "Preview"
msgstr "Vorschau" msgstr "Vorschau"
#: project/views/admin.py:55 #: project/views/admin.py:58
msgid "Organization successfully updated" msgid "Organization successfully updated"
msgstr "Organisation erfolgreich aktualisiert" msgstr "Organisation erfolgreich aktualisiert"
#: project/views/admin.py:79 project/views/manage.py:361 #: project/views/admin.py:82 project/views/manage.py:361
#: project/views/user.py:27
msgid "Settings successfully updated" msgid "Settings successfully updated"
msgstr "Einstellungen erfolgreich aktualisiert" msgstr "Einstellungen erfolgreich aktualisiert"
#: project/views/admin.py:108 #: project/views/admin.py:111
#, python-format #, python-format
msgid "Test mail from %(site_name)s" msgid "Test mail from %(site_name)s"
msgstr "Test-Mail von %(site_name)s" msgstr "Test-Mail von %(site_name)s"
#: project/views/admin.py:152 #: project/views/admin.py:150
#, python-format
msgid "Newsletter from %(site_name)s"
msgstr "Newsletter von %(site_name)s"
#: project/views/admin.py:200
msgid "User successfully updated" msgid "User successfully updated"
msgstr "Nutzer erfolgreich aktualisiert" msgstr "Nutzer erfolgreich aktualisiert"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2023-03-24 21:24+0100\n" "POT-Creation-Date: 2023-03-28 17:04+0200\n"
"PO-Revision-Date: 2021-04-30 15:04+0200\n" "PO-Revision-Date: 2021-04-30 15:04+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n" "Language: en\n"
@ -209,7 +209,7 @@ msgstr ""
msgid "Legal notice" msgid "Legal notice"
msgstr "" msgstr ""
#: project/forms/admin.py:13 project/templates/_macros.html:1395 #: project/forms/admin.py:13 project/templates/_macros.html:1397
#: project/templates/layout.html:302 #: project/templates/layout.html:302
#: project/templates/widget/event_suggestion/create.html:204 #: project/templates/widget/event_suggestion/create.html:204
#: project/views/admin_unit.py:73 project/views/root.py:69 #: project/views/admin_unit.py:73 project/views/root.py:69
@ -226,6 +226,7 @@ msgid "Start page"
msgstr "" msgstr ""
#: project/forms/admin.py:17 project/forms/oauth2_client.py:24 #: project/forms/admin.py:17 project/forms/oauth2_client.py:24
#: project/forms/user.py:13
msgid "Save" msgid "Save"
msgstr "" msgstr ""
@ -286,7 +287,7 @@ msgstr ""
msgid "Update organization" msgid "Update organization"
msgstr "" msgstr ""
#: project/forms/admin.py:63 #: project/forms/admin.py:63 project/forms/admin.py:70
msgid "Recipient" msgid "Recipient"
msgstr "" msgstr ""
@ -294,6 +295,22 @@ msgstr ""
msgid "Send test mail synchronously" msgid "Send test mail synchronously"
msgstr "" msgstr ""
#: project/forms/admin.py:72 project/forms/admin.py:78
msgid "Test recipient"
msgstr ""
#: project/forms/admin.py:73
msgid "All users with enabled newsletter setting"
msgstr ""
#: project/forms/admin.py:79
msgid "Message"
msgstr ""
#: project/forms/admin.py:80
msgid "Send newsletter"
msgstr ""
#: project/forms/admin_unit.py:15 project/forms/event_place.py:12 #: project/forms/admin_unit.py:15 project/forms/event_place.py:12
#: project/forms/organizer.py:12 #: project/forms/organizer.py:12
msgid "Street" msgid "Street"
@ -343,7 +360,7 @@ msgstr ""
msgid "The short name is used to create a unique identifier for your events" msgid "The short name is used to create a unique identifier for your events"
msgstr "" msgstr ""
#: project/forms/admin_unit.py:41 project/templates/_macros.html:1531 #: project/forms/admin_unit.py:41 project/templates/_macros.html:1533
msgid "Short name must contain only letters numbers or underscore" msgid "Short name must contain only letters numbers or underscore"
msgstr "" msgstr ""
@ -356,20 +373,21 @@ msgstr ""
#: project/forms/admin_unit.py:48 project/forms/admin_unit_member.py:11 #: project/forms/admin_unit.py:48 project/forms/admin_unit_member.py:11
#: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28 #: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28
#: project/forms/event.py:107 project/forms/event_suggestion.py:38 #: project/forms/event.py:107 project/forms/event_suggestion.py:38
#: project/forms/organizer.py:27 project/templates/_macros.html:235 #: project/forms/organizer.py:27 project/templates/_macros.html:237
#: project/templates/_macros.html:1491 project/templates/admin/admin.html:27 #: project/templates/_macros.html:1493 project/templates/admin/admin.html:27
#: project/templates/admin/email.html:4 project/templates/admin/email.html:66
#: project/templates/admin/users.html:19 #: project/templates/admin/users.html:19
msgid "Email" msgid "Email"
msgstr "" msgstr ""
#: project/forms/admin_unit.py:49 project/forms/event.py:108 #: project/forms/admin_unit.py:49 project/forms/event.py:108
#: project/forms/event_suggestion.py:31 project/forms/organizer.py:28 #: project/forms/event_suggestion.py:31 project/forms/organizer.py:28
#: project/templates/_macros.html:288 #: project/templates/_macros.html:290
msgid "Phone" msgid "Phone"
msgstr "" msgstr ""
#: project/forms/admin_unit.py:50 project/forms/event.py:109 #: project/forms/admin_unit.py:50 project/forms/event.py:109
#: project/forms/organizer.py:29 project/templates/_macros.html:296 #: project/forms/organizer.py:29 project/templates/_macros.html:298
msgid "Fax" msgid "Fax"
msgstr "" msgstr ""
@ -567,16 +585,16 @@ msgstr ""
msgid "All-day" msgid "All-day"
msgstr "" msgstr ""
#: project/forms/event.py:54 project/templates/_macros.html:1711 #: project/forms/event.py:54 project/templates/_macros.html:1713
#: project/templates/widget/event_suggestion/create.html:240 #: project/templates/widget/event_suggestion/create.html:240
msgid "Recurring event" msgid "Recurring event"
msgstr "" msgstr ""
#: project/forms/event.py:61 project/templates/_macros.html:1252 #: project/forms/event.py:61 project/templates/_macros.html:1254
msgid "The start must be before the end." msgid "The start must be before the end."
msgstr "" msgstr ""
#: project/forms/event.py:67 project/templates/_macros.html:1269 #: project/forms/event.py:67 project/templates/_macros.html:1271
msgid "An event can last a maximum of 14 days." msgid "An event can last a maximum of 14 days."
msgstr "" msgstr ""
@ -610,7 +628,7 @@ msgstr ""
msgid "Enter a link where tickets can be purchased." msgid "Enter a link where tickets can be purchased."
msgstr "" msgstr ""
#: project/forms/event.py:136 project/templates/_macros.html:217 #: project/forms/event.py:136 project/templates/_macros.html:219
msgid "Tags" msgid "Tags"
msgstr "" msgstr ""
@ -660,7 +678,7 @@ msgstr ""
msgid "If the participants needs to register for the event." msgid "If the participants needs to register for the event."
msgstr "" msgstr ""
#: project/forms/event.py:170 project/templates/_macros.html:249 #: project/forms/event.py:170 project/templates/_macros.html:251
#: project/templates/layout.html:110 #: project/templates/layout.html:110
msgid "Booked up" msgid "Booked up"
msgstr "" msgstr ""
@ -740,8 +758,8 @@ msgid ""
" course it works without it." " course it works without it."
msgstr "" msgstr ""
#: project/forms/event.py:242 project/templates/_macros.html:396 #: project/forms/event.py:242 project/templates/_macros.html:398
#: project/templates/_macros.html:559 #: project/templates/_macros.html:561
msgid "Previous start date" msgid "Previous start date"
msgstr "" msgstr ""
@ -787,7 +805,7 @@ msgstr ""
#: project/forms/event.py:286 project/forms/event.py:295 #: project/forms/event.py:286 project/forms/event.py:295
#: project/forms/event.py:368 project/forms/event_suggestion.py:50 #: project/forms/event.py:368 project/forms/event_suggestion.py:50
#: project/templates/_macros.html:436 project/templates/_macros.html:599 #: project/templates/_macros.html:438 project/templates/_macros.html:601
#: project/templates/event/create.html:284 #: project/templates/event/create.html:284
#: project/templates/event/update.html:166 #: project/templates/event/update.html:166
#: project/templates/event_place/create.html:31 #: project/templates/event_place/create.html:31
@ -806,8 +824,8 @@ msgstr ""
#: project/forms/event.py:302 project/forms/event.py:311 #: project/forms/event.py:302 project/forms/event.py:311
#: project/forms/event.py:376 project/forms/event.py:439 #: project/forms/event.py:376 project/forms/event.py:439
#: project/forms/event_suggestion.py:60 project/templates/_macros.html:473 #: project/forms/event_suggestion.py:60 project/templates/_macros.html:475
#: project/templates/_macros.html:636 project/templates/event/create.html:253 #: project/templates/_macros.html:638 project/templates/event/create.html:253
#: project/templates/event/update.html:156 #: project/templates/event/update.html:156
#: project/templates/organizer/create.html:27 #: project/templates/organizer/create.html:27
#: project/templates/organizer/delete.html:13 #: project/templates/organizer/delete.html:13
@ -892,7 +910,7 @@ msgstr ""
msgid "PublicStatus.published" msgid "PublicStatus.published"
msgstr "" msgstr ""
#: project/forms/event.py:402 project/templates/_macros.html:255 #: project/forms/event.py:402 project/templates/_macros.html:257
msgid "PublicStatus.draft" msgid "PublicStatus.draft"
msgstr "" msgstr ""
@ -905,7 +923,7 @@ msgstr ""
msgid "Update event" msgid "Update event"
msgstr "" msgstr ""
#: project/forms/event.py:423 project/templates/_macros.html:1224 #: project/forms/event.py:423 project/templates/_macros.html:1226
#: project/templates/event/actions.html:66 #: project/templates/event/actions.html:66
#: project/templates/event/delete.html:6 #: project/templates/event/delete.html:6
msgid "Delete event" msgid "Delete event"
@ -926,7 +944,7 @@ msgid "Keyword"
msgstr "" msgstr ""
#: project/forms/event.py:436 project/forms/event_date.py:21 #: project/forms/event.py:436 project/forms/event_date.py:21
#: project/forms/planing.py:19 project/templates/_macros.html:369 #: project/forms/planing.py:19 project/templates/_macros.html:371
msgid "Category" msgid "Category"
msgstr "" msgstr ""
@ -935,7 +953,7 @@ msgid "Find events"
msgstr "" msgstr ""
#: project/forms/event_date.py:24 project/forms/planing.py:22 #: project/forms/event_date.py:24 project/forms/planing.py:22
#: project/templates/_macros.html:303 #: project/templates/_macros.html:305
#: project/templates/admin_unit/create.html:38 #: project/templates/admin_unit/create.html:38
#: project/templates/admin_unit/update.html:39 #: project/templates/admin_unit/update.html:39
#: project/templates/event_place/create.html:40 #: project/templates/event_place/create.html:40
@ -1078,7 +1096,7 @@ msgid "Weekdays"
msgstr "" msgstr ""
#: project/forms/reference.py:11 project/forms/reference_request.py:16 #: project/forms/reference.py:11 project/forms/reference_request.py:16
#: project/templates/_macros.html:489 project/templates/_macros.html:652 #: project/templates/_macros.html:491 project/templates/_macros.html:654
#: project/templates/admin_unit/create.html:28 #: project/templates/admin_unit/create.html:28
#: project/templates/admin_unit/update.html:29 #: project/templates/admin_unit/update.html:29
#: project/templates/layout.html:242 #: project/templates/layout.html:242
@ -1106,7 +1124,7 @@ msgstr ""
msgid "Delete request" msgid "Delete request"
msgstr "" msgstr ""
#: project/forms/reference_request.py:28 project/templates/_macros.html:1407 #: project/forms/reference_request.py:28 project/templates/_macros.html:1409
#: project/templates/event_suggestion/review_status.html:18 #: project/templates/event_suggestion/review_status.html:18
#: project/templates/reference_request/review_status.html:12 #: project/templates/reference_request/review_status.html:12
msgid "Review status" msgid "Review status"
@ -1164,43 +1182,53 @@ msgstr ""
msgid "Deny" msgid "Deny"
msgstr "" msgstr ""
#: project/forms/user.py:9 project/templates/admin/admin.html:31
#: project/templates/admin/newsletter.html:4
#: project/templates/admin/newsletter.html:93
msgid "Newsletter"
msgstr ""
#: project/forms/user.py:10
msgid "Information about new features and improvements."
msgstr ""
#: project/forms/widgets.py:154 #: project/forms/widgets.py:154
msgid "This field is required." msgid "This field is required."
msgstr "" msgstr ""
#: project/templates/_macros.html:147 #: project/templates/_macros.html:149
msgid "Show on Google Maps" msgid "Show on Google Maps"
msgstr "" msgstr ""
#: project/templates/_macros.html:226 #: project/templates/_macros.html:228
msgid "Link" msgid "Link"
msgstr "" msgstr ""
#: project/templates/_macros.html:282 #: project/templates/_macros.html:284
msgid "Verified" msgid "Verified"
msgstr "" msgstr ""
#: project/templates/_macros.html:346
#, python-format
msgid "Created at %(created_at)s by %(created_by)s."
msgstr ""
#: project/templates/_macros.html:348 #: project/templates/_macros.html:348
#, python-format #, python-format
msgid "Created at %(created_at)s." msgid "Created at %(created_at)s by %(created_by)s."
msgstr "" msgstr ""
#: project/templates/_macros.html:353 #: project/templates/_macros.html:350
#, python-format #, python-format
msgid "Last updated at %(updated_at)s by %(updated_by)s." msgid "Created at %(created_at)s."
msgstr "" msgstr ""
#: project/templates/_macros.html:355 #: project/templates/_macros.html:355
#, python-format #, python-format
msgid "Last updated at %(updated_at)s by %(updated_by)s."
msgstr ""
#: project/templates/_macros.html:357
#, python-format
msgid "Last updated at %(updated_at)s." msgid "Last updated at %(updated_at)s."
msgstr "" msgstr ""
#: project/templates/_macros.html:385 project/templates/_macros.html:555 #: project/templates/_macros.html:387 project/templates/_macros.html:557
#: project/templates/event/actions.html:25 #: project/templates/event/actions.html:25
#: project/templates/event/create.html:230 #: project/templates/event/create.html:230
#: project/templates/event/update.html:122 #: project/templates/event/update.html:122
@ -1208,63 +1236,63 @@ msgstr ""
msgid "Event" msgid "Event"
msgstr "" msgstr ""
#: project/templates/_macros.html:391 project/templates/_macros.html:920 #: project/templates/_macros.html:393 project/templates/_macros.html:922
msgid "Date" msgid "Date"
msgstr "" msgstr ""
#: project/templates/_macros.html:418 project/templates/_macros.html:577 #: project/templates/_macros.html:420 project/templates/_macros.html:579
#: project/templates/_macros.html:1476 project/templates/event/actions.html:51 #: project/templates/_macros.html:1478 project/templates/event/actions.html:51
msgid "Share" msgid "Share"
msgstr "" msgstr ""
#: project/templates/_macros.html:422 project/templates/_macros.html:581 #: project/templates/_macros.html:424 project/templates/_macros.html:583
#: project/templates/_macros.html:1506 #: project/templates/_macros.html:1508
msgid "Add to calendar" msgid "Add to calendar"
msgstr "" msgstr ""
#: project/templates/_macros.html:430 project/templates/_macros.html:592 #: project/templates/_macros.html:432 project/templates/_macros.html:594
#: project/templates/event/report.html:4 #: project/templates/event/report.html:4
msgid "Report event" msgid "Report event"
msgstr "" msgstr ""
#: project/templates/_macros.html:457 project/templates/_macros.html:618 #: project/templates/_macros.html:459 project/templates/_macros.html:620
msgid "Show directions" msgid "Show directions"
msgstr "" msgstr ""
#: project/templates/_macros.html:462 project/templates/_macros.html:623 #: project/templates/_macros.html:464 project/templates/_macros.html:625
msgid "The event takes place online." msgid "The event takes place online."
msgstr "" msgstr ""
#: project/templates/_macros.html:464 project/templates/_macros.html:625 #: project/templates/_macros.html:466 project/templates/_macros.html:627
msgid "The event takes place both offline and online." msgid "The event takes place both offline and online."
msgstr "" msgstr ""
#: project/templates/_macros.html:585 project/templates/layout.html:168 #: project/templates/_macros.html:587 project/templates/layout.html:168
#: project/templates/user/favorite_events.html:4 #: project/templates/user/favorite_events.html:4
msgid "Favorite events" msgid "Favorite events"
msgstr "" msgstr ""
#: project/templates/_macros.html:679 project/templates/event_date/list.html:5 #: project/templates/_macros.html:681 project/templates/event_date/list.html:5
#: project/templates/event_date/list.html:299 #: project/templates/event_date/list.html:299
#: project/templates/reference_request/review.html:32 #: project/templates/reference_request/review.html:32
msgid "Event Dates" msgid "Event Dates"
msgstr "" msgstr ""
#: project/templates/_macros.html:771 #: project/templates/_macros.html:773
msgid "Search location on Google" msgid "Search location on Google"
msgstr "" msgstr ""
#: project/templates/_macros.html:837 #: project/templates/_macros.html:839
#, python-format #, python-format
msgid "%(count)d event dates" msgid "%(count)d event dates"
msgstr "" msgstr ""
#: project/templates/_macros.html:860 project/templates/_macros.html:862 #: project/templates/_macros.html:862 project/templates/_macros.html:864
#: project/templates/event_date/list.html:321 #: project/templates/event_date/list.html:321
msgid "First" msgid "First"
msgstr "" msgstr ""
#: project/templates/_macros.html:865 project/templates/_macros.html:867 #: project/templates/_macros.html:867 project/templates/_macros.html:869
#: project/templates/event_date/list.html:322 #: project/templates/event_date/list.html:322
#: project/templates/widget/event_suggestion/create.html:193 #: project/templates/widget/event_suggestion/create.html:193
#: project/templates/widget/event_suggestion/create.html:218 #: project/templates/widget/event_suggestion/create.html:218
@ -1275,12 +1303,12 @@ msgstr ""
msgid "Previous" msgid "Previous"
msgstr "" msgstr ""
#: project/templates/_macros.html:869 #: project/templates/_macros.html:871
#, python-format #, python-format
msgid "Page %(page)d of %(pages)d (%(total)d total)" msgid "Page %(page)d of %(pages)d (%(total)d total)"
msgstr "" msgstr ""
#: project/templates/_macros.html:871 project/templates/_macros.html:873 #: project/templates/_macros.html:873 project/templates/_macros.html:875
#: project/templates/event_date/list.html:324 #: project/templates/event_date/list.html:324
#: project/templates/widget/event_suggestion/create.html:194 #: project/templates/widget/event_suggestion/create.html:194
#: project/templates/widget/event_suggestion/create.html:219 #: project/templates/widget/event_suggestion/create.html:219
@ -1290,88 +1318,88 @@ msgstr ""
msgid "Next" msgid "Next"
msgstr "" msgstr ""
#: project/templates/_macros.html:876 project/templates/_macros.html:878 #: project/templates/_macros.html:878 project/templates/_macros.html:880
#: project/templates/event_date/list.html:325 #: project/templates/event_date/list.html:325
msgid "Last" msgid "Last"
msgstr "" msgstr ""
#: project/templates/_macros.html:943 #: project/templates/_macros.html:945
msgid "Radius" msgid "Radius"
msgstr "" msgstr ""
#: project/templates/_macros.html:1153 #: project/templates/_macros.html:1155
msgid "Edit image" msgid "Edit image"
msgstr "" msgstr ""
#: project/templates/_macros.html:1174 #: project/templates/_macros.html:1176
msgid "Close" msgid "Close"
msgstr "" msgstr ""
#: project/templates/_macros.html:1175 #: project/templates/_macros.html:1177
msgid "Okay" msgid "Okay"
msgstr "" msgstr ""
#: project/templates/_macros.html:1187 #: project/templates/_macros.html:1189
msgid "Choose image file" msgid "Choose image file"
msgstr "" msgstr ""
#: project/templates/_macros.html:1223 project/templates/event/actions.html:65 #: project/templates/_macros.html:1225 project/templates/event/actions.html:65
#: project/templates/event/delete.html:12 #: project/templates/event/delete.html:12
msgid "Edit event" msgid "Edit event"
msgstr "" msgstr ""
#: project/templates/_macros.html:1226 project/templates/manage/events.html:66 #: project/templates/_macros.html:1228 project/templates/manage/events.html:66
msgid "More" msgid "More"
msgstr "" msgstr ""
#: project/templates/_macros.html:1273 #: project/templates/_macros.html:1275
msgid "Please enter a valid time, between 00:00 and 23:59." msgid "Please enter a valid time, between 00:00 and 23:59."
msgstr "" msgstr ""
#: project/templates/_macros.html:1301 #: project/templates/_macros.html:1303
#, python-format #, python-format
msgid "Just use %(term)s" msgid "Just use %(term)s"
msgstr "" msgstr ""
#: project/templates/_macros.html:1367 #: project/templates/_macros.html:1369
msgid "Event suggestion" msgid "Event suggestion"
msgstr "" msgstr ""
#: project/templates/_macros.html:1485 #: project/templates/_macros.html:1487
msgid "Link copied" msgid "Link copied"
msgstr "" msgstr ""
#: project/templates/_macros.html:1485 #: project/templates/_macros.html:1487
msgid "Copy link" msgid "Copy link"
msgstr "" msgstr ""
#: project/templates/_macros.html:1514 #: project/templates/_macros.html:1516
msgid "Google calendar" msgid "Google calendar"
msgstr "" msgstr ""
#: project/templates/_macros.html:1515 #: project/templates/_macros.html:1517
msgid "Apple calendar" msgid "Apple calendar"
msgstr "" msgstr ""
#: project/templates/_macros.html:1516 #: project/templates/_macros.html:1518
msgid "Yahoo calendar" msgid "Yahoo calendar"
msgstr "" msgstr ""
#: project/templates/_macros.html:1517 #: project/templates/_macros.html:1519
msgid "Other calendar" msgid "Other calendar"
msgstr "" msgstr ""
#: project/templates/_macros.html:1712 #: project/templates/_macros.html:1714
msgid "Remove event date" msgid "Remove event date"
msgstr "" msgstr ""
#: project/templates/_macros.html:1741 project/templates/event/create.html:176 #: project/templates/_macros.html:1743 project/templates/event/create.html:176
#: project/templates/event/update.html:99 #: project/templates/event/update.html:99
#: project/templates/widget/event_suggestion/create.html:129 #: project/templates/widget/event_suggestion/create.html:129
msgid "Enter organizer" msgid "Enter organizer"
msgstr "" msgstr ""
#: project/templates/_macros.html:1765 #: project/templates/_macros.html:1767
msgid "Enter list name" msgid "Enter list name"
msgstr "" msgstr ""
@ -1415,6 +1443,7 @@ msgstr ""
#: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9 #: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9
#: project/templates/admin/admin_units.html:10 #: project/templates/admin/admin_units.html:10
#: project/templates/admin/email.html:65 #: project/templates/admin/email.html:65
#: project/templates/admin/newsletter.html:92
#: project/templates/admin/settings.html:10 #: project/templates/admin/settings.html:10
#: project/templates/admin/users.html:10 project/templates/layout.html:171 #: project/templates/admin/users.html:10 project/templates/layout.html:171
msgid "Admin" msgid "Admin"
@ -1502,8 +1531,7 @@ msgstr ""
msgid "Organization invitations" msgid "Organization invitations"
msgstr "" msgstr ""
#: project/templates/admin/admin.html:15 project/templates/admin/email.html:4 #: project/templates/admin/admin.html:15
#: project/templates/admin/email.html:66
#: project/templates/admin/settings.html:4 #: project/templates/admin/settings.html:4
#: project/templates/admin/settings.html:11 #: project/templates/admin/settings.html:11
#: project/templates/admin_unit/update.html:6 #: project/templates/admin_unit/update.html:6
@ -1529,18 +1557,24 @@ msgid "Switch organization"
msgstr "" msgstr ""
#: project/templates/developer/read.html:4 project/templates/layout.html:310 #: project/templates/developer/read.html:4 project/templates/layout.html:310
#: project/templates/profile.html:29 #: project/templates/profile.html:33
msgid "Developer" msgid "Developer"
msgstr "" msgstr ""
#: project/templates/profile.html:23 #: project/templates/profile.html:23
#: project/templates/user/notifications.html:4
#: project/templates/user/notifications.html:8
msgid "Notifications"
msgstr ""
#: project/templates/profile.html:27
msgid "Applications" msgid "Applications"
msgstr "" msgstr ""
#: project/templates/oauth2_client/list.html:4 #: project/templates/oauth2_client/list.html:4
#: project/templates/oauth2_client/list.html:11 #: project/templates/oauth2_client/list.html:11
#: project/templates/oauth2_client/read.html:11 #: project/templates/oauth2_client/read.html:11
#: project/templates/profile.html:33 #: project/templates/profile.html:37
msgid "OAuth2 clients" msgid "OAuth2 clients"
msgstr "" msgstr ""
@ -1561,7 +1595,7 @@ msgstr ""
msgid "Edit" msgid "Edit"
msgstr "" msgstr ""
#: project/templates/admin/email.html:47 project/views/admin.py:119 #: project/templates/admin/email.html:47 project/views/admin.py:122
msgid "Mail sent successfully" msgid "Mail sent successfully"
msgstr "" msgstr ""
@ -1573,6 +1607,10 @@ msgstr ""
msgid "Send test mail asynchronously" msgid "Send test mail asynchronously"
msgstr "" msgstr ""
#: project/templates/admin/newsletter.html:59
msgid "Mails sent successfully"
msgstr ""
#: project/templates/admin_unit/create.html:58 #: project/templates/admin_unit/create.html:58
#: project/templates/admin_unit/update.html:59 #: project/templates/admin_unit/update.html:59
#: project/templates/event/create.html:347 #: project/templates/event/create.html:347
@ -1627,6 +1665,10 @@ msgstr ""
msgid "this is a message from %(site_name)s." msgid "this is a message from %(site_name)s."
msgstr "" msgstr ""
#: project/templates/email/newsletter.html:7
msgid "Notification settings"
msgstr ""
#: project/templates/email/organization_invitation_accepted_notice.html:4 #: project/templates/email/organization_invitation_accepted_notice.html:4
#, python-format #, python-format
msgid "" msgid ""
@ -2036,20 +2078,26 @@ msgstr ""
msgid "Preview" msgid "Preview"
msgstr "" msgstr ""
#: project/views/admin.py:55 #: project/views/admin.py:58
msgid "Organization successfully updated" msgid "Organization successfully updated"
msgstr "" msgstr ""
#: project/views/admin.py:79 project/views/manage.py:361 #: project/views/admin.py:82 project/views/manage.py:361
#: project/views/user.py:27
msgid "Settings successfully updated" msgid "Settings successfully updated"
msgstr "" msgstr ""
#: project/views/admin.py:108 #: project/views/admin.py:111
#, python-format #, python-format
msgid "Test mail from %(site_name)s" msgid "Test mail from %(site_name)s"
msgstr "" msgstr ""
#: project/views/admin.py:152 #: project/views/admin.py:150
#, python-format
msgid "Newsletter from %(site_name)s"
msgstr ""
#: project/views/admin.py:200
msgid "User successfully updated" msgid "User successfully updated"
msgstr "" msgstr ""

View File

@ -1,3 +1,4 @@
from celery import group
from flask import flash, redirect, render_template, request, url_for from flask import flash, redirect, render_template, request, url_for
from flask_babelex import gettext from flask_babelex import gettext
from flask_security import roles_required from flask_security import roles_required
@ -7,6 +8,7 @@ from sqlalchemy.sql import func
from project import app, celery, db from project import app, celery, db
from project.base_tasks import send_mail_task from project.base_tasks import send_mail_task
from project.forms.admin import ( from project.forms.admin import (
AdminNewsletterForm,
AdminSettingsForm, AdminSettingsForm,
AdminTestEmailForm, AdminTestEmailForm,
UpdateAdminUnitForm, UpdateAdminUnitForm,
@ -125,6 +127,51 @@ def admin_email():
return render_template("admin/email.html", form=form) return render_template("admin/email.html", form=form)
@app.route("/admin/newsletter", methods=["GET", "POST"])
@roles_required("admin")
def admin_newsletter():
form = AdminNewsletterForm()
if "poll" in request.args: # pragma: no cover
try:
result = celery.GroupResult.restore(request.args["poll"])
ready = result.ready()
return {
"ready": ready,
"count": len(result.children),
"completed": result.completed_count(),
"successful": result.successful() if ready else None,
}
except Exception as e:
return {"ready": True, "successful": False, "error": str(e)}
if form.validate_on_submit():
subject = gettext(
"Newsletter from %(site_name)s",
site_name=app.config["SITE_NAME"],
)
if form.recipient_choice.data == 1: # pragma: no cover
recipients = [form.test_recipient.data]
else:
users = (
User.query.filter(User.email != None)
.filter(User.confirmed_at != None)
.filter(User.newsletter_enabled)
.all()
)
recipients = [u.email for u in users]
result = group(
send_mail_task.s(r, subject, "newsletter", message=form.message.data)
for r in recipients
).delay()
result.save()
return {"result_id": result.id}
return render_template("admin/newsletter.html", form=form)
@app.route("/admin/users") @app.route("/admin/users")
@roles_required("admin") @roles_required("admin")
def admin_users(): def admin_users():

View File

@ -1,9 +1,12 @@
from flask import render_template from flask import flash, redirect, render_template, url_for
from flask_security import auth_required from flask_babelex import gettext
from flask_security import auth_required, current_user
from sqlalchemy.exc import SQLAlchemyError
from project import app from project import app, db
from project.models import AdminUnitInvitation from project.forms.user import NotificationForm
from project.views.utils import get_invitation_access_result from project.models import AdminUnitInvitation, User
from project.views.utils import get_invitation_access_result, handleSqlError
@app.route("/profile") @app.route("/profile")
@ -12,6 +15,25 @@ def profile():
return render_template("profile.html") return render_template("profile.html")
@app.route("/user/notifications", methods=("GET", "POST"))
@auth_required()
def user_notifications():
user = User.query.get_or_404(current_user.id)
form = NotificationForm(obj=user)
if form.validate_on_submit():
try:
form.populate_obj(user)
db.session.commit()
flash(gettext("Settings successfully updated"), "success")
return redirect(url_for("profile"))
except SQLAlchemyError as e: # pragma: no cover
db.session.rollback()
flash(handleSqlError(e), "danger")
return render_template("user/notifications.html", form=form)
@app.route("/user/organization-invitations/<int:id>") @app.route("/user/organization-invitations/<int:id>")
def user_organization_invitation(id): def user_organization_invitation(id):
invitation = AdminUnitInvitation.query.get_or_404(id) invitation = AdminUnitInvitation.query.get_or_404(id)

View File

@ -14,6 +14,7 @@ def pytest_generate_tests(metafunc):
os.environ["DATABASE_URL"] = os.environ.get( os.environ["DATABASE_URL"] = os.environ.get(
"TEST_DATABASE_URL", "postgresql://postgres@localhost/eventcally_tests" "TEST_DATABASE_URL", "postgresql://postgres@localhost/eventcally_tests"
) )
os.environ["REDIS_URL"] = os.environ.get("TEST_REDIS_URL", "redis://")
os.environ["AUTHLIB_INSECURE_TRANSPORT"] = "1" os.environ["AUTHLIB_INSECURE_TRANSPORT"] = "1"
os.environ[ os.environ[
"JWT_PRIVATE_KEY" "JWT_PRIVATE_KEY"

View File

@ -79,6 +79,28 @@ def test_admin_email(client, seeder, utils, app, mocker):
utils.assert_send_mail_called(mail_mock, "test@test.de") utils.assert_send_mail_called(mail_mock, "test@test.de")
def test_newsletter(app, utils, seeder):
user_id, admin_unit_id = seeder.setup_base(True)
for i in range(10):
seeder.create_user(f"test{i}@test.de")
url = utils.get_url("admin_newsletter")
response = utils.get_ok(url)
response = utils.post_form(
url,
response,
{
"recipient_choice": 2,
"message": "Message",
},
)
utils.assert_response_ok(response)
assert "result_id" in response.json
def test_admin_users(client, seeder, utils, app): def test_admin_users(client, seeder, utils, app):
seeder.create_user(admin=True) seeder.create_user(admin=True)
user = utils.login() user = utils.login()

View File

@ -65,3 +65,26 @@ def test_user_favorite_events(client, seeder, utils):
url = utils.get_url("user_favorite_events") url = utils.get_url("user_favorite_events")
utils.get_ok(url) utils.get_ok(url)
def test_user_notifications(client, seeder, utils, app):
user_id, admin_unit_id = seeder.setup_base()
url = utils.get_url("user_notifications")
response = utils.get_ok(url)
response = utils.post_form(
url,
response,
{
"newsletter_enabled": None,
},
)
utils.assert_response_redirect(response, "profile")
with app.app_context():
from project.models import User
place = User.query.get(user_id)
assert not place.newsletter_enabled