diff --git a/messages.pot b/messages.pot index 6c89f95..bb5cadb 100644 --- a/messages.pot +++ b/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2021-07-25 23:12+0200\n" +"POT-Creation-Date: 2021-07-30 15:18+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -165,24 +165,24 @@ msgstr "" msgid "." msgstr "" -#: project/forms/admin.py:10 project/templates/layout.html:257 +#: project/forms/admin.py:10 project/templates/layout.html:259 #: project/views/root.py:42 msgid "Terms of service" msgstr "" -#: project/forms/admin.py:11 project/templates/layout.html:261 +#: project/forms/admin.py:11 project/templates/layout.html:263 #: project/views/root.py:50 msgid "Legal notice" msgstr "" #: project/forms/admin.py:12 project/templates/_macros.html:1271 -#: project/templates/layout.html:265 +#: project/templates/layout.html:267 #: project/templates/widget/event_suggestion/create.html:172 #: project/views/admin_unit.py:36 project/views/root.py:58 msgid "Contact" msgstr "" -#: project/forms/admin.py:13 project/templates/layout.html:269 +#: project/forms/admin.py:13 project/templates/layout.html:271 #: project/views/root.py:66 msgid "Privacy" msgstr "" @@ -216,18 +216,18 @@ msgstr "" msgid "Update organization" msgstr "" -#: project/forms/admin_unit.py:14 project/forms/event.py:33 -#: project/forms/event_place.py:12 project/forms/organizer.py:12 +#: project/forms/admin_unit.py:14 project/forms/event_place.py:12 +#: project/forms/organizer.py:12 msgid "Street" msgstr "" -#: project/forms/admin_unit.py:15 project/forms/event.py:34 -#: project/forms/event_place.py:13 project/forms/organizer.py:13 +#: project/forms/admin_unit.py:15 project/forms/event_place.py:13 +#: project/forms/organizer.py:13 msgid "Postal code" msgstr "" -#: project/forms/admin_unit.py:16 project/forms/event.py:35 -#: project/forms/event_place.py:14 project/forms/organizer.py:14 +#: project/forms/admin_unit.py:16 project/forms/event_place.py:14 +#: project/forms/organizer.py:14 msgid "City" msgstr "" @@ -246,8 +246,8 @@ msgstr "" msgid "Longitude" msgstr "" -#: project/forms/admin_unit.py:28 project/forms/event.py:40 -#: project/forms/event.py:69 project/forms/event.py:363 +#: project/forms/admin_unit.py:28 project/forms/event.py:35 +#: project/forms/event.py:64 project/forms/event.py:358 #: project/forms/event_place.py:25 project/forms/event_place.py:50 #: project/forms/event_suggestion.py:26 project/forms/oauth2_client.py:66 #: project/forms/organizer.py:25 project/forms/organizer.py:52 @@ -272,27 +272,27 @@ msgstr "" msgid "Short name must contain only letters numbers or underscore" msgstr "" -#: project/forms/admin_unit.py:46 project/forms/event.py:61 -#: project/forms/event.py:98 project/forms/event_place.py:26 +#: project/forms/admin_unit.py:46 project/forms/event.py:56 +#: project/forms/event.py:93 project/forms/event_place.py:26 #: project/forms/organizer.py:26 msgid "Link URL" msgstr "" #: project/forms/admin_unit.py:47 project/forms/admin_unit_member.py:11 #: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28 -#: project/forms/event.py:62 project/forms/event_suggestion.py:38 +#: project/forms/event.py:57 project/forms/event_suggestion.py:38 #: project/forms/organizer.py:27 project/templates/_macros.html:253 #: project/templates/_macros.html:1361 project/templates/admin/users.html:19 msgid "Email" msgstr "" -#: project/forms/admin_unit.py:48 project/forms/event.py:63 +#: project/forms/admin_unit.py:48 project/forms/event.py:58 #: project/forms/event_suggestion.py:31 project/forms/organizer.py:28 #: project/templates/_macros.html:296 msgid "Phone" msgstr "" -#: project/forms/admin_unit.py:49 project/forms/event.py:64 +#: project/forms/admin_unit.py:49 project/forms/event.py:59 #: project/forms/organizer.py:29 project/templates/_macros.html:304 msgid "Fax" msgstr "" @@ -432,362 +432,362 @@ msgstr "" msgid "100 km" msgstr "" -#: project/forms/event.py:58 +#: project/forms/event.py:53 msgid "Organizator" msgstr "" -#: project/forms/event.py:71 +#: project/forms/event.py:66 msgid "Enter a short, meaningful name for the event." msgstr "" -#: project/forms/event.py:74 +#: project/forms/event.py:69 msgid "Start" msgstr "" -#: project/forms/event.py:76 +#: project/forms/event.py:71 msgid "" "Indicate when the event will take place. If the event takes place " "regularly, enter when the first date will begin." msgstr "" -#: project/forms/event.py:81 +#: project/forms/event.py:76 msgid "End" msgstr "" -#: project/forms/event.py:83 +#: project/forms/event.py:78 msgid "" "Indicate when the event will end. An event can last a maximum of 14 days." " If the event takes place regularly, enter when the first date will end." msgstr "" -#: project/forms/event.py:88 +#: project/forms/event.py:83 msgid "Recurrence rule" msgstr "" -#: project/forms/event.py:90 +#: project/forms/event.py:85 msgid "Enter if the event takes place regularly." msgstr "" -#: project/forms/event.py:93 project/forms/event_place.py:28 +#: project/forms/event.py:88 project/forms/event_place.py:28 msgid "Description" msgstr "" -#: project/forms/event.py:95 +#: project/forms/event.py:90 msgid "Add an description of the event." msgstr "" -#: project/forms/event.py:100 +#: project/forms/event.py:95 msgid "" "Enter a link to an external website containing more information about the" " event." msgstr "" -#: project/forms/event.py:105 +#: project/forms/event.py:100 msgid "Ticket Link URL" msgstr "" -#: project/forms/event.py:107 +#: project/forms/event.py:102 msgid "Enter a link where tickets can be purchased." msgstr "" -#: project/forms/event.py:110 project/templates/_macros.html:235 +#: project/forms/event.py:105 project/templates/_macros.html:235 msgid "Tags" msgstr "" -#: project/forms/event.py:112 +#: project/forms/event.py:107 msgid "" "Enter keywords with which the event should be found. Words do not need to" " be entered if they are already in the name or description." msgstr "" -#: project/forms/event.py:117 +#: project/forms/event.py:112 msgid "Kid friendly" msgstr "" -#: project/forms/event.py:119 +#: project/forms/event.py:114 msgid "If the event is particularly suitable for children." msgstr "" -#: project/forms/event.py:122 +#: project/forms/event.py:117 msgid "Accessible for free" msgstr "" -#: project/forms/event.py:124 +#: project/forms/event.py:119 msgid "If the event is accessible for free." msgstr "" -#: project/forms/event.py:127 +#: project/forms/event.py:122 msgid "Typical Age from" msgstr "" -#: project/forms/event.py:129 +#: project/forms/event.py:124 msgid "The minimum age that participants should be." msgstr "" -#: project/forms/event.py:132 +#: project/forms/event.py:127 msgid "Typical Age to" msgstr "" -#: project/forms/event.py:134 +#: project/forms/event.py:129 msgid "The maximum age that participants should be." msgstr "" -#: project/forms/event.py:137 +#: project/forms/event.py:132 msgid "Registration required" msgstr "" -#: project/forms/event.py:139 +#: project/forms/event.py:134 msgid "If the participants needs to register for the event." msgstr "" -#: project/forms/event.py:144 project/templates/_macros.html:267 -#: project/templates/layout.html:155 +#: project/forms/event.py:139 project/templates/_macros.html:267 +#: project/templates/layout.html:157 msgid "Booked up" msgstr "" -#: project/forms/event.py:146 +#: project/forms/event.py:141 msgid "If the event is booked up or sold out." msgstr "" -#: project/forms/event.py:149 +#: project/forms/event.py:144 msgid "Expected number of participants" msgstr "" -#: project/forms/event.py:151 +#: project/forms/event.py:146 msgid "The estimated expected attendance." msgstr "" -#: project/forms/event.py:154 +#: project/forms/event.py:149 msgid "Price info" msgstr "" -#: project/forms/event.py:156 +#: project/forms/event.py:151 msgid "" "Enter price information in textual form. E.g., different prices for " "adults and children." msgstr "" -#: project/forms/event.py:161 +#: project/forms/event.py:156 msgid "Target group origin" msgstr "" -#: project/forms/event.py:166 +#: project/forms/event.py:161 msgid "EventTargetGroupOrigin.both" msgstr "" -#: project/forms/event.py:170 +#: project/forms/event.py:165 msgid "EventTargetGroupOrigin.tourist" msgstr "" -#: project/forms/event.py:174 +#: project/forms/event.py:169 msgid "EventTargetGroupOrigin.resident" msgstr "" -#: project/forms/event.py:177 +#: project/forms/event.py:172 msgid "" "Choose whether the event is particularly suitable for tourists or " "residents." msgstr "" -#: project/forms/event.py:182 +#: project/forms/event.py:177 msgid "Attendance mode" msgstr "" -#: project/forms/event.py:187 +#: project/forms/event.py:182 msgid "EventAttendanceMode.offline" msgstr "" -#: project/forms/event.py:191 project/templates/layout.html:143 +#: project/forms/event.py:186 project/templates/layout.html:145 msgid "EventAttendanceMode.online" msgstr "" -#: project/forms/event.py:193 project/templates/layout.html:146 +#: project/forms/event.py:188 project/templates/layout.html:148 msgid "EventAttendanceMode.mixed" msgstr "" -#: project/forms/event.py:195 +#: project/forms/event.py:190 msgid "Choose how people can attend the event." msgstr "" -#: project/forms/event.py:199 project/forms/event_place.py:27 +#: project/forms/event.py:194 project/forms/event_place.py:27 #: project/templates/widget/event_suggestion/create.html:219 msgid "Photo" msgstr "" -#: project/forms/event.py:201 +#: project/forms/event.py:196 msgid "" "We recommend uploading a photo for the event. It looks a lot more, but of" " course it works without it." msgstr "" -#: project/forms/event.py:211 project/templates/_macros.html:1184 +#: project/forms/event.py:206 project/templates/_macros.html:1184 msgid "The start must be before the end." msgstr "" -#: project/forms/event.py:217 project/templates/_macros.html:1201 +#: project/forms/event.py:212 project/templates/_macros.html:1201 msgid "An event can last a maximum of 14 days." msgstr "" -#: project/forms/event.py:225 project/templates/_macros.html:414 +#: project/forms/event.py:220 project/templates/_macros.html:414 #: project/templates/_macros.html:573 msgid "Previous start date" msgstr "" -#: project/forms/event.py:227 +#: project/forms/event.py:222 msgid "Enter when the event should have taken place before it was postponed." msgstr "" -#: project/forms/event.py:232 project/forms/event_suggestion.py:71 +#: project/forms/event.py:227 project/forms/event_suggestion.py:71 msgid "Categories" msgstr "" -#: project/forms/event.py:235 project/forms/event_suggestion.py:74 +#: project/forms/event.py:230 project/forms/event_suggestion.py:74 msgid "Choose categories that fit the event." msgstr "" -#: project/forms/event.py:238 project/forms/reference.py:14 +#: project/forms/event.py:233 project/forms/reference.py:14 #: project/forms/reference.py:27 project/forms/reference_request.py:70 -#: project/templates/event/create.html:193 -#: project/templates/event/update.html:158 +#: project/templates/event/create.html:318 +#: project/templates/event/update.html:183 msgid "Rating" msgstr "" -#: project/forms/event.py:242 project/forms/reference.py:18 +#: project/forms/event.py:237 project/forms/reference.py:18 #: project/forms/reference.py:31 project/forms/reference_request.py:74 msgid "" "Choose how relevant the event is to your organization. The value is not " "visible and is used for sorting." msgstr "" -#: project/forms/event.py:250 project/forms/event.py:259 -#: project/forms/event.py:319 project/forms/event_suggestion.py:50 +#: project/forms/event.py:245 project/forms/event.py:254 +#: project/forms/event.py:314 project/forms/event_suggestion.py:50 #: project/templates/_macros.html:453 project/templates/_macros.html:609 -#: project/templates/event/create.html:124 -#: project/templates/event/update.html:108 +#: project/templates/event/create.html:243 +#: project/templates/event/update.html:133 #: project/templates/event_place/create.html:21 #: project/templates/event_place/delete.html:13 #: project/templates/event_place/update.html:21 msgid "Place" msgstr "" -#: project/forms/event.py:252 +#: project/forms/event.py:247 msgid "Select existing place" msgstr "" -#: project/forms/event.py:253 +#: project/forms/event.py:248 msgid "Enter new place" msgstr "" -#: project/forms/event.py:266 project/forms/event.py:275 -#: project/forms/event.py:327 project/forms/event.py:377 +#: project/forms/event.py:261 project/forms/event.py:270 +#: project/forms/event.py:322 project/forms/event.py:372 #: project/forms/event_suggestion.py:60 project/templates/_macros.html:491 -#: project/templates/_macros.html:646 project/templates/event/create.html:99 -#: project/templates/event/update.html:99 +#: project/templates/_macros.html:646 project/templates/event/create.html:218 +#: project/templates/event/update.html:124 #: project/templates/organizer/create.html:17 #: project/templates/organizer/delete.html:13 #: project/templates/organizer/update.html:17 msgid "Organizer" msgstr "" -#: project/forms/event.py:268 +#: project/forms/event.py:263 msgid "Select existing organizer" msgstr "" -#: project/forms/event.py:269 +#: project/forms/event.py:264 msgid "Enter new organizer" msgstr "" -#: project/forms/event.py:281 project/templates/event/create.html:4 -#: project/templates/event/create.html:71 +#: project/forms/event.py:276 project/templates/event/create.html:4 +#: project/templates/event/create.html:190 #: project/templates/manage/events.html:12 #: project/templates/manage/organizers.html:21 msgid "Create event" msgstr "" -#: project/forms/event.py:305 +#: project/forms/event.py:300 msgid "Select existing place or enter new place" msgstr "" -#: project/forms/event.py:310 +#: project/forms/event.py:305 msgid "Select existing organizer or enter new organizer" msgstr "" -#: project/forms/event.py:322 +#: project/forms/event.py:317 msgid "" "Choose where the event takes place. You can add and modify places at " "Manage > Places." msgstr "" -#: project/forms/event.py:330 +#: project/forms/event.py:325 msgid "" "Select the organizer. You can add and modify organizers at Manage > " "Organizers." msgstr "" -#: project/forms/event.py:336 project/templates/event/update.html:89 +#: project/forms/event.py:331 project/templates/event/update.html:114 #: project/templates/oauth2_token/list.html:21 msgid "Status" msgstr "" -#: project/forms/event.py:339 +#: project/forms/event.py:334 msgid "EventStatus.scheduled" msgstr "" -#: project/forms/event.py:340 project/templates/layout.html:109 -#: project/templates/layout.html:124 +#: project/forms/event.py:335 project/templates/layout.html:111 +#: project/templates/layout.html:126 msgid "EventStatus.cancelled" msgstr "" -#: project/forms/event.py:341 project/templates/layout.html:112 -#: project/templates/layout.html:127 +#: project/forms/event.py:336 project/templates/layout.html:114 +#: project/templates/layout.html:129 msgid "EventStatus.movedOnline" msgstr "" -#: project/forms/event.py:342 project/templates/layout.html:115 -#: project/templates/layout.html:130 +#: project/forms/event.py:337 project/templates/layout.html:117 +#: project/templates/layout.html:132 msgid "EventStatus.postponed" msgstr "" -#: project/forms/event.py:343 project/templates/layout.html:118 -#: project/templates/layout.html:133 +#: project/forms/event.py:338 project/templates/layout.html:120 +#: project/templates/layout.html:135 msgid "EventStatus.rescheduled" msgstr "" -#: project/forms/event.py:345 +#: project/forms/event.py:340 msgid "Select the status of the event." msgstr "" -#: project/forms/event.py:348 project/templates/event/update.html:4 -#: project/templates/event/update.html:61 +#: project/forms/event.py:343 project/templates/event/update.html:4 +#: project/templates/event/update.html:86 msgid "Update event" msgstr "" -#: project/forms/event.py:362 project/templates/_macros.html:1156 +#: project/forms/event.py:357 project/templates/_macros.html:1156 #: project/templates/event/actions.html:47 #: project/templates/event/delete.html:6 msgid "Delete event" msgstr "" -#: project/forms/event.py:370 project/forms/event_date.py:15 +#: project/forms/event.py:365 project/forms/event_date.py:15 #: project/forms/planing.py:14 msgid "From" msgstr "" -#: project/forms/event.py:371 project/forms/event_date.py:16 +#: project/forms/event.py:366 project/forms/event_date.py:16 #: project/forms/planing.py:15 msgid "to" msgstr "" -#: project/forms/event.py:372 project/forms/event_date.py:17 +#: project/forms/event.py:367 project/forms/event_date.py:17 msgid "Keyword" msgstr "" -#: project/forms/event.py:374 project/forms/event_date.py:19 +#: project/forms/event.py:369 project/forms/event_date.py:19 #: project/forms/planing.py:17 project/templates/_macros.html:377 msgid "Category" msgstr "" -#: project/forms/event.py:380 +#: project/forms/event.py:375 msgid "Find events" msgstr "" @@ -846,13 +846,13 @@ msgstr "" msgid "I would like to be notified by email after the review" msgstr "" -#: project/forms/event_suggestion.py:52 project/templates/event/create.html:129 +#: project/forms/event_suggestion.py:52 project/templates/event/create.html:248 msgid "" "Choose where the event takes place. If the venue is not yet in the list, " "just enter it." msgstr "" -#: project/forms/event_suggestion.py:62 project/templates/event/create.html:103 +#: project/forms/event_suggestion.py:62 project/templates/event/create.html:222 msgid "" "Select the organizer. If the organizer is not yet on the list, just enter" " it." @@ -1046,9 +1046,9 @@ msgstr "" #: project/templates/_macros.html:393 project/templates/_macros.html:569 #: project/templates/event/actions.html:12 -#: project/templates/event/create.html:78 +#: project/templates/event/create.html:197 #: project/templates/event/delete.html:13 -#: project/templates/event/update.html:68 +#: project/templates/event/update.html:93 #: project/templates/reference/delete.html:13 #: project/templates/widget/event_suggestion/create.html:197 msgid "Event" @@ -1174,7 +1174,7 @@ msgstr "" msgid "Other calendar" msgstr "" -#: project/templates/home.html:27 project/templates/layout.html:203 +#: project/templates/home.html:27 project/templates/layout.html:205 msgid "Manage" msgstr "" @@ -1183,22 +1183,22 @@ msgstr "" msgid "Register for free" msgstr "" -#: project/templates/event_place/read.html:22 project/templates/layout.html:206 +#: project/templates/event_place/read.html:22 project/templates/layout.html:208 #: project/templates/layout_manage.html:24 #: project/templates/manage/events.html:5 #: project/templates/manage/events.html:9 msgid "Events" msgstr "" -#: project/templates/layout.html:207 +#: project/templates/layout.html:209 msgid "Planing" msgstr "" -#: project/templates/layout.html:208 +#: project/templates/layout.html:210 msgid "Example" msgstr "" -#: project/templates/layout.html:217 +#: project/templates/layout.html:219 #: project/templates/oauth2_client/list.html:10 #: project/templates/oauth2_client/read.html:10 #: project/templates/oauth2_token/list.html:10 project/templates/profile.html:4 @@ -1208,15 +1208,15 @@ msgstr "" #: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9 #: project/templates/admin/admin_units.html:10 -#: project/templates/admin/users.html:10 project/templates/layout.html:220 +#: project/templates/admin/users.html:10 project/templates/layout.html:222 msgid "Admin" msgstr "" -#: project/templates/layout.html:224 +#: project/templates/layout.html:226 msgid "Logout" msgstr "" -#: project/templates/developer/read.html:4 project/templates/layout.html:279 +#: project/templates/developer/read.html:4 project/templates/layout.html:281 #: project/templates/profile.html:29 msgid "Developer" msgstr "" @@ -1333,8 +1333,8 @@ msgstr "" #: project/templates/admin_unit/create.html:49 #: project/templates/admin_unit/update.html:50 -#: project/templates/event/create.html:181 -#: project/templates/event/update.html:146 +#: project/templates/event/create.html:306 +#: project/templates/event/update.html:171 #: project/templates/event_place/create.html:47 #: project/templates/event_place/update.html:47 #: project/templates/organizer/create.html:46 @@ -1439,18 +1439,32 @@ msgstr "" msgid "List all events of %(admin_unit_name)s" msgstr "" -#: project/templates/event/create.html:88 -#: project/templates/event/update.html:78 +#: project/templates/event/create.html:87 +#: project/templates/event/update.html:73 +msgid "Enter place or address" +msgstr "" + +#: project/templates/event/create.html:97 +#, python-format +msgid "Just use %(term)s" +msgstr "" + +#: project/templates/event/create.html:207 +#: project/templates/event/update.html:103 msgid "Event date" msgstr "" -#: project/templates/event/create.html:154 -#: project/templates/event/update.html:119 +#: project/templates/event/create.html:268 +msgid "Switch to place search" +msgstr "" + +#: project/templates/event/create.html:279 +#: project/templates/event/update.html:144 msgid "Access" msgstr "" -#: project/templates/event/create.html:168 -#: project/templates/event/update.html:133 +#: project/templates/event/create.html:293 +#: project/templates/event/update.html:158 msgid "Target group" msgstr "" @@ -1716,23 +1730,23 @@ msgstr "" msgid "Invitation successfully deleted" msgstr "" -#: project/views/event.py:166 +#: project/views/event.py:167 msgid "Event successfully created" msgstr "" -#: project/views/event.py:203 +#: project/views/event.py:207 msgid "Event successfully updated" msgstr "" -#: project/views/event.py:226 project/views/reference.py:162 +#: project/views/event.py:230 project/views/reference.py:162 msgid "Entered name does not match event name" msgstr "" -#: project/views/event.py:232 +#: project/views/event.py:236 msgid "Event successfully deleted" msgstr "" -#: project/views/event.py:369 +#: project/views/event.py:379 msgid "Referenced event changed" msgstr "" @@ -1761,14 +1775,22 @@ msgstr "" msgid "Event review status updated" msgstr "" -#: project/views/js.py:24 +#: project/views/js.py:27 msgid "Short name is already taken" msgstr "" -#: project/views/js.py:38 +#: project/views/js.py:41 msgid "An account already exists with this email." msgstr "" +#: project/views/js.py:66 +msgid "Places of organization" +msgstr "" + +#: project/views/js.py:74 +msgid "Places of Google Maps" +msgstr "" + #: project/views/oauth2_client.py:37 msgid "OAuth2 client successfully created" msgstr "" diff --git a/project/forms/event.py b/project/forms/event.py index 5491418..7da1363 100644 --- a/project/forms/event.py +++ b/project/forms/event.py @@ -17,6 +17,7 @@ from wtforms.fields.html5 import EmailField, URLField from wtforms.validators import DataRequired, Length, Optional from project.forms.common import Base64ImageForm, event_rating_choices +from project.forms.event_place import EventPlaceLocationForm from project.forms.widgets import CustomDateField, CustomDateTimeField, HTML5StringField from project.models import ( EventAttendanceMode, @@ -29,12 +30,6 @@ from project.models import ( ) -class EventPlaceLocationForm(FlaskForm): - street = StringField(lazy_gettext("Street"), validators=[Optional()]) - postalCode = StringField(lazy_gettext("Postal code"), validators=[Optional()]) - city = StringField(lazy_gettext("City"), validators=[Optional()]) - - class EventPlaceForm(FlaskForm): name = StringField( lazy_gettext("Name"), @@ -301,12 +296,16 @@ class CreateEventForm(BaseEventForm): def validate(self): if not super(BaseEventForm, self).validate(): return False - if self.event_place_id.data == 0 and not self.new_event_place.form.name.data: + if ( + not self.event_place_id.data or self.event_place_id.data == 0 + ) and not self.new_event_place.form.name.data: msg = gettext("Select existing place or enter new place") self.event_place_id.errors.append(msg) self.new_event_place.form.name.errors.append(msg) return False - if self.organizer_id.data == 0 and not self.new_organizer.form.name.data: + if ( + not self.organizer_id.data or self.organizer_id.data == 0 + ) and not self.new_organizer.form.name.data: msg = gettext("Select existing organizer or enter new organizer") self.organizer_id.errors.append(msg) self.new_organizer.form.name.errors.append(msg) diff --git a/project/maputils.py b/project/maputils.py new file mode 100644 index 0000000..ac9e39d --- /dev/null +++ b/project/maputils.py @@ -0,0 +1,42 @@ +import logging +import os + +import googlemaps + +google_maps_api_key = os.getenv("GOOGLE_MAPS_API_KEY") +gmaps = googlemaps.Client(key=google_maps_api_key) if google_maps_api_key else None + + +def find_gmaps_places(query: str) -> list: + result = list() + + if gmaps: + try: + places = gmaps.places_autocomplete_query( + query, location=(51.9059531, 10.4289963), radius=1000000, language="de" + ) + result = list(filter(lambda p: "place_id" in p, places)) + + except Exception as e: # pragma: no cover + logging.exception(e) + + return result + + +def get_gmaps_place(gmaps_id) -> dict: + result = dict() + + if gmaps: + try: + place = gmaps.place( + gmaps_id, + fields=["address_component", "geometry", "name"], + language="de", + ) + + if place["status"] == "OK": + result = place["result"] + except Exception as e: # pragma: no cover + logging.exception(e) + + return result diff --git a/project/services/place.py b/project/services/place.py index 91ba19c..cfc24de 100644 --- a/project/services/place.py +++ b/project/services/place.py @@ -23,9 +23,16 @@ def upsert_event_place(admin_unit_id, name): return result -def get_event_places(admin_unit_id): - return ( - EventPlace.query.filter(EventPlace.admin_unit_id == admin_unit_id) - .order_by(func.lower(EventPlace.name)) - .all() - ) +def get_event_places(admin_unit_id, keyword=None, limit=None): + query = EventPlace.query.filter(EventPlace.admin_unit_id == admin_unit_id) + + if keyword: + like_keyword = "%" + keyword + "%" + query = query.filter(EventPlace.name.ilike(like_keyword)) + + query = query.order_by(func.lower(EventPlace.name)) + + if limit: + query = query.limit(5) + + return query.all() diff --git a/project/static/site.js b/project/static/site.js index 405d5b1..60e0476 100644 --- a/project/static/site.js +++ b/project/static/site.js @@ -243,9 +243,65 @@ function handle_request_success(result_id = '#result_container', spinner_id = '# $(error_id).hide(); } +function reset_place_form(prefix = '') { + $('#' + prefix + 'name').val(''); + $('#' + prefix + 'url').val(''); + $('#' + prefix + 'location-street').val(''); + $('#' + prefix + 'location-postalCode').val(''); + $('#' + prefix + 'location-city').val(''); + $('#' + prefix + 'location-state').val(''); + $('#' + prefix + 'location-latitude').val(''); + $('#' + prefix + 'location-longitude').val(''); +} + +function fill_place_form_with_gmaps_place(place, prefix = '', location_only = false) { + var street_number = ""; + var route = ""; + var city = ""; + + for (var i = 0; i < place.address_components.length; i++) { + var component = place.address_components[i] + var addressType = component.types[0]; + var val = component.long_name + + if (addressType == 'street_number') { + street_number = val; + } else if (addressType == 'route') { + route = val; + } else if (addressType == 'locality') { + city = val; + } else if (addressType == 'administrative_area_level_1') { + $('#' + prefix + 'location-state').val(val); + } else if (addressType == 'postal_code') { + $('#' + prefix + 'location-postalCode').val(val); + } + } + + if (!location_only) { + $('#' + prefix + 'name').val(place.name); + + if (place.website) { + $('#' + prefix + 'url').val(place.website); + } + } + + $('#' + prefix + 'location-street').val([route, street_number].join(' ')); + $('#' + prefix + 'location-city').val(city); + $('#' + prefix + 'location-latitude').val(place.geometry.location.lat); + $('#' + prefix + 'location-longitude').val(place.geometry.location.lng); +} + $( function() { $('[data-toggle="tooltip"]').tooltip(); - $('.autocomplete').select2({width: '100%'}); + + $.fn.select2.defaults.set("language", "de"); + $('.autocomplete').select2({ + width: '100%', + theme: 'bootstrap4' + }); + $('.autocomplete-multi').select2({ + width: '100%' + }); $('.datepicker').each(function (index, element){ start_datepicker($(element)); diff --git a/project/templates/event/create.html b/project/templates/event/create.html index 404abbb..2d84954 100644 --- a/project/templates/event/create.html +++ b/project/templates/event/create.html @@ -6,7 +6,6 @@ {% block header_before_site_js %} {{ render_jquery_steps_header() }} {{ render_cropper_header() }} -{{ render_google_place_autocomplete_header(False, 'new_event_place-') }} @@ -108,7 +133,7 @@ {{ _('Place') }}
- {{ render_field_with_errors(form.event_place_id, class="autocomplete w-100") }} + {{ render_field_with_errors(form.event_place_id, class="w-100") }}
@@ -146,7 +171,7 @@ {{ _('Additional information') }}
- {{ render_field_with_errors(form.category_ids, class="autocomplete w-100") }} + {{ render_field_with_errors(form.category_ids, class="autocomplete-multi w-100") }} {{ render_field_with_errors(form.tags) }} {{ render_field_with_errors(form.external_link) }}
diff --git a/project/templates/layout.html b/project/templates/layout.html index db5a6a1..a89a5a3 100644 --- a/project/templates/layout.html +++ b/project/templates/layout.html @@ -48,6 +48,7 @@ + @@ -80,6 +81,7 @@ + diff --git a/project/templates/widget/event_suggestion/create.html b/project/templates/widget/event_suggestion/create.html index 2515900..1071ce5 100644 --- a/project/templates/widget/event_suggestion/create.html +++ b/project/templates/widget/event_suggestion/create.html @@ -86,7 +86,7 @@ {{ render_cropper_code() }} - $('#event_place_id').select2({width: '100%', tags: true, selectOnClose: true}) + $('#event_place_id').select2({width: '100%', language: 'de', tags: true, theme: 'bootstrap4'}) .on('select2:select', function (e) { var item = $('#event_place_id').select2('data')[0]; var needs_suffix = item.id != '' && item.id == item.text; @@ -100,7 +100,7 @@ } }); - $('#organizer_id').select2({width: '100%', tags: true, selectOnClose: true}) + $('#organizer_id').select2({width: '100%', language: 'de', tags: true, theme: 'bootstrap4'}) .on('select2:select', function (e) { var item = $('#organizer_id').select2('data')[0]; var needs_suffix = item.id != '' && item.id == item.text; @@ -257,7 +257,7 @@ {{ render_field_with_errors(form.age_to) }} {{ render_field_with_errors(form.expected_participants) }}
- {{ render_field_with_errors(form.category_ids, class="autocomplete w-100") }} + {{ render_field_with_errors(form.category_ids, class="autocomplete-multi w-100") }} {{ render_field_with_errors(form.tags) }} {{ render_field_with_errors(form.external_link) }}
diff --git a/project/translations/de/LC_MESSAGES/messages.mo b/project/translations/de/LC_MESSAGES/messages.mo index 8a74bf4..c314d12 100644 Binary files a/project/translations/de/LC_MESSAGES/messages.mo and b/project/translations/de/LC_MESSAGES/messages.mo differ diff --git a/project/translations/de/LC_MESSAGES/messages.po b/project/translations/de/LC_MESSAGES/messages.po index 17a488f..490b4d4 100644 --- a/project/translations/de/LC_MESSAGES/messages.po +++ b/project/translations/de/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2021-07-25 23:12+0200\n" +"POT-Creation-Date: 2021-07-30 15:18+0200\n" "PO-Revision-Date: 2020-06-07 18:51+0200\n" "Last-Translator: FULL NAME \n" "Language: de\n" @@ -166,24 +166,24 @@ msgstr "Event_" msgid "." msgstr "." -#: project/forms/admin.py:10 project/templates/layout.html:257 +#: project/forms/admin.py:10 project/templates/layout.html:259 #: project/views/root.py:42 msgid "Terms of service" msgstr "Nutzungsbedingungen" -#: project/forms/admin.py:11 project/templates/layout.html:261 +#: project/forms/admin.py:11 project/templates/layout.html:263 #: project/views/root.py:50 msgid "Legal notice" msgstr "Impressum" #: project/forms/admin.py:12 project/templates/_macros.html:1271 -#: project/templates/layout.html:265 +#: project/templates/layout.html:267 #: project/templates/widget/event_suggestion/create.html:172 #: project/views/admin_unit.py:36 project/views/root.py:58 msgid "Contact" msgstr "Kontakt" -#: project/forms/admin.py:13 project/templates/layout.html:269 +#: project/forms/admin.py:13 project/templates/layout.html:271 #: project/views/root.py:66 msgid "Privacy" msgstr "Datenschutz" @@ -219,18 +219,18 @@ msgstr "" msgid "Update organization" msgstr "Organisation aktualisieren" -#: project/forms/admin_unit.py:14 project/forms/event.py:33 -#: project/forms/event_place.py:12 project/forms/organizer.py:12 +#: project/forms/admin_unit.py:14 project/forms/event_place.py:12 +#: project/forms/organizer.py:12 msgid "Street" msgstr "Straße" -#: project/forms/admin_unit.py:15 project/forms/event.py:34 -#: project/forms/event_place.py:13 project/forms/organizer.py:13 +#: project/forms/admin_unit.py:15 project/forms/event_place.py:13 +#: project/forms/organizer.py:13 msgid "Postal code" msgstr "Postleitzahl" -#: project/forms/admin_unit.py:16 project/forms/event.py:35 -#: project/forms/event_place.py:14 project/forms/organizer.py:14 +#: project/forms/admin_unit.py:16 project/forms/event_place.py:14 +#: project/forms/organizer.py:14 msgid "City" msgstr "Stadt/Ort" @@ -249,8 +249,8 @@ msgstr "Breitengrad" msgid "Longitude" msgstr "Längengrad" -#: project/forms/admin_unit.py:28 project/forms/event.py:40 -#: project/forms/event.py:69 project/forms/event.py:363 +#: project/forms/admin_unit.py:28 project/forms/event.py:35 +#: project/forms/event.py:64 project/forms/event.py:358 #: project/forms/event_place.py:25 project/forms/event_place.py:50 #: project/forms/event_suggestion.py:26 project/forms/oauth2_client.py:66 #: project/forms/organizer.py:25 project/forms/organizer.py:52 @@ -278,27 +278,27 @@ msgstr "" msgid "Short name must contain only letters numbers or underscore" msgstr "Der Kurzname darf nur Buchstaben, Nummern und Unterstriche enthalten" -#: project/forms/admin_unit.py:46 project/forms/event.py:61 -#: project/forms/event.py:98 project/forms/event_place.py:26 +#: project/forms/admin_unit.py:46 project/forms/event.py:56 +#: project/forms/event.py:93 project/forms/event_place.py:26 #: project/forms/organizer.py:26 msgid "Link URL" msgstr "Link URL" #: project/forms/admin_unit.py:47 project/forms/admin_unit_member.py:11 #: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28 -#: project/forms/event.py:62 project/forms/event_suggestion.py:38 +#: project/forms/event.py:57 project/forms/event_suggestion.py:38 #: project/forms/organizer.py:27 project/templates/_macros.html:253 #: project/templates/_macros.html:1361 project/templates/admin/users.html:19 msgid "Email" msgstr "Email" -#: project/forms/admin_unit.py:48 project/forms/event.py:63 +#: project/forms/admin_unit.py:48 project/forms/event.py:58 #: project/forms/event_suggestion.py:31 project/forms/organizer.py:28 #: project/templates/_macros.html:296 msgid "Phone" msgstr "Telefon" -#: project/forms/admin_unit.py:49 project/forms/event.py:64 +#: project/forms/admin_unit.py:49 project/forms/event.py:59 #: project/forms/organizer.py:29 project/templates/_macros.html:304 msgid "Fax" msgstr "Fax" @@ -365,7 +365,7 @@ msgstr "Copyright Text" #: project/forms/common.py:25 msgid "Image" -msgstr "" +msgstr "Bild" #: project/forms/common.py:72 #, python-format @@ -441,19 +441,19 @@ msgstr "50 km" msgid "100 km" msgstr "100 km" -#: project/forms/event.py:58 +#: project/forms/event.py:53 msgid "Organizator" msgstr "Veranstalter" -#: project/forms/event.py:71 +#: project/forms/event.py:66 msgid "Enter a short, meaningful name for the event." msgstr "Gib einen kurzen, aussagekräftigen Namen für die Veranstaltung ein." -#: project/forms/event.py:74 +#: project/forms/event.py:69 msgid "Start" msgstr "Beginn" -#: project/forms/event.py:76 +#: project/forms/event.py:71 msgid "" "Indicate when the event will take place. If the event takes place " "regularly, enter when the first date will begin." @@ -461,11 +461,11 @@ msgstr "" "Gib an, wann die Veranstaltung stattfindet. Wenn die Veranstaltung " "regelmäßig stattfindet, gib an, wann der erste Termin beginnt." -#: project/forms/event.py:81 +#: project/forms/event.py:76 msgid "End" msgstr "Ende" -#: project/forms/event.py:83 +#: project/forms/event.py:78 msgid "" "Indicate when the event will end. An event can last a maximum of 14 days." " If the event takes place regularly, enter when the first date will end." @@ -474,23 +474,23 @@ msgstr "" "Tage dauern. Wenn die Veranstaltung regelmäßig stattfindet, gib an, wann " "der erste Termin endet." -#: project/forms/event.py:88 +#: project/forms/event.py:83 msgid "Recurrence rule" msgstr "Wiederholen" -#: project/forms/event.py:90 +#: project/forms/event.py:85 msgid "Enter if the event takes place regularly." msgstr "Gib an, ob die Veranstaltung regelmäßig stattfindet." -#: project/forms/event.py:93 project/forms/event_place.py:28 +#: project/forms/event.py:88 project/forms/event_place.py:28 msgid "Description" msgstr "Beschreibung" -#: project/forms/event.py:95 +#: project/forms/event.py:90 msgid "Add an description of the event." msgstr "Füge der Veranstaltung eine Beschreibung hinzu." -#: project/forms/event.py:100 +#: project/forms/event.py:95 msgid "" "Enter a link to an external website containing more information about the" " event." @@ -498,19 +498,19 @@ msgstr "" "Gib einen Link zu einer externen Website ein, die weitere Informationen " "zur Veranstaltung enthält." -#: project/forms/event.py:105 +#: project/forms/event.py:100 msgid "Ticket Link URL" msgstr "Ticket Link" -#: project/forms/event.py:107 +#: project/forms/event.py:102 msgid "Enter a link where tickets can be purchased." msgstr "Gib einen Link ein, über den Tickets gekauft werden können." -#: project/forms/event.py:110 project/templates/_macros.html:235 +#: project/forms/event.py:105 project/templates/_macros.html:235 msgid "Tags" msgstr "Stichworte" -#: project/forms/event.py:112 +#: project/forms/event.py:107 msgid "" "Enter keywords with which the event should be found. Words do not need to" " be entered if they are already in the name or description." @@ -519,68 +519,68 @@ msgstr "" "Worte müssen nicht eingegeben werden, wenn sie bereits im Namen oder in " "der Beschreibung enthalten sind." -#: project/forms/event.py:117 +#: project/forms/event.py:112 msgid "Kid friendly" msgstr "Für Kinder geeignet" -#: project/forms/event.py:119 +#: project/forms/event.py:114 msgid "If the event is particularly suitable for children." msgstr "Wenn die Veranstaltung besonders für Kinder geeignet ist." -#: project/forms/event.py:122 +#: project/forms/event.py:117 msgid "Accessible for free" msgstr "Kostenlos zugänglich" -#: project/forms/event.py:124 +#: project/forms/event.py:119 msgid "If the event is accessible for free." msgstr "Wenn die Veranstaltung kostenlos zugänglich ist." -#: project/forms/event.py:127 +#: project/forms/event.py:122 msgid "Typical Age from" msgstr "Typisches Alter von" -#: project/forms/event.py:129 +#: project/forms/event.py:124 msgid "The minimum age that participants should be." msgstr "Das Mindestalter, das die Teilnehmer haben sollten." -#: project/forms/event.py:132 +#: project/forms/event.py:127 msgid "Typical Age to" msgstr "Typisches Alter bis" -#: project/forms/event.py:134 +#: project/forms/event.py:129 msgid "The maximum age that participants should be." msgstr "Das maximale Alter, das die Teilnehmer haben sollten." -#: project/forms/event.py:137 +#: project/forms/event.py:132 msgid "Registration required" msgstr "Anmeldung erforderlich" -#: project/forms/event.py:139 +#: project/forms/event.py:134 msgid "If the participants needs to register for the event." msgstr "Wenn sich die Teilnehmer für die Veranstaltung anmelden müssen." -#: project/forms/event.py:144 project/templates/_macros.html:267 -#: project/templates/layout.html:155 +#: project/forms/event.py:139 project/templates/_macros.html:267 +#: project/templates/layout.html:157 msgid "Booked up" msgstr "Ausgebucht" -#: project/forms/event.py:146 +#: project/forms/event.py:141 msgid "If the event is booked up or sold out." msgstr "Wenn die Veranstaltung ausgebucht oder ausverkauft ist." -#: project/forms/event.py:149 +#: project/forms/event.py:144 msgid "Expected number of participants" msgstr "Erwartete Teilnehmerzahl" -#: project/forms/event.py:151 +#: project/forms/event.py:146 msgid "The estimated expected attendance." msgstr "Die geschätzte erwartete Teilnehmerzahl." -#: project/forms/event.py:154 +#: project/forms/event.py:149 msgid "Price info" msgstr "Preisinformation" -#: project/forms/event.py:156 +#: project/forms/event.py:151 msgid "" "Enter price information in textual form. E.g., different prices for " "adults and children." @@ -588,23 +588,23 @@ msgstr "" "Gib die Preisinformationen in Textform ein. Z.B. unterschiedliche Preise " "für Erwachsene und Kinder." -#: project/forms/event.py:161 +#: project/forms/event.py:156 msgid "Target group origin" msgstr "Für Touristen/Einwohner geeignet" -#: project/forms/event.py:166 +#: project/forms/event.py:161 msgid "EventTargetGroupOrigin.both" msgstr "Für Touristen und Einwohner" -#: project/forms/event.py:170 +#: project/forms/event.py:165 msgid "EventTargetGroupOrigin.tourist" msgstr "Hauptsächlich für Touristen" -#: project/forms/event.py:174 +#: project/forms/event.py:169 msgid "EventTargetGroupOrigin.resident" msgstr "Hauptsächlich für Einwohner" -#: project/forms/event.py:177 +#: project/forms/event.py:172 msgid "" "Choose whether the event is particularly suitable for tourists or " "residents." @@ -612,32 +612,32 @@ msgstr "" "Wähle, ob die Veranstaltung besonders für Touristen oder Einwohner " "geeignet ist." -#: project/forms/event.py:182 +#: project/forms/event.py:177 msgid "Attendance mode" msgstr "Teilnahme" -#: project/forms/event.py:187 +#: project/forms/event.py:182 msgid "EventAttendanceMode.offline" msgstr "Präsenzveranstaltung" -#: project/forms/event.py:191 project/templates/layout.html:143 +#: project/forms/event.py:186 project/templates/layout.html:145 msgid "EventAttendanceMode.online" msgstr "Online" -#: project/forms/event.py:193 project/templates/layout.html:146 +#: project/forms/event.py:188 project/templates/layout.html:148 msgid "EventAttendanceMode.mixed" msgstr "Präsenzveranstaltung und online" -#: project/forms/event.py:195 +#: project/forms/event.py:190 msgid "Choose how people can attend the event." msgstr "Wähle aus, wie Personen an der Veranstaltung teilnehmen können." -#: project/forms/event.py:199 project/forms/event_place.py:27 +#: project/forms/event.py:194 project/forms/event_place.py:27 #: project/templates/widget/event_suggestion/create.html:219 msgid "Photo" msgstr "Foto" -#: project/forms/event.py:201 +#: project/forms/event.py:196 msgid "" "We recommend uploading a photo for the event. It looks a lot more, but of" " course it works without it." @@ -645,41 +645,41 @@ msgstr "" "Wir empfehlen dir, ein Foto für die Veranstaltung hochzuladen. Es macht " "schon deutlich mehr her, aber es geht natürlich auch ohne." -#: project/forms/event.py:211 project/templates/_macros.html:1184 +#: project/forms/event.py:206 project/templates/_macros.html:1184 msgid "The start must be before the end." msgstr "Der Start muss vor dem Ende sein." -#: project/forms/event.py:217 project/templates/_macros.html:1201 +#: project/forms/event.py:212 project/templates/_macros.html:1201 msgid "An event can last a maximum of 14 days." msgstr "Eine Veranstaltung darf maximal 14 Tage dauern." -#: project/forms/event.py:225 project/templates/_macros.html:414 +#: project/forms/event.py:220 project/templates/_macros.html:414 #: project/templates/_macros.html:573 msgid "Previous start date" msgstr "Vorheriges Startdatum" -#: project/forms/event.py:227 +#: project/forms/event.py:222 msgid "Enter when the event should have taken place before it was postponed." msgstr "" "Gib ein, wann die Veranstaltung hätte stattfinden sollen, bevor sie " "verschoben wurde." -#: project/forms/event.py:232 project/forms/event_suggestion.py:71 +#: project/forms/event.py:227 project/forms/event_suggestion.py:71 msgid "Categories" msgstr "Kategorien" -#: project/forms/event.py:235 project/forms/event_suggestion.py:74 +#: project/forms/event.py:230 project/forms/event_suggestion.py:74 msgid "Choose categories that fit the event." msgstr "Wähle Kategorien, die zur Veranstaltung passen." -#: project/forms/event.py:238 project/forms/reference.py:14 +#: project/forms/event.py:233 project/forms/reference.py:14 #: project/forms/reference.py:27 project/forms/reference_request.py:70 -#: project/templates/event/create.html:193 -#: project/templates/event/update.html:158 +#: project/templates/event/create.html:318 +#: project/templates/event/update.html:183 msgid "Rating" msgstr "Bewertung" -#: project/forms/event.py:242 project/forms/reference.py:18 +#: project/forms/event.py:237 project/forms/reference.py:18 #: project/forms/reference.py:31 project/forms/reference_request.py:74 msgid "" "Choose how relevant the event is to your organization. The value is not " @@ -688,60 +688,60 @@ msgstr "" "Wähle aus, wie relevant die Veranstaltung für deine Organisation ist. Der" " Wert ist nicht sichtbar und dient der Sortierung." -#: project/forms/event.py:250 project/forms/event.py:259 -#: project/forms/event.py:319 project/forms/event_suggestion.py:50 +#: project/forms/event.py:245 project/forms/event.py:254 +#: project/forms/event.py:314 project/forms/event_suggestion.py:50 #: project/templates/_macros.html:453 project/templates/_macros.html:609 -#: project/templates/event/create.html:124 -#: project/templates/event/update.html:108 +#: project/templates/event/create.html:243 +#: project/templates/event/update.html:133 #: project/templates/event_place/create.html:21 #: project/templates/event_place/delete.html:13 #: project/templates/event_place/update.html:21 msgid "Place" msgstr "Ort" -#: project/forms/event.py:252 +#: project/forms/event.py:247 msgid "Select existing place" msgstr "Vorhandenen Ort auswählen" -#: project/forms/event.py:253 +#: project/forms/event.py:248 msgid "Enter new place" msgstr "Neuen Ort eingeben" -#: project/forms/event.py:266 project/forms/event.py:275 -#: project/forms/event.py:327 project/forms/event.py:377 +#: project/forms/event.py:261 project/forms/event.py:270 +#: project/forms/event.py:322 project/forms/event.py:372 #: project/forms/event_suggestion.py:60 project/templates/_macros.html:491 -#: project/templates/_macros.html:646 project/templates/event/create.html:99 -#: project/templates/event/update.html:99 +#: project/templates/_macros.html:646 project/templates/event/create.html:218 +#: project/templates/event/update.html:124 #: project/templates/organizer/create.html:17 #: project/templates/organizer/delete.html:13 #: project/templates/organizer/update.html:17 msgid "Organizer" msgstr "Veranstalter" -#: project/forms/event.py:268 +#: project/forms/event.py:263 msgid "Select existing organizer" msgstr "Vorhandenen Veranstalter auswählen" -#: project/forms/event.py:269 +#: project/forms/event.py:264 msgid "Enter new organizer" msgstr "Neuen Veranstalter eingeben" -#: project/forms/event.py:281 project/templates/event/create.html:4 -#: project/templates/event/create.html:71 +#: project/forms/event.py:276 project/templates/event/create.html:4 +#: project/templates/event/create.html:190 #: project/templates/manage/events.html:12 #: project/templates/manage/organizers.html:21 msgid "Create event" msgstr "Veranstaltung erstellen" -#: project/forms/event.py:305 +#: project/forms/event.py:300 msgid "Select existing place or enter new place" msgstr "Existierenden Ort wählen oder neuen Ort eingeben" -#: project/forms/event.py:310 +#: project/forms/event.py:305 msgid "Select existing organizer or enter new organizer" msgstr "Wähle einen vorhandenen Veranstalter oder gib einen neuen Veranstalter ein" -#: project/forms/event.py:322 +#: project/forms/event.py:317 msgid "" "Choose where the event takes place. You can add and modify places at " "Manage > Places." @@ -749,7 +749,7 @@ msgstr "" "Wähle, wo die Veranstaltung stattfindet. Du kannst Orte unter Verwaltung " "> Orte hinzufügen und ändern." -#: project/forms/event.py:330 +#: project/forms/event.py:325 msgid "" "Select the organizer. You can add and modify organizers at Manage > " "Organizers." @@ -757,70 +757,70 @@ msgstr "" "Wähle den Veranstalter. Du kannst Veranstalter unter Verwaltung > " "Veranstalter hinzufügen und ändern." -#: project/forms/event.py:336 project/templates/event/update.html:89 +#: project/forms/event.py:331 project/templates/event/update.html:114 #: project/templates/oauth2_token/list.html:21 msgid "Status" msgstr "Status" -#: project/forms/event.py:339 +#: project/forms/event.py:334 msgid "EventStatus.scheduled" msgstr "Geplant" -#: project/forms/event.py:340 project/templates/layout.html:109 -#: project/templates/layout.html:124 +#: project/forms/event.py:335 project/templates/layout.html:111 +#: project/templates/layout.html:126 msgid "EventStatus.cancelled" msgstr "Abgesagt" -#: project/forms/event.py:341 project/templates/layout.html:112 -#: project/templates/layout.html:127 +#: project/forms/event.py:336 project/templates/layout.html:114 +#: project/templates/layout.html:129 msgid "EventStatus.movedOnline" msgstr "Online verschoben" -#: project/forms/event.py:342 project/templates/layout.html:115 -#: project/templates/layout.html:130 +#: project/forms/event.py:337 project/templates/layout.html:117 +#: project/templates/layout.html:132 msgid "EventStatus.postponed" msgstr "Verschoben" -#: project/forms/event.py:343 project/templates/layout.html:118 -#: project/templates/layout.html:133 +#: project/forms/event.py:338 project/templates/layout.html:120 +#: project/templates/layout.html:135 msgid "EventStatus.rescheduled" msgstr "Neu angesetzt" -#: project/forms/event.py:345 +#: project/forms/event.py:340 msgid "Select the status of the event." msgstr "Wähle den Status der Veranstaltung." -#: project/forms/event.py:348 project/templates/event/update.html:4 -#: project/templates/event/update.html:61 +#: project/forms/event.py:343 project/templates/event/update.html:4 +#: project/templates/event/update.html:86 msgid "Update event" msgstr "Veranstaltung aktualisieren" -#: project/forms/event.py:362 project/templates/_macros.html:1156 +#: project/forms/event.py:357 project/templates/_macros.html:1156 #: project/templates/event/actions.html:47 #: project/templates/event/delete.html:6 msgid "Delete event" msgstr "Veranstaltung löschen" -#: project/forms/event.py:370 project/forms/event_date.py:15 +#: project/forms/event.py:365 project/forms/event_date.py:15 #: project/forms/planing.py:14 msgid "From" msgstr "Von" -#: project/forms/event.py:371 project/forms/event_date.py:16 +#: project/forms/event.py:366 project/forms/event_date.py:16 #: project/forms/planing.py:15 msgid "to" msgstr "bis" -#: project/forms/event.py:372 project/forms/event_date.py:17 +#: project/forms/event.py:367 project/forms/event_date.py:17 msgid "Keyword" msgstr "Stichwort" -#: project/forms/event.py:374 project/forms/event_date.py:19 +#: project/forms/event.py:369 project/forms/event_date.py:19 #: project/forms/planing.py:17 project/templates/_macros.html:377 msgid "Category" msgstr "Kategorie" -#: project/forms/event.py:380 +#: project/forms/event.py:375 msgid "Find events" msgstr "Veranstaltungen finden" @@ -879,7 +879,7 @@ msgstr "Bitte gib deine Email-Adresse oder deine Telefonnummer für die Prüfung msgid "I would like to be notified by email after the review" msgstr "Ich möchte per Email benachrichtigt werden nach der Prüfung" -#: project/forms/event_suggestion.py:52 project/templates/event/create.html:129 +#: project/forms/event_suggestion.py:52 project/templates/event/create.html:248 msgid "" "Choose where the event takes place. If the venue is not yet in the list, " "just enter it." @@ -887,7 +887,7 @@ msgstr "" "Wähle aus, wo die Veranstaltung stattfindet. Ist der Veranstaltungsort " "noch nicht in der Liste, trage ihn einfach ein." -#: project/forms/event_suggestion.py:62 project/templates/event/create.html:103 +#: project/forms/event_suggestion.py:62 project/templates/event/create.html:222 msgid "" "Select the organizer. If the organizer is not yet on the list, just enter" " it." @@ -1083,9 +1083,9 @@ msgstr "Zuletzt aktualisiert am %(updated_at)s." #: project/templates/_macros.html:393 project/templates/_macros.html:569 #: project/templates/event/actions.html:12 -#: project/templates/event/create.html:78 +#: project/templates/event/create.html:197 #: project/templates/event/delete.html:13 -#: project/templates/event/update.html:68 +#: project/templates/event/update.html:93 #: project/templates/reference/delete.html:13 #: project/templates/widget/event_suggestion/create.html:197 msgid "Event" @@ -1213,7 +1213,7 @@ msgstr "Yahoo Kalender" msgid "Other calendar" msgstr "Anderer Kalender" -#: project/templates/home.html:27 project/templates/layout.html:203 +#: project/templates/home.html:27 project/templates/layout.html:205 msgid "Manage" msgstr "Verwaltung" @@ -1222,22 +1222,22 @@ msgstr "Verwaltung" msgid "Register for free" msgstr "Kostenlos registrieren" -#: project/templates/event_place/read.html:22 project/templates/layout.html:206 +#: project/templates/event_place/read.html:22 project/templates/layout.html:208 #: project/templates/layout_manage.html:24 #: project/templates/manage/events.html:5 #: project/templates/manage/events.html:9 msgid "Events" msgstr "Veranstaltungen" -#: project/templates/layout.html:207 +#: project/templates/layout.html:209 msgid "Planing" msgstr "Planung" -#: project/templates/layout.html:208 +#: project/templates/layout.html:210 msgid "Example" msgstr "Beispiel" -#: project/templates/layout.html:217 +#: project/templates/layout.html:219 #: project/templates/oauth2_client/list.html:10 #: project/templates/oauth2_client/read.html:10 #: project/templates/oauth2_token/list.html:10 project/templates/profile.html:4 @@ -1247,15 +1247,15 @@ msgstr "Profil" #: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9 #: project/templates/admin/admin_units.html:10 -#: project/templates/admin/users.html:10 project/templates/layout.html:220 +#: project/templates/admin/users.html:10 project/templates/layout.html:222 msgid "Admin" msgstr "Administration" -#: project/templates/layout.html:224 +#: project/templates/layout.html:226 msgid "Logout" msgstr "Ausloggen" -#: project/templates/developer/read.html:4 project/templates/layout.html:279 +#: project/templates/developer/read.html:4 project/templates/layout.html:281 #: project/templates/profile.html:29 msgid "Developer" msgstr "Entwickler" @@ -1372,8 +1372,8 @@ msgstr "Bearbeiten" #: project/templates/admin_unit/create.html:49 #: project/templates/admin_unit/update.html:50 -#: project/templates/event/create.html:181 -#: project/templates/event/update.html:146 +#: project/templates/event/create.html:306 +#: project/templates/event/update.html:171 #: project/templates/event_place/create.html:47 #: project/templates/event_place/update.html:47 #: project/templates/organizer/create.html:46 @@ -1480,18 +1480,32 @@ msgstr "Erstelle eine weitere Veranstaltung für %(admin_unit_name)s" msgid "List all events of %(admin_unit_name)s" msgstr "Zeige alle Veranstaltungen von %(admin_unit_name)s" -#: project/templates/event/create.html:88 -#: project/templates/event/update.html:78 +#: project/templates/event/create.html:87 +#: project/templates/event/update.html:73 +msgid "Enter place or address" +msgstr "Orte oder Adresse eingeben" + +#: project/templates/event/create.html:97 +#, python-format +msgid "Just use %(term)s" +msgstr "Verwende einfach %(term)s" + +#: project/templates/event/create.html:207 +#: project/templates/event/update.html:103 msgid "Event date" msgstr "Termin" -#: project/templates/event/create.html:154 -#: project/templates/event/update.html:119 +#: project/templates/event/create.html:268 +msgid "Switch to place search" +msgstr "Zur Ortssuche wechseln" + +#: project/templates/event/create.html:279 +#: project/templates/event/update.html:144 msgid "Access" msgstr "Zugang" -#: project/templates/event/create.html:168 -#: project/templates/event/update.html:133 +#: project/templates/event/create.html:293 +#: project/templates/event/update.html:158 msgid "Target group" msgstr "Zielgruppe" @@ -1760,23 +1774,23 @@ msgstr "Die eingegebene Email passt nicht zur Email der Einladung" msgid "Invitation successfully deleted" msgstr "Einladung erfolgreich gelöscht" -#: project/views/event.py:166 +#: project/views/event.py:167 msgid "Event successfully created" msgstr "Veranstaltung erfolgreich erstellt" -#: project/views/event.py:203 +#: project/views/event.py:207 msgid "Event successfully updated" msgstr "Veranstaltung erfolgreich aktualisiert" -#: project/views/event.py:226 project/views/reference.py:162 +#: project/views/event.py:230 project/views/reference.py:162 msgid "Entered name does not match event name" msgstr "Der eingegebene Name entspricht nicht dem Namen der Veranstaltung" -#: project/views/event.py:232 +#: project/views/event.py:236 msgid "Event successfully deleted" msgstr "Veranstaltung erfolgreich gelöscht" -#: project/views/event.py:369 +#: project/views/event.py:379 msgid "Referenced event changed" msgstr "Empfohlene Veranstaltung wurde geändert" @@ -1805,14 +1819,22 @@ msgstr "Veranstaltungsvorschlag erfolgreich abgelehnt" msgid "Event review status updated" msgstr "Prüfungsstatus aktualisiert" -#: project/views/js.py:24 +#: project/views/js.py:27 msgid "Short name is already taken" msgstr "Der Kurzname ist bereits vergeben" -#: project/views/js.py:38 +#: project/views/js.py:41 msgid "An account already exists with this email." msgstr "Mit dieser E-Mail existiert bereits ein Account." +#: project/views/js.py:66 +msgid "Places of organization" +msgstr "Orte der Organisation" + +#: project/views/js.py:74 +msgid "Places of Google Maps" +msgstr "Orte von Google Maps" + #: project/views/oauth2_client.py:37 msgid "OAuth2 client successfully created" msgstr "OAuth2 Client erfolgreich erstellt" diff --git a/project/translations/en/LC_MESSAGES/messages.mo b/project/translations/en/LC_MESSAGES/messages.mo index 52371a5..9451832 100644 Binary files a/project/translations/en/LC_MESSAGES/messages.mo and b/project/translations/en/LC_MESSAGES/messages.mo differ diff --git a/project/translations/en/LC_MESSAGES/messages.po b/project/translations/en/LC_MESSAGES/messages.po index 80dff32..c07e65e 100644 --- a/project/translations/en/LC_MESSAGES/messages.po +++ b/project/translations/en/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2021-07-25 23:12+0200\n" +"POT-Creation-Date: 2021-07-30 15:18+0200\n" "PO-Revision-Date: 2021-04-30 15:04+0200\n" "Last-Translator: FULL NAME \n" "Language: en\n" @@ -166,24 +166,24 @@ msgstr "" msgid "." msgstr "" -#: project/forms/admin.py:10 project/templates/layout.html:257 +#: project/forms/admin.py:10 project/templates/layout.html:259 #: project/views/root.py:42 msgid "Terms of service" msgstr "" -#: project/forms/admin.py:11 project/templates/layout.html:261 +#: project/forms/admin.py:11 project/templates/layout.html:263 #: project/views/root.py:50 msgid "Legal notice" msgstr "" #: project/forms/admin.py:12 project/templates/_macros.html:1271 -#: project/templates/layout.html:265 +#: project/templates/layout.html:267 #: project/templates/widget/event_suggestion/create.html:172 #: project/views/admin_unit.py:36 project/views/root.py:58 msgid "Contact" msgstr "" -#: project/forms/admin.py:13 project/templates/layout.html:269 +#: project/forms/admin.py:13 project/templates/layout.html:271 #: project/views/root.py:66 msgid "Privacy" msgstr "" @@ -217,18 +217,18 @@ msgstr "" msgid "Update organization" msgstr "" -#: project/forms/admin_unit.py:14 project/forms/event.py:33 -#: project/forms/event_place.py:12 project/forms/organizer.py:12 +#: project/forms/admin_unit.py:14 project/forms/event_place.py:12 +#: project/forms/organizer.py:12 msgid "Street" msgstr "" -#: project/forms/admin_unit.py:15 project/forms/event.py:34 -#: project/forms/event_place.py:13 project/forms/organizer.py:13 +#: project/forms/admin_unit.py:15 project/forms/event_place.py:13 +#: project/forms/organizer.py:13 msgid "Postal code" msgstr "" -#: project/forms/admin_unit.py:16 project/forms/event.py:35 -#: project/forms/event_place.py:14 project/forms/organizer.py:14 +#: project/forms/admin_unit.py:16 project/forms/event_place.py:14 +#: project/forms/organizer.py:14 msgid "City" msgstr "" @@ -247,8 +247,8 @@ msgstr "" msgid "Longitude" msgstr "" -#: project/forms/admin_unit.py:28 project/forms/event.py:40 -#: project/forms/event.py:69 project/forms/event.py:363 +#: project/forms/admin_unit.py:28 project/forms/event.py:35 +#: project/forms/event.py:64 project/forms/event.py:358 #: project/forms/event_place.py:25 project/forms/event_place.py:50 #: project/forms/event_suggestion.py:26 project/forms/oauth2_client.py:66 #: project/forms/organizer.py:25 project/forms/organizer.py:52 @@ -273,27 +273,27 @@ msgstr "" msgid "Short name must contain only letters numbers or underscore" msgstr "" -#: project/forms/admin_unit.py:46 project/forms/event.py:61 -#: project/forms/event.py:98 project/forms/event_place.py:26 +#: project/forms/admin_unit.py:46 project/forms/event.py:56 +#: project/forms/event.py:93 project/forms/event_place.py:26 #: project/forms/organizer.py:26 msgid "Link URL" msgstr "" #: project/forms/admin_unit.py:47 project/forms/admin_unit_member.py:11 #: project/forms/admin_unit_member.py:23 project/forms/admin_unit_member.py:28 -#: project/forms/event.py:62 project/forms/event_suggestion.py:38 +#: project/forms/event.py:57 project/forms/event_suggestion.py:38 #: project/forms/organizer.py:27 project/templates/_macros.html:253 #: project/templates/_macros.html:1361 project/templates/admin/users.html:19 msgid "Email" msgstr "" -#: project/forms/admin_unit.py:48 project/forms/event.py:63 +#: project/forms/admin_unit.py:48 project/forms/event.py:58 #: project/forms/event_suggestion.py:31 project/forms/organizer.py:28 #: project/templates/_macros.html:296 msgid "Phone" msgstr "" -#: project/forms/admin_unit.py:49 project/forms/event.py:64 +#: project/forms/admin_unit.py:49 project/forms/event.py:59 #: project/forms/organizer.py:29 project/templates/_macros.html:304 msgid "Fax" msgstr "" @@ -433,362 +433,362 @@ msgstr "" msgid "100 km" msgstr "" -#: project/forms/event.py:58 +#: project/forms/event.py:53 msgid "Organizator" msgstr "" -#: project/forms/event.py:71 +#: project/forms/event.py:66 msgid "Enter a short, meaningful name for the event." msgstr "" -#: project/forms/event.py:74 +#: project/forms/event.py:69 msgid "Start" msgstr "" -#: project/forms/event.py:76 +#: project/forms/event.py:71 msgid "" "Indicate when the event will take place. If the event takes place " "regularly, enter when the first date will begin." msgstr "" -#: project/forms/event.py:81 +#: project/forms/event.py:76 msgid "End" msgstr "" -#: project/forms/event.py:83 +#: project/forms/event.py:78 msgid "" "Indicate when the event will end. An event can last a maximum of 14 days." " If the event takes place regularly, enter when the first date will end." msgstr "" -#: project/forms/event.py:88 +#: project/forms/event.py:83 msgid "Recurrence rule" msgstr "" -#: project/forms/event.py:90 +#: project/forms/event.py:85 msgid "Enter if the event takes place regularly." msgstr "" -#: project/forms/event.py:93 project/forms/event_place.py:28 +#: project/forms/event.py:88 project/forms/event_place.py:28 msgid "Description" msgstr "" -#: project/forms/event.py:95 +#: project/forms/event.py:90 msgid "Add an description of the event." msgstr "" -#: project/forms/event.py:100 +#: project/forms/event.py:95 msgid "" "Enter a link to an external website containing more information about the" " event." msgstr "" -#: project/forms/event.py:105 +#: project/forms/event.py:100 msgid "Ticket Link URL" msgstr "" -#: project/forms/event.py:107 +#: project/forms/event.py:102 msgid "Enter a link where tickets can be purchased." msgstr "" -#: project/forms/event.py:110 project/templates/_macros.html:235 +#: project/forms/event.py:105 project/templates/_macros.html:235 msgid "Tags" msgstr "" -#: project/forms/event.py:112 +#: project/forms/event.py:107 msgid "" "Enter keywords with which the event should be found. Words do not need to" " be entered if they are already in the name or description." msgstr "" -#: project/forms/event.py:117 +#: project/forms/event.py:112 msgid "Kid friendly" msgstr "" -#: project/forms/event.py:119 +#: project/forms/event.py:114 msgid "If the event is particularly suitable for children." msgstr "" -#: project/forms/event.py:122 +#: project/forms/event.py:117 msgid "Accessible for free" msgstr "" -#: project/forms/event.py:124 +#: project/forms/event.py:119 msgid "If the event is accessible for free." msgstr "" -#: project/forms/event.py:127 +#: project/forms/event.py:122 msgid "Typical Age from" msgstr "" -#: project/forms/event.py:129 +#: project/forms/event.py:124 msgid "The minimum age that participants should be." msgstr "" -#: project/forms/event.py:132 +#: project/forms/event.py:127 msgid "Typical Age to" msgstr "" -#: project/forms/event.py:134 +#: project/forms/event.py:129 msgid "The maximum age that participants should be." msgstr "" -#: project/forms/event.py:137 +#: project/forms/event.py:132 msgid "Registration required" msgstr "" -#: project/forms/event.py:139 +#: project/forms/event.py:134 msgid "If the participants needs to register for the event." msgstr "" -#: project/forms/event.py:144 project/templates/_macros.html:267 -#: project/templates/layout.html:155 +#: project/forms/event.py:139 project/templates/_macros.html:267 +#: project/templates/layout.html:157 msgid "Booked up" msgstr "" -#: project/forms/event.py:146 +#: project/forms/event.py:141 msgid "If the event is booked up or sold out." msgstr "" -#: project/forms/event.py:149 +#: project/forms/event.py:144 msgid "Expected number of participants" msgstr "" -#: project/forms/event.py:151 +#: project/forms/event.py:146 msgid "The estimated expected attendance." msgstr "" -#: project/forms/event.py:154 +#: project/forms/event.py:149 msgid "Price info" msgstr "" -#: project/forms/event.py:156 +#: project/forms/event.py:151 msgid "" "Enter price information in textual form. E.g., different prices for " "adults and children." msgstr "" -#: project/forms/event.py:161 +#: project/forms/event.py:156 msgid "Target group origin" msgstr "Suitable for tourists / residents" -#: project/forms/event.py:166 +#: project/forms/event.py:161 msgid "EventTargetGroupOrigin.both" msgstr "For tourists and residents" -#: project/forms/event.py:170 +#: project/forms/event.py:165 msgid "EventTargetGroupOrigin.tourist" msgstr "Mainly for tourists" -#: project/forms/event.py:174 +#: project/forms/event.py:169 msgid "EventTargetGroupOrigin.resident" msgstr "Mainly for residents" -#: project/forms/event.py:177 +#: project/forms/event.py:172 msgid "" "Choose whether the event is particularly suitable for tourists or " "residents." msgstr "" -#: project/forms/event.py:182 +#: project/forms/event.py:177 msgid "Attendance mode" msgstr "" -#: project/forms/event.py:187 +#: project/forms/event.py:182 msgid "EventAttendanceMode.offline" msgstr "Normal (Offline)" -#: project/forms/event.py:191 project/templates/layout.html:143 +#: project/forms/event.py:186 project/templates/layout.html:145 msgid "EventAttendanceMode.online" msgstr "Online" -#: project/forms/event.py:193 project/templates/layout.html:146 +#: project/forms/event.py:188 project/templates/layout.html:148 msgid "EventAttendanceMode.mixed" msgstr "Online and offline" -#: project/forms/event.py:195 +#: project/forms/event.py:190 msgid "Choose how people can attend the event." msgstr "" -#: project/forms/event.py:199 project/forms/event_place.py:27 +#: project/forms/event.py:194 project/forms/event_place.py:27 #: project/templates/widget/event_suggestion/create.html:219 msgid "Photo" msgstr "" -#: project/forms/event.py:201 +#: project/forms/event.py:196 msgid "" "We recommend uploading a photo for the event. It looks a lot more, but of" " course it works without it." msgstr "" -#: project/forms/event.py:211 project/templates/_macros.html:1184 +#: project/forms/event.py:206 project/templates/_macros.html:1184 msgid "The start must be before the end." msgstr "" -#: project/forms/event.py:217 project/templates/_macros.html:1201 +#: project/forms/event.py:212 project/templates/_macros.html:1201 msgid "An event can last a maximum of 14 days." msgstr "" -#: project/forms/event.py:225 project/templates/_macros.html:414 +#: project/forms/event.py:220 project/templates/_macros.html:414 #: project/templates/_macros.html:573 msgid "Previous start date" msgstr "" -#: project/forms/event.py:227 +#: project/forms/event.py:222 msgid "Enter when the event should have taken place before it was postponed." msgstr "" -#: project/forms/event.py:232 project/forms/event_suggestion.py:71 +#: project/forms/event.py:227 project/forms/event_suggestion.py:71 msgid "Categories" msgstr "" -#: project/forms/event.py:235 project/forms/event_suggestion.py:74 +#: project/forms/event.py:230 project/forms/event_suggestion.py:74 msgid "Choose categories that fit the event." msgstr "" -#: project/forms/event.py:238 project/forms/reference.py:14 +#: project/forms/event.py:233 project/forms/reference.py:14 #: project/forms/reference.py:27 project/forms/reference_request.py:70 -#: project/templates/event/create.html:193 -#: project/templates/event/update.html:158 +#: project/templates/event/create.html:318 +#: project/templates/event/update.html:183 msgid "Rating" msgstr "" -#: project/forms/event.py:242 project/forms/reference.py:18 +#: project/forms/event.py:237 project/forms/reference.py:18 #: project/forms/reference.py:31 project/forms/reference_request.py:74 msgid "" "Choose how relevant the event is to your organization. The value is not " "visible and is used for sorting." msgstr "" -#: project/forms/event.py:250 project/forms/event.py:259 -#: project/forms/event.py:319 project/forms/event_suggestion.py:50 +#: project/forms/event.py:245 project/forms/event.py:254 +#: project/forms/event.py:314 project/forms/event_suggestion.py:50 #: project/templates/_macros.html:453 project/templates/_macros.html:609 -#: project/templates/event/create.html:124 -#: project/templates/event/update.html:108 +#: project/templates/event/create.html:243 +#: project/templates/event/update.html:133 #: project/templates/event_place/create.html:21 #: project/templates/event_place/delete.html:13 #: project/templates/event_place/update.html:21 msgid "Place" msgstr "" -#: project/forms/event.py:252 +#: project/forms/event.py:247 msgid "Select existing place" msgstr "" -#: project/forms/event.py:253 +#: project/forms/event.py:248 msgid "Enter new place" msgstr "" -#: project/forms/event.py:266 project/forms/event.py:275 -#: project/forms/event.py:327 project/forms/event.py:377 +#: project/forms/event.py:261 project/forms/event.py:270 +#: project/forms/event.py:322 project/forms/event.py:372 #: project/forms/event_suggestion.py:60 project/templates/_macros.html:491 -#: project/templates/_macros.html:646 project/templates/event/create.html:99 -#: project/templates/event/update.html:99 +#: project/templates/_macros.html:646 project/templates/event/create.html:218 +#: project/templates/event/update.html:124 #: project/templates/organizer/create.html:17 #: project/templates/organizer/delete.html:13 #: project/templates/organizer/update.html:17 msgid "Organizer" msgstr "" -#: project/forms/event.py:268 +#: project/forms/event.py:263 msgid "Select existing organizer" msgstr "" -#: project/forms/event.py:269 +#: project/forms/event.py:264 msgid "Enter new organizer" msgstr "" -#: project/forms/event.py:281 project/templates/event/create.html:4 -#: project/templates/event/create.html:71 +#: project/forms/event.py:276 project/templates/event/create.html:4 +#: project/templates/event/create.html:190 #: project/templates/manage/events.html:12 #: project/templates/manage/organizers.html:21 msgid "Create event" msgstr "" -#: project/forms/event.py:305 +#: project/forms/event.py:300 msgid "Select existing place or enter new place" msgstr "" -#: project/forms/event.py:310 +#: project/forms/event.py:305 msgid "Select existing organizer or enter new organizer" msgstr "" -#: project/forms/event.py:322 +#: project/forms/event.py:317 msgid "" "Choose where the event takes place. You can add and modify places at " "Manage > Places." msgstr "" -#: project/forms/event.py:330 +#: project/forms/event.py:325 msgid "" "Select the organizer. You can add and modify organizers at Manage > " "Organizers." msgstr "" -#: project/forms/event.py:336 project/templates/event/update.html:89 +#: project/forms/event.py:331 project/templates/event/update.html:114 #: project/templates/oauth2_token/list.html:21 msgid "Status" msgstr "" -#: project/forms/event.py:339 +#: project/forms/event.py:334 msgid "EventStatus.scheduled" msgstr "Scheduled" -#: project/forms/event.py:340 project/templates/layout.html:109 -#: project/templates/layout.html:124 +#: project/forms/event.py:335 project/templates/layout.html:111 +#: project/templates/layout.html:126 msgid "EventStatus.cancelled" msgstr "Cancelled" -#: project/forms/event.py:341 project/templates/layout.html:112 -#: project/templates/layout.html:127 +#: project/forms/event.py:336 project/templates/layout.html:114 +#: project/templates/layout.html:129 msgid "EventStatus.movedOnline" msgstr "Moved online" -#: project/forms/event.py:342 project/templates/layout.html:115 -#: project/templates/layout.html:130 +#: project/forms/event.py:337 project/templates/layout.html:117 +#: project/templates/layout.html:132 msgid "EventStatus.postponed" msgstr "Postponed" -#: project/forms/event.py:343 project/templates/layout.html:118 -#: project/templates/layout.html:133 +#: project/forms/event.py:338 project/templates/layout.html:120 +#: project/templates/layout.html:135 msgid "EventStatus.rescheduled" msgstr "Rescheduled" -#: project/forms/event.py:345 +#: project/forms/event.py:340 msgid "Select the status of the event." msgstr "" -#: project/forms/event.py:348 project/templates/event/update.html:4 -#: project/templates/event/update.html:61 +#: project/forms/event.py:343 project/templates/event/update.html:4 +#: project/templates/event/update.html:86 msgid "Update event" msgstr "" -#: project/forms/event.py:362 project/templates/_macros.html:1156 +#: project/forms/event.py:357 project/templates/_macros.html:1156 #: project/templates/event/actions.html:47 #: project/templates/event/delete.html:6 msgid "Delete event" msgstr "" -#: project/forms/event.py:370 project/forms/event_date.py:15 +#: project/forms/event.py:365 project/forms/event_date.py:15 #: project/forms/planing.py:14 msgid "From" msgstr "" -#: project/forms/event.py:371 project/forms/event_date.py:16 +#: project/forms/event.py:366 project/forms/event_date.py:16 #: project/forms/planing.py:15 msgid "to" msgstr "" -#: project/forms/event.py:372 project/forms/event_date.py:17 +#: project/forms/event.py:367 project/forms/event_date.py:17 msgid "Keyword" msgstr "" -#: project/forms/event.py:374 project/forms/event_date.py:19 +#: project/forms/event.py:369 project/forms/event_date.py:19 #: project/forms/planing.py:17 project/templates/_macros.html:377 msgid "Category" msgstr "" -#: project/forms/event.py:380 +#: project/forms/event.py:375 msgid "Find events" msgstr "" @@ -847,13 +847,13 @@ msgstr "" msgid "I would like to be notified by email after the review" msgstr "" -#: project/forms/event_suggestion.py:52 project/templates/event/create.html:129 +#: project/forms/event_suggestion.py:52 project/templates/event/create.html:248 msgid "" "Choose where the event takes place. If the venue is not yet in the list, " "just enter it." msgstr "" -#: project/forms/event_suggestion.py:62 project/templates/event/create.html:103 +#: project/forms/event_suggestion.py:62 project/templates/event/create.html:222 msgid "" "Select the organizer. If the organizer is not yet on the list, just enter" " it." @@ -1047,9 +1047,9 @@ msgstr "" #: project/templates/_macros.html:393 project/templates/_macros.html:569 #: project/templates/event/actions.html:12 -#: project/templates/event/create.html:78 +#: project/templates/event/create.html:197 #: project/templates/event/delete.html:13 -#: project/templates/event/update.html:68 +#: project/templates/event/update.html:93 #: project/templates/reference/delete.html:13 #: project/templates/widget/event_suggestion/create.html:197 msgid "Event" @@ -1175,7 +1175,7 @@ msgstr "" msgid "Other calendar" msgstr "" -#: project/templates/home.html:27 project/templates/layout.html:203 +#: project/templates/home.html:27 project/templates/layout.html:205 msgid "Manage" msgstr "" @@ -1184,22 +1184,22 @@ msgstr "" msgid "Register for free" msgstr "" -#: project/templates/event_place/read.html:22 project/templates/layout.html:206 +#: project/templates/event_place/read.html:22 project/templates/layout.html:208 #: project/templates/layout_manage.html:24 #: project/templates/manage/events.html:5 #: project/templates/manage/events.html:9 msgid "Events" msgstr "" -#: project/templates/layout.html:207 +#: project/templates/layout.html:209 msgid "Planing" msgstr "" -#: project/templates/layout.html:208 +#: project/templates/layout.html:210 msgid "Example" msgstr "" -#: project/templates/layout.html:217 +#: project/templates/layout.html:219 #: project/templates/oauth2_client/list.html:10 #: project/templates/oauth2_client/read.html:10 #: project/templates/oauth2_token/list.html:10 project/templates/profile.html:4 @@ -1209,15 +1209,15 @@ msgstr "" #: project/templates/admin/admin.html:3 project/templates/admin/admin.html:9 #: project/templates/admin/admin_units.html:10 -#: project/templates/admin/users.html:10 project/templates/layout.html:220 +#: project/templates/admin/users.html:10 project/templates/layout.html:222 msgid "Admin" msgstr "" -#: project/templates/layout.html:224 +#: project/templates/layout.html:226 msgid "Logout" msgstr "" -#: project/templates/developer/read.html:4 project/templates/layout.html:279 +#: project/templates/developer/read.html:4 project/templates/layout.html:281 #: project/templates/profile.html:29 msgid "Developer" msgstr "" @@ -1334,8 +1334,8 @@ msgstr "" #: project/templates/admin_unit/create.html:49 #: project/templates/admin_unit/update.html:50 -#: project/templates/event/create.html:181 -#: project/templates/event/update.html:146 +#: project/templates/event/create.html:306 +#: project/templates/event/update.html:171 #: project/templates/event_place/create.html:47 #: project/templates/event_place/update.html:47 #: project/templates/organizer/create.html:46 @@ -1440,18 +1440,32 @@ msgstr "" msgid "List all events of %(admin_unit_name)s" msgstr "" -#: project/templates/event/create.html:88 -#: project/templates/event/update.html:78 +#: project/templates/event/create.html:87 +#: project/templates/event/update.html:73 +msgid "Enter place or address" +msgstr "" + +#: project/templates/event/create.html:97 +#, python-format +msgid "Just use %(term)s" +msgstr "" + +#: project/templates/event/create.html:207 +#: project/templates/event/update.html:103 msgid "Event date" msgstr "" -#: project/templates/event/create.html:154 -#: project/templates/event/update.html:119 +#: project/templates/event/create.html:268 +msgid "Switch to place search" +msgstr "" + +#: project/templates/event/create.html:279 +#: project/templates/event/update.html:144 msgid "Access" msgstr "" -#: project/templates/event/create.html:168 -#: project/templates/event/update.html:133 +#: project/templates/event/create.html:293 +#: project/templates/event/update.html:158 msgid "Target group" msgstr "" @@ -1717,23 +1731,23 @@ msgstr "" msgid "Invitation successfully deleted" msgstr "" -#: project/views/event.py:166 +#: project/views/event.py:167 msgid "Event successfully created" msgstr "" -#: project/views/event.py:203 +#: project/views/event.py:207 msgid "Event successfully updated" msgstr "" -#: project/views/event.py:226 project/views/reference.py:162 +#: project/views/event.py:230 project/views/reference.py:162 msgid "Entered name does not match event name" msgstr "" -#: project/views/event.py:232 +#: project/views/event.py:236 msgid "Event successfully deleted" msgstr "" -#: project/views/event.py:369 +#: project/views/event.py:379 msgid "Referenced event changed" msgstr "" @@ -1762,14 +1776,22 @@ msgstr "" msgid "Event review status updated" msgstr "" -#: project/views/js.py:24 +#: project/views/js.py:27 msgid "Short name is already taken" msgstr "" -#: project/views/js.py:38 +#: project/views/js.py:41 msgid "An account already exists with this email." msgstr "" +#: project/views/js.py:66 +msgid "Places of organization" +msgstr "" + +#: project/views/js.py:74 +msgid "Places of Google Maps" +msgstr "" + #: project/views/oauth2_client.py:37 msgid "OAuth2 client successfully created" msgstr "" diff --git a/project/views/event.py b/project/views/event.py index 1dc267e..1ce4b4d 100644 --- a/project/views/event.py +++ b/project/views/event.py @@ -24,6 +24,7 @@ from project.models import ( Event, EventCategory, EventOrganizer, + EventPlace, EventReference, EventReviewStatus, EventSuggestion, @@ -38,8 +39,7 @@ from project.services.event import ( update_event, upsert_event_category, ) -from project.services.place import get_event_places -from project.utils import get_event_category_name +from project.utils import get_event_category_name, get_place_str from project.views.event_suggestion import send_event_suggestion_review_status_mail from project.views.utils import ( flash_errors, @@ -103,6 +103,7 @@ def event_create_for_admin_unit_id(id): admin_unit_id=admin_unit.id, category_ids=[upsert_event_category("Other").id] ) prepare_event_form(form, admin_unit) + form.organizer_id.choices.insert(0, (0, "")) # Vorlagen event_suggestion = None @@ -115,6 +116,7 @@ def event_create_for_admin_unit_id(id): event_template = Event.query.get_or_404(event_template_id) if not form.is_submitted(): form.process(obj=event_template) + prepare_event_place(form) if not event_template: event_suggestion_id = ( @@ -173,7 +175,10 @@ def event_create_for_admin_unit_id(id): else: flash_errors(form) return render_template( - "event/create.html", form=form, event_suggestion=event_suggestion + "event/create.html", + admin_unit=admin_unit, + form=form, + event_suggestion=event_suggestion, ) @@ -265,6 +270,14 @@ def get_event_category_choices(): ) +def prepare_event_place(form): + if form.event_place_id.data and form.event_place_id.data > 0: + place = EventPlace.query.get(form.event_place_id.data) + + if place: + form.event_place_id.choices = [(place.id, get_place_str(place))] + + def prepare_event_form(form, admin_unit): form.organizer_id.choices = [ (o.id, o.name) @@ -274,11 +287,7 @@ def prepare_event_form(form, admin_unit): ] form.category_ids.choices = get_event_category_choices() - places = get_event_places(admin_unit.id) - form.event_place_id.choices = [(p.id, p.name) for p in places] - - form.organizer_id.choices.insert(0, (0, "")) - form.event_place_id.choices.insert(0, (0, "")) + prepare_event_place(form) if not form.start.data: form.start.data = get_next_full_hour() @@ -323,6 +332,8 @@ def prepare_event_form_for_suggestion(form, event_suggestion): form.organizer_choice.data = 2 form.new_organizer.form.name.data = event_suggestion.organizer_text + prepare_event_place(form) + def update_event_with_form(event, form, event_suggestion=None): with db.session.no_autoflush: diff --git a/project/views/js.py b/project/views/js.py index 08a128b..5b902b7 100644 --- a/project/views/js.py +++ b/project/views/js.py @@ -1,11 +1,13 @@ -import json - from flask import request +from flask.json import jsonify from flask_babelex import gettext from project import app, csrf +from project.maputils import find_gmaps_places, get_gmaps_place from project.models import AdminUnit +from project.services.place import get_event_places from project.services.user import find_user_by_email +from project.utils import get_place_str @app.route("/js/check/organization/short_name", methods=["POST"]) @@ -19,10 +21,10 @@ def js_check_org_short_name(): organization = AdminUnit.query.filter(AdminUnit.short_name == short_name).first() if not organization or organization.id == admin_unit_id: - return json.dumps(True) + return jsonify(True) error = gettext("Short name is already taken") - return json.dumps(error) + return jsonify(error) @app.route("/js/check/register/email", methods=["POST"]) @@ -33,7 +35,62 @@ def js_check_register_email(): user = find_user_by_email(email) if not user: - return json.dumps(True) + return jsonify(True) error = gettext("An account already exists with this email.") - return json.dumps(error) + return jsonify(error) + + +@app.route("/js/autocomplete/place") +def js_autocomplete_place(): + csrf.protect() + + admin_unit_id = int(request.args["admin_unit_id"]) + keyword = request.args.get("keyword") + exclude_gmaps = request.args.get("exclude_gmaps") + + places = get_event_places(admin_unit_id, keyword, 5) + places_result = [{"id": p.id, "text": get_place_str(p)} for p in places] + + if exclude_gmaps: + results = places_result + else: + google_places = find_gmaps_places(keyword) if keyword else list() + + results = list() + + if len(places) > 0: + results.append( + { + "text": gettext("Places of organization"), + "children": places_result, + } + ) + + if len(google_places) > 0: + results.append( + { + "text": gettext("Places of Google Maps"), + "children": [ + { + "id": p["place_id"], + "gmaps_id": p["place_id"], + "text": p["description"], + "main_text": p["structured_formatting"]["main_text"], + } + for p in google_places + ], + } + ) + + result = {"results": results} + return jsonify(result) + + +@app.route("/js/autocomplete/gmaps_place") +def js_autocomplete_gmaps_place(): + csrf.protect() + + gmaps_id = request.args["gmaps_id"] + place = get_gmaps_place(gmaps_id) + return jsonify(place) diff --git a/requirements.txt b/requirements.txt index b87596d..9f17dc2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,7 +18,7 @@ cfgv==3.2.0 chardet==3.0.4 click==7.1.2 colour==0.1.5 -coverage==5.3 +coverage==5.5 coveralls==2.2.0 cryptography==3.3.2 distlib==0.3.1 @@ -46,6 +46,7 @@ Flask-Security-Too==4.0.0 Flask-SQLAlchemy==2.4.4 Flask-WTF==0.14.3 GeoAlchemy2==0.8.4 +googlemaps==4.4.7 gunicorn==20.0.4 icalendar==4.0.7 identify==1.5.10 diff --git a/tests/conftest.py b/tests/conftest.py index c6f4fad..ab191d7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -17,6 +17,7 @@ def pytest_generate_tests(metafunc): os.environ[ "JWT_PUBLIC_JWKS" ] = '{"keys":[{"kid":"default","kty":"RSA","use":"sig","alg":"RS256","n":"vy41pD9VTDVmGVxkeSPUDGuzULf0rfVFypnVnBO12l0V_fXU0Rdqf9qlSCklwSWFT7XcGRS9gDw_HGkbQ2qycmQ0-S2FbU65D3VKR1amqtMgonDFwNinoCEBfh6H52RpvduKmdMZ3PfhqTZP5rStxs7uHuAa-BBzqCl4fTBcwB-sDM-lE5tPuGkoXCZAEllw7G5lHKETZJt2dsvf0aBlPSb-pITQkLLSC1OjbAHmo3h7PP1yQU0qnHsCJv7BhGIFTy3cfvbsa1QdNxI3VHg7ZP2vs-JFm4cDxdk-nft8dDnP8z42kha0iqiLAWDLOyyk-kP7EHvn0jgpZM6N6tzJxw","e":"AQAB"}]}' + os.environ["GOOGLE_MAPS_API_KEY"] = "AIzaDummy" @pytest.fixture @@ -49,8 +50,8 @@ def client(app, db): @pytest.fixture -def utils(client, app): - return UtilActions(client, app) +def utils(client, app, mocker): + return UtilActions(client, app, mocker) @pytest.fixture diff --git a/tests/utils.py b/tests/utils.py index ebedecf..9115ccc 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,21 +1,30 @@ import re from urllib.parse import parse_qs, urlsplit +import googlemaps from bs4 import BeautifulSoup from flask import g, url_for from sqlalchemy.exc import IntegrityError class UtilActions(object): - def __init__(self, client, app): + def __init__(self, client, app, mocker): self._client = client self._app = app + self._mocker = mocker self._access_token = None self._refresh_token = None self._client_id = None self._client_secret = None self._ajax_csrf = None + self.gmaps_places_autocomplete_query = self._mocker.patch.object( + googlemaps.Client, "places_autocomplete_query", return_value=list() + ) + self.gmaps_place = self._mocker.patch.object( + googlemaps.Client, "place", return_value=dict() + ) + def get_access_token(self): return self._access_token diff --git a/tests/views/test_js.py b/tests/views/test_js.py index fab0394..9f183d9 100644 --- a/tests/views/test_js.py +++ b/tests/views/test_js.py @@ -1,3 +1,7 @@ +from tests.seeder import Seeder +from tests.utils import UtilActions + + def test_js_check_org_short_name(client, seeder, utils): seeder.create_user(admin=True) utils.login() @@ -14,7 +18,7 @@ def test_js_check_org_short_name(client, seeder, utils): }, ) utils.assert_response_ok(response) - assert response.data == b"true" + assert response.json def test_js_check_org_short_name_exists(client, seeder, utils): @@ -34,7 +38,7 @@ def test_js_check_org_short_name_exists(client, seeder, utils): }, ) utils.assert_response_ok(response) - assert response.data == b'"Der Kurzname ist bereits vergeben"' + assert response.json == "Der Kurzname ist bereits vergeben" def test_js_js_check_register_email(client, seeder, utils): @@ -50,7 +54,7 @@ def test_js_js_check_register_email(client, seeder, utils): }, ) utils.assert_response_ok(response) - assert response.data == b"true" + assert response.json def test_js_js_check_register_email_exists(client, seeder, utils): @@ -70,4 +74,74 @@ def test_js_js_check_register_email_exists(client, seeder, utils): }, ) utils.assert_response_ok(response) - assert response.data == b'"Mit dieser E-Mail existiert bereits ein Account."' + assert response.json == "Mit dieser E-Mail existiert bereits ein Account." + + +def test_js_autocomplete_place(client, seeder: Seeder, utils: UtilActions): + user_id, admin_unit_id = seeder.setup_base() + seeder.upsert_default_event_place(admin_unit_id) + + url = utils.get_url("event_create_for_admin_unit_id", id=admin_unit_id) + response = utils.get(url) + + utils.gmaps_places_autocomplete_query.return_value = [ + { + "place_id": "123", + "description": "Beschreibung", + "structured_formatting": {"main_text": "Haupttext"}, + } + ] + + with client: + url = utils.get_url( + "js_autocomplete_place", admin_unit_id=admin_unit_id, keyword="crew" + ) + response = utils.get(url) + + utils.assert_response_ok(response) + assert response.json["results"][0]["children"][0]["text"] == "Meine Crew" + assert response.json["results"][1]["children"][0]["text"] == "Beschreibung" + + +def test_js_autocomplete_place_exclude_gmaps( + client, seeder: Seeder, utils: UtilActions +): + user_id, admin_unit_id = seeder.setup_base() + seeder.upsert_default_event_place(admin_unit_id) + + url = utils.get_url("event_create_for_admin_unit_id", id=admin_unit_id) + response = utils.get(url) + + with client: + url = utils.get_url( + "js_autocomplete_place", + admin_unit_id=admin_unit_id, + keyword="crew", + exclude_gmaps=1, + ) + response = utils.get(url) + + utils.assert_response_ok(response) + assert response.json["results"][0]["text"] == "Meine Crew" + + +def test_js_autocomplete_gmaps_place(client, seeder: Seeder, utils: UtilActions): + user_id, admin_unit_id = seeder.setup_base() + seeder.upsert_default_event_place(admin_unit_id) + + url = utils.get_url("event_create_for_admin_unit_id", id=admin_unit_id) + response = utils.get(url) + + utils.gmaps_place.return_value = { + "status": "OK", + "result": { + "place_id": "123", + }, + } + + with client: + url = utils.get_url("js_autocomplete_gmaps_place", gmaps_id="123") + response = utils.get(url) + + utils.assert_response_ok(response) + assert response.json["place_id"] == "123"