issue submission forms
This commit is contained in:
parent
e7fc0f24ae
commit
52c02a4101
18 changed files with 652 additions and 79 deletions
|
@ -283,7 +283,7 @@ def create_editor_form(editor_model):
|
|||
'outside', 'can_search', 'can_describe', 'geometry', 'single', 'altitude', 'short_label',
|
||||
'origin_space', 'target_space', 'data', 'comment', 'slow_down_factor',
|
||||
'extra_seconds', 'speed', 'description', 'speed_up', 'description_up', 'enter_description',
|
||||
'level_change_description', 'base_mapdata_accessible',
|
||||
'level_change_description', 'base_mapdata_accessible', 'can_report_missing',
|
||||
'label_settings', 'label_override', 'min_zoom', 'max_zoom', 'font_size',
|
||||
'allow_levels', 'allow_spaces', 'allow_areas', 'allow_pois', 'left', 'top', 'right', 'bottom']
|
||||
field_names = [field.name for field in editor_model._meta.get_fields() if not field.one_to_many]
|
||||
|
|
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-12-24 03:50+0100\n"
|
||||
"POT-Creation-Date: 2019-12-24 17:22+0100\n"
|
||||
"PO-Revision-Date: 2019-12-22 00:44+0100\n"
|
||||
"Last-Translator: Jenny Danzmayr <mail@evilscientress.at>\n"
|
||||
"Language-Team: \n"
|
||||
|
@ -42,7 +42,7 @@ msgstr "Nich angemeldet."
|
|||
msgid "Logout successful."
|
||||
msgstr "Login erfolgreich."
|
||||
|
||||
#: c3nav/api/models.py:14
|
||||
#: c3nav/api/models.py:14 c3nav/mapdata/models/report.py:79
|
||||
msgid "secret"
|
||||
msgstr "secret"
|
||||
|
||||
|
@ -514,6 +514,7 @@ msgstr "zurück"
|
|||
|
||||
#: c3nav/control/templates/control/user.html:73
|
||||
#: c3nav/mapdata/models/access.py:77 c3nav/mapdata/models/geometry/space.py:385
|
||||
#: c3nav/mapdata/models/report.py:58 c3nav/mapdata/models/report.py:109
|
||||
#: c3nav/site/models.py:17
|
||||
msgid "author"
|
||||
msgstr "Autor"
|
||||
|
@ -788,8 +789,8 @@ msgid "Change Set"
|
|||
msgstr "Änderungsset"
|
||||
|
||||
#: c3nav/editor/models/changedobject.py:35 c3nav/editor/models/changeset.py:39
|
||||
#: c3nav/editor/views/changes.py:266 c3nav/site/models.py:14
|
||||
#: c3nav/site/models.py:54
|
||||
#: c3nav/editor/views/changes.py:266 c3nav/mapdata/models/report.py:56
|
||||
#: c3nav/site/models.py:14 c3nav/site/models.py:54
|
||||
msgid "created"
|
||||
msgstr "erstellt"
|
||||
|
||||
|
@ -863,7 +864,7 @@ msgstr "letzte Statusänderung"
|
|||
|
||||
#: c3nav/editor/models/changeset.py:48 c3nav/mapdata/models/base.py:64
|
||||
#: c3nav/mapdata/models/graph.py:38 c3nav/mapdata/models/locations.py:256
|
||||
#: c3nav/mapdata/models/locations.py:421 c3nav/mapdata/utils/locations.py:344
|
||||
#: c3nav/mapdata/models/locations.py:423 c3nav/mapdata/utils/locations.py:344
|
||||
msgid "Title"
|
||||
msgstr "Titel"
|
||||
|
||||
|
@ -871,7 +872,8 @@ msgstr "Titel"
|
|||
msgid "Description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
#: c3nav/editor/models/changeset.py:51
|
||||
#: c3nav/editor/models/changeset.py:51 c3nav/mapdata/models/report.py:66
|
||||
#: c3nav/mapdata/models/report.py:113
|
||||
msgid "assigned to"
|
||||
msgstr "zugewiesen"
|
||||
|
||||
|
@ -898,7 +900,7 @@ msgid_plural "%(num)d objects changed"
|
|||
msgstr[0] "%(num)d Objekt geändert"
|
||||
msgstr[1] "%(num)d Objekte geändert"
|
||||
|
||||
#: c3nav/editor/models/changesetupdate.py:12
|
||||
#: c3nav/editor/models/changesetupdate.py:12 c3nav/mapdata/models/report.py:108
|
||||
msgid "datetime"
|
||||
msgstr "Zeitpunkt"
|
||||
|
||||
|
@ -1150,7 +1152,7 @@ msgid "Log out"
|
|||
msgstr "Abmelden"
|
||||
|
||||
#: c3nav/editor/templates/editor/fragment_nav.html:23
|
||||
#: c3nav/editor/views/account.py:27 c3nav/site/views.py:227
|
||||
#: c3nav/editor/views/account.py:27 c3nav/site/views.py:232
|
||||
msgid "Log in"
|
||||
msgstr "Anmelden"
|
||||
|
||||
|
@ -1277,7 +1279,7 @@ msgid "Activate direct editing"
|
|||
msgstr "Direktes Bearbeiten aktivieren"
|
||||
|
||||
#: c3nav/editor/templates/editor/user.html:54 c3nav/editor/views/account.py:85
|
||||
#: c3nav/site/templates/site/account.html:29 c3nav/site/views.py:292
|
||||
#: c3nav/site/templates/site/account.html:29 c3nav/site/views.py:297
|
||||
msgid "Change password"
|
||||
msgstr "Passwort ändern"
|
||||
|
||||
|
@ -1298,11 +1300,11 @@ msgid "All recent change sets"
|
|||
msgstr "Alle kürzlichen Änderungssets"
|
||||
|
||||
#: c3nav/editor/views/account.py:30 c3nav/editor/views/account.py:61
|
||||
#: c3nav/site/views.py:234 c3nav/site/views.py:269
|
||||
#: c3nav/site/views.py:239 c3nav/site/views.py:274
|
||||
msgid "Create new account"
|
||||
msgstr "Neues Konto erstellen"
|
||||
|
||||
#: c3nav/editor/views/account.py:75 c3nav/site/views.py:283
|
||||
#: c3nav/editor/views/account.py:75 c3nav/site/views.py:288
|
||||
msgid "Password successfully changed."
|
||||
msgstr "Passwort erfolgreich geändert."
|
||||
|
||||
|
@ -1509,7 +1511,7 @@ msgstr "Invalides GeoJSON."
|
|||
msgid "Could not clean geometry."
|
||||
msgstr "Konnte Geometrie nicht bereinigen."
|
||||
|
||||
#: c3nav/mapdata/forms.py:54
|
||||
#: c3nav/mapdata/forms.py:55
|
||||
#, python-brace-format
|
||||
msgid "You have to choose a value for {field} in at least one language."
|
||||
msgstr "Du must das Feld {field} in mindestens einer Sprache ausfüllen."
|
||||
|
@ -1679,9 +1681,11 @@ msgstr "Werte zurücksetzen"
|
|||
msgid "save result to the stats directory"
|
||||
msgstr "Ergebnis im stats-Ordner speichern"
|
||||
|
||||
#: c3nav/mapdata/models/access.py:23
|
||||
#: c3nav/mapdata/models/access.py:23 c3nav/mapdata/models/report.py:59
|
||||
#: c3nav/mapdata/models/report.py:110
|
||||
#: c3nav/site/templates/site/report_detail.html:9
|
||||
msgid "open"
|
||||
msgstr "öffnen"
|
||||
msgstr "offen"
|
||||
|
||||
#: c3nav/mapdata/models/access.py:24
|
||||
msgid "Groups"
|
||||
|
@ -1723,8 +1727,8 @@ msgstr "Zugangserlaubnis-Token"
|
|||
msgid "Access Permission Tokens"
|
||||
msgstr "Zugangserlaubnis-Token"
|
||||
|
||||
#: c3nav/mapdata/models/access.py:133 c3nav/site/views.py:79
|
||||
#: c3nav/site/views.py:326
|
||||
#: c3nav/mapdata/models/access.py:133 c3nav/site/views.py:84
|
||||
#: c3nav/site/views.py:331
|
||||
msgid "Area successfully unlocked."
|
||||
msgid_plural "Areas successfully unlocked."
|
||||
msgstr[0] "Bereich erfolgreich freigeschaltet."
|
||||
|
@ -1976,6 +1980,7 @@ msgstr "Zielraum"
|
|||
|
||||
#: c3nav/mapdata/models/geometry/space.py:308
|
||||
#: c3nav/mapdata/models/geometry/space.py:347 c3nav/mapdata/models/graph.py:48
|
||||
#: c3nav/mapdata/models/report.py:63
|
||||
msgid "description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
|
@ -2000,6 +2005,7 @@ msgid "Cross descriptions"
|
|||
msgstr "Durchschreitungsbeschreibungen"
|
||||
|
||||
#: c3nav/mapdata/models/geometry/space.py:386
|
||||
#: c3nav/mapdata/models/report.py:111
|
||||
msgid "comment"
|
||||
msgstr "Kommentar"
|
||||
|
||||
|
@ -2159,7 +2165,7 @@ msgstr "name eines material icons"
|
|||
msgid "searchable"
|
||||
msgstr "suchbar"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:162 c3nav/mapdata/models/locations.py:321
|
||||
#: c3nav/mapdata/models/locations.py:162 c3nav/mapdata/models/locations.py:323
|
||||
msgid "Location Groups"
|
||||
msgstr "Ortgruppen"
|
||||
|
||||
|
@ -2215,7 +2221,7 @@ msgstr "Ortgruppenkategorie"
|
|||
msgid "Location Group Categories"
|
||||
msgstr "Ortgruppenkategorien"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:309 c3nav/mapdata/models/locations.py:342
|
||||
#: c3nav/mapdata/models/locations.py:309 c3nav/mapdata/models/locations.py:344
|
||||
msgid "Category"
|
||||
msgstr "Kategorie"
|
||||
|
||||
|
@ -2228,65 +2234,162 @@ msgid "unless location specifies otherwise"
|
|||
msgstr "kann von Orten überschrieben werden"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:315
|
||||
msgid "for missing locations"
|
||||
msgstr "for fehlende Orte"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:316
|
||||
msgid "can be used when reporting a missing location"
|
||||
msgstr "kann beim melden eines fehlenden Ortges genutzt werden"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:317
|
||||
msgid "background color"
|
||||
msgstr "Hintergrundfarbe"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:320
|
||||
#: c3nav/mapdata/models/locations.py:322
|
||||
msgid "Location Group"
|
||||
msgstr "Ortgruppe"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:344 c3nav/mapdata/models/locations.py:359
|
||||
#: c3nav/mapdata/models/locations.py:346 c3nav/mapdata/models/locations.py:361
|
||||
msgid "color"
|
||||
msgstr "Farbe"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:345
|
||||
#: c3nav/mapdata/models/locations.py:347
|
||||
msgid "priority"
|
||||
msgstr "Priorität"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:355
|
||||
#: c3nav/mapdata/models/locations.py:357
|
||||
msgid "search"
|
||||
msgstr "suchen"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:357
|
||||
#: c3nav/mapdata/models/locations.py:359
|
||||
msgid "describe"
|
||||
msgstr "beschreiben"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:361
|
||||
#: c3nav/mapdata/models/locations.py:363
|
||||
msgid "internal"
|
||||
msgstr "intern"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:378
|
||||
#: c3nav/mapdata/models/locations.py:380
|
||||
#, python-brace-format
|
||||
msgid "{category_title}, {num_locations}"
|
||||
msgstr "{category_title}, {num_locations}"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:380
|
||||
#: c3nav/mapdata/models/locations.py:382
|
||||
#, python-format
|
||||
msgid "%(num)d location"
|
||||
msgid_plural "%(num)d locations"
|
||||
msgstr[0] "%(num)d Ort"
|
||||
msgstr[1] "%(num)d Orte"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:403
|
||||
#: c3nav/mapdata/models/locations.py:405
|
||||
msgid "target"
|
||||
msgstr "Ziel"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:422
|
||||
#: c3nav/mapdata/models/locations.py:424
|
||||
msgid "min zoom"
|
||||
msgstr "Mindestzoom"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:425
|
||||
#: c3nav/mapdata/models/locations.py:427
|
||||
msgid "max zoom"
|
||||
msgstr "Maximalzoom"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:428
|
||||
#: c3nav/mapdata/models/locations.py:430
|
||||
msgid "font size"
|
||||
msgstr "Schriftgröße"
|
||||
|
||||
#: c3nav/mapdata/models/locations.py:444 c3nav/mapdata/models/locations.py:445
|
||||
#: c3nav/mapdata/models/locations.py:446 c3nav/mapdata/models/locations.py:447
|
||||
msgid "Label Settings"
|
||||
msgstr "Labeleinstellungen"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:52
|
||||
msgid "location issue"
|
||||
msgstr "Ortfehler"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:53
|
||||
msgid "missing location"
|
||||
msgstr "fehlender Ort"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:54
|
||||
msgid "route issue"
|
||||
msgstr "Routenfehler"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:57
|
||||
msgid "category"
|
||||
msgstr "Kategorie"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:60
|
||||
msgid "last_update"
|
||||
msgstr "letzte Anderung"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:61
|
||||
msgid "title"
|
||||
msgstr "Titel"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:62
|
||||
msgid "a short title for your report"
|
||||
msgstr "ein kurzer Titel für deine Meldung"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:64
|
||||
msgid "tell us precisely what's wrong"
|
||||
msgstr "Sag uns im Detail was falsch ist"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:68
|
||||
msgid "location"
|
||||
msgstr "Ort"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:69
|
||||
msgid "coordinates"
|
||||
msgstr "Koordinaten"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:70
|
||||
msgid "origin"
|
||||
msgstr "Start"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:71
|
||||
msgid "destination"
|
||||
msgstr "Ziel"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:72
|
||||
msgid "route options"
|
||||
msgstr "Routenoptionen"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:74
|
||||
msgid "new location title"
|
||||
msgstr "Neuer Ortstitel"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:75
|
||||
msgid "you have to supply a title in at least one language"
|
||||
msgstr "Du must das Feld {field} in mindestens einer Sprache ausfüllen."
|
||||
|
||||
#: c3nav/mapdata/models/report.py:76
|
||||
msgid "location groups"
|
||||
msgstr "Ortgruppen"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:78
|
||||
msgid "select all groups that apply, if any"
|
||||
msgstr ""
|
||||
|
||||
#: c3nav/mapdata/models/report.py:86
|
||||
#: c3nav/site/templates/site/report_detail.html:6
|
||||
msgid "Report"
|
||||
msgstr "Meldung"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:87
|
||||
msgid "Reports"
|
||||
msgstr "Meldungen"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:114
|
||||
msgid "public"
|
||||
msgstr "öffentlich"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:117
|
||||
msgid "Report update"
|
||||
msgstr "Meldungsupdate"
|
||||
|
||||
#: c3nav/mapdata/models/report.py:118
|
||||
msgid "Report updates"
|
||||
msgstr "Meldungsupdates"
|
||||
|
||||
#: c3nav/mapdata/models/source.py:18
|
||||
msgid "Source"
|
||||
msgstr "Vorlage"
|
||||
|
@ -2408,7 +2511,7 @@ msgstr "Unerreichbarer Ort."
|
|||
msgid "No route found."
|
||||
msgstr "Keine Route gefunden."
|
||||
|
||||
#: c3nav/routing/api.py:110
|
||||
#: c3nav/routing/api.py:109
|
||||
msgid "Invalid scan data."
|
||||
msgstr "Invalide Scandaten."
|
||||
|
||||
|
@ -2456,65 +2559,66 @@ msgstr "Invalider Scan. Unerlaubte Frequenz."
|
|||
msgid "Invalid Scan. Invalid last timestamp."
|
||||
msgstr "Invalider Scan. Letzter Zeitstempel ungültig."
|
||||
|
||||
#: c3nav/routing/models.py:21 c3nav/routing/models.py:22
|
||||
#: c3nav/routing/models.py:20 c3nav/routing/models.py:21
|
||||
#: c3nav/site/templates/site/fragment_report_meta.html:17
|
||||
#: c3nav/site/templates/site/map.html:177
|
||||
msgid "Route options"
|
||||
msgstr "Routenoptionen"
|
||||
|
||||
#: c3nav/routing/models.py:33
|
||||
#: c3nav/routing/models.py:32
|
||||
msgid "Routing mode"
|
||||
msgstr "Routemodus"
|
||||
|
||||
#: c3nav/routing/models.py:34
|
||||
#: c3nav/routing/models.py:33
|
||||
msgid "fastest"
|
||||
msgstr "schnellste"
|
||||
|
||||
#: c3nav/routing/models.py:34
|
||||
#: c3nav/routing/models.py:33
|
||||
msgid "shortest"
|
||||
msgstr "kürzeste"
|
||||
|
||||
#: c3nav/routing/models.py:38
|
||||
#: c3nav/routing/models.py:37
|
||||
msgid "Walk speed"
|
||||
msgstr "Gehgeschwindigkeit"
|
||||
|
||||
#: c3nav/routing/models.py:39
|
||||
#: c3nav/routing/models.py:38
|
||||
msgid "slow"
|
||||
msgstr "langsam"
|
||||
|
||||
#: c3nav/routing/models.py:39
|
||||
#: c3nav/routing/models.py:38
|
||||
msgid "default"
|
||||
msgstr "standard"
|
||||
|
||||
#: c3nav/routing/models.py:39
|
||||
#: c3nav/routing/models.py:38
|
||||
msgid "fast"
|
||||
msgstr "schnell"
|
||||
|
||||
#: c3nav/routing/models.py:45
|
||||
#: c3nav/routing/models.py:44
|
||||
msgid "allow"
|
||||
msgstr "erlaubt"
|
||||
|
||||
#: c3nav/routing/models.py:47
|
||||
#: c3nav/routing/models.py:46
|
||||
msgid "avoid upwards"
|
||||
msgstr "aufwärts vermeiden"
|
||||
|
||||
#: c3nav/routing/models.py:48
|
||||
#: c3nav/routing/models.py:47
|
||||
msgid "avoid downwards"
|
||||
msgstr "abwärts vermeiden"
|
||||
|
||||
#: c3nav/routing/models.py:49
|
||||
#: c3nav/routing/models.py:48
|
||||
msgid "avoid completely"
|
||||
msgstr "komplett vermeiden"
|
||||
|
||||
#: c3nav/routing/models.py:51
|
||||
#: c3nav/routing/models.py:50
|
||||
msgid "avoid"
|
||||
msgstr "vermeiden"
|
||||
|
||||
#: c3nav/routing/models.py:144
|
||||
#: c3nav/routing/models.py:143
|
||||
#, python-format
|
||||
msgid "Unknown route option: %s"
|
||||
msgstr "Unbekannte Routenoption: %s"
|
||||
|
||||
#: c3nav/routing/models.py:148
|
||||
#: c3nav/routing/models.py:147
|
||||
#, python-format
|
||||
msgid "Invalid value for route option %s."
|
||||
msgstr "Invalider Wert für Routenoption %s."
|
||||
|
@ -2658,6 +2762,26 @@ msgstr "Du bist angemeldet als <strong>%(username)s</strong>."
|
|||
msgid "You can access the control panel."
|
||||
msgstr "Du kannst das Control Panel betreten."
|
||||
|
||||
#: c3nav/site/templates/site/fragment_report_meta.html:3
|
||||
msgid "You are reporting an issue with the following location:"
|
||||
msgstr "Du meldest einen Fehler beim folgenden Ort:"
|
||||
|
||||
#: c3nav/site/templates/site/fragment_report_meta.html:6
|
||||
msgid "You are reporting an missing location at the following position:"
|
||||
msgstr "Du meldest einen fehlenden Ort an der folgenden Stelle."
|
||||
|
||||
#: c3nav/site/templates/site/fragment_report_meta.html:9
|
||||
msgid "You are reporting an issue with the following route:"
|
||||
msgstr "Du meldest einen Fehler bei der folgenden Route:"
|
||||
|
||||
#: c3nav/site/templates/site/fragment_report_meta.html:11
|
||||
msgid "Origin"
|
||||
msgstr "Start"
|
||||
|
||||
#: c3nav/site/templates/site/fragment_report_meta.html:14
|
||||
msgid "Destination"
|
||||
msgstr "Ziel"
|
||||
|
||||
#: c3nav/site/templates/site/language.html:7
|
||||
msgid "Pick your language"
|
||||
msgstr "Sprache wählen"
|
||||
|
@ -2697,11 +2821,11 @@ msgstr "Route von hier aus"
|
|||
|
||||
#: c3nav/site/templates/site/map.html:52 c3nav/site/templates/site/map.html:149
|
||||
#: c3nav/site/templates/site/map.html:170
|
||||
#: c3nav/site/templates/site/report_create.html:6
|
||||
msgid "Report issue"
|
||||
msgstr "Fehler melden"
|
||||
|
||||
#: c3nav/site/templates/site/map.html:56 c3nav/site/templates/site/map.html:153
|
||||
#| msgid "Select this location"
|
||||
msgid "Report missing location"
|
||||
msgstr "Fehlenden Ort melden"
|
||||
|
||||
|
@ -2770,39 +2894,70 @@ msgstr ""
|
|||
msgid "open in c3nav"
|
||||
msgstr "in c3nav öffnen"
|
||||
|
||||
#: c3nav/site/templates/site/report.html:6
|
||||
msgid "Coming soon"
|
||||
msgstr "Coming soon"
|
||||
#: c3nav/site/templates/site/report_create.html:13
|
||||
msgid "Submit"
|
||||
msgstr "Absenden"
|
||||
|
||||
#: c3nav/site/views.py:71 c3nav/site/views.py:318
|
||||
#: c3nav/site/templates/site/report_detail.html:11
|
||||
msgid "closed"
|
||||
msgstr "geschlossen"
|
||||
|
||||
#: c3nav/site/templates/site/report_detail.html:15
|
||||
msgid "anonymous submission"
|
||||
msgstr "anonyme Meldung"
|
||||
|
||||
#: c3nav/site/templates/site/report_detail.html:17
|
||||
msgid "by"
|
||||
msgstr "von"
|
||||
|
||||
#: c3nav/site/templates/site/report_detail.html:35
|
||||
msgid "(none)"
|
||||
msgstr "(keine)"
|
||||
|
||||
#: c3nav/site/views.py:76 c3nav/site/views.py:323
|
||||
msgid "You need to log in to unlock areas."
|
||||
msgstr "Du musst dich anmelden um Bereiche freizuschalten."
|
||||
|
||||
#: c3nav/site/views.py:206
|
||||
#: c3nav/site/views.py:211
|
||||
msgid "Areas could not be unlocked because the token has expired."
|
||||
msgstr ""
|
||||
"Zugangserlaubnis konnte nicht gewährt werden weil der Code abgelaufen ist."
|
||||
|
||||
#: c3nav/site/views.py:249
|
||||
#: c3nav/site/views.py:254
|
||||
msgid "account creation is currently disabled."
|
||||
msgstr "Benutzerregistrierung ist momentan deaktiviert."
|
||||
|
||||
#: c3nav/site/views.py:311
|
||||
#: c3nav/site/views.py:316
|
||||
msgid "This token does not exist or was already redeemed."
|
||||
msgstr "Dieser Code existiert nicht oder wurde bereits eingelöst."
|
||||
|
||||
#: c3nav/site/views.py:331
|
||||
#: c3nav/site/views.py:336
|
||||
msgid "Unlock area"
|
||||
msgid_plural "Unlock areas"
|
||||
msgstr[0] "Bereich freischalten"
|
||||
msgstr[1] "Bereiche freischalten"
|
||||
|
||||
#: c3nav/site/views.py:332
|
||||
#: c3nav/site/views.py:337
|
||||
msgid "You have been invited to unlock the following area:"
|
||||
msgid_plural "You have been invited to unlock the following areas:"
|
||||
msgstr[0] "Du wurdest eingeladen, den folgenden Bereich freizuschalten:"
|
||||
msgstr[1] "Du wurdest eingeladen, die folgenden Bereiche freizuschalten:"
|
||||
|
||||
#: c3nav/site/views.py:408
|
||||
msgid "Your report was submitted."
|
||||
msgstr "Deine Meldiung wurde abgesendet."
|
||||
|
||||
#: c3nav/site/views.py:411
|
||||
msgid "You can keep track of it from your user dashboard."
|
||||
msgstr "Du kannst sie in deinerm Benutzerdashboard verfolgen."
|
||||
|
||||
#: c3nav/site/views.py:413
|
||||
msgid "You can keep track of it by revisiting the public URL mentioned below."
|
||||
msgstr "Du kannst sie mit dem unten angegebenen öffentlichen link verfolgen."
|
||||
|
||||
#~ msgid "Coming soon"
|
||||
#~ msgstr "Coming soon"
|
||||
|
||||
#~ msgid "You can not edit this object."
|
||||
#~ msgstr "Du kannst dieses Objekt nicht bearbeiten."
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@ class I18nModelFormMixin(ModelForm):
|
|||
new_fields[sub_field_name] = CharField(label=field_title,
|
||||
required=False,
|
||||
initial=values[language].strip(),
|
||||
max_length=model_field.i18n_max_length)
|
||||
max_length=model_field.i18n_max_length,
|
||||
help_text=form_field.help_text)
|
||||
|
||||
if has_values:
|
||||
self.i18n_fields.append((model_field, values))
|
||||
|
|
84
src/c3nav/mapdata/migrations/0078_reports.py
Normal file
84
src/c3nav/mapdata/migrations/0078_reports.py
Normal file
|
@ -0,0 +1,84 @@
|
|||
# Generated by Django 2.2.8 on 2019-12-24 15:52
|
||||
|
||||
import c3nav.mapdata.fields
|
||||
import c3nav.mapdata.models.report
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('mapdata', '0077_obstacle_altitude'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Report',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='created')),
|
||||
('category', models.CharField(choices=[('location-issue', 'location issue'), ('missing-location', 'missing location'), ('route-issue', 'route issue')], db_index=True, max_length=20, verbose_name='category')),
|
||||
('open', models.BooleanField(default=True, verbose_name='open')),
|
||||
('last_update', models.DateTimeField(auto_now=True, verbose_name='last_update')),
|
||||
('title', models.CharField(default='', help_text='a short title for your report', max_length=100, verbose_name='title')),
|
||||
('description', models.TextField(default='', help_text="tell us precisely what's wrong", max_length=1000, verbose_name='description')),
|
||||
('coordinates_id', models.CharField(max_length=48, null=True, verbose_name='coordinates')),
|
||||
('origin_id', models.CharField(max_length=48, null=True, verbose_name='origin')),
|
||||
('destination_id', models.CharField(max_length=48, null=True, verbose_name='destination')),
|
||||
('route_options', models.CharField(max_length=128, null=True, verbose_name='route options')),
|
||||
('created_title', c3nav.mapdata.fields.I18nField(fallback_any=True, help_text='you have to supply a title in at least one language', plural_name='titles', verbose_name='new location title')),
|
||||
('secret', models.CharField(default=c3nav.mapdata.models.report.get_report_secret, max_length=32, verbose_name='secret')),
|
||||
('assigned_to', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='assigned_reports', to=settings.AUTH_USER_MODEL, verbose_name='assigned to')),
|
||||
('author', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='report', to=settings.AUTH_USER_MODEL, verbose_name='author')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Report',
|
||||
'verbose_name_plural': 'Reports',
|
||||
'default_related_name': 'report',
|
||||
},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='lineobstacle',
|
||||
options={'default_related_name': 'lineobstacles', 'ordering': ('altitude', 'height'), 'verbose_name': 'Line Obstacle', 'verbose_name_plural': 'Line Obstacles'},
|
||||
),
|
||||
migrations.AlterModelOptions(
|
||||
name='obstacle',
|
||||
options={'default_related_name': 'obstacles', 'ordering': ('altitude', 'height'), 'verbose_name': 'Obstacle', 'verbose_name_plural': 'Obstacles'},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='locationgroup',
|
||||
name='can_report_missing',
|
||||
field=models.BooleanField(default=False, help_text='can be used when reporting a missing location', verbose_name='for missing locations'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ReportUpdate',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('datetime', models.DateTimeField(auto_now_add=True, verbose_name='datetime')),
|
||||
('open', models.NullBooleanField(verbose_name='open')),
|
||||
('comment', models.TextField(verbose_name='comment')),
|
||||
('public', models.BooleanField(verbose_name='public')),
|
||||
('assigned_to', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='report_update_assigns', to=settings.AUTH_USER_MODEL, verbose_name='assigned to')),
|
||||
('author', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='reportupdate', to=settings.AUTH_USER_MODEL, verbose_name='author')),
|
||||
('report', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reportupdate', to='mapdata.Report')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Report update',
|
||||
'verbose_name_plural': 'Report updates',
|
||||
'default_related_name': 'reportupdate',
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='report',
|
||||
name='created_groups',
|
||||
field=models.ManyToManyField(blank=True, help_text='select all groups that apply, if any', limit_choices_to={'can_report_missing': True}, related_name='report', to='mapdata.LocationGroup', verbose_name='location groups'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='report',
|
||||
name='location',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='reports', to='mapdata.LocationSlug', verbose_name='location'),
|
||||
),
|
||||
]
|
|
@ -312,6 +312,8 @@ class LocationGroup(Location, models.Model):
|
|||
label_settings = models.ForeignKey('mapdata.LabelSettings', null=True, blank=True, on_delete=models.PROTECT,
|
||||
verbose_name=_('label settings'),
|
||||
help_text=_('unless location specifies otherwise'))
|
||||
can_report_missing = models.BooleanField(default=False, verbose_name=_('for missing locations'),
|
||||
help_text=_('can be used when reporting a missing location'))
|
||||
color = models.CharField(null=True, blank=True, max_length=32, verbose_name=_('background color'))
|
||||
|
||||
objects = LocationGroupManager()
|
||||
|
|
119
src/c3nav/mapdata/models/report.py
Normal file
119
src/c3nav/mapdata/models/report.py
Normal file
|
@ -0,0 +1,119 @@
|
|||
import string
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db import models
|
||||
from django.utils.crypto import get_random_string
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from c3nav.mapdata.fields import I18nField
|
||||
from c3nav.mapdata.utils.locations import get_location_by_id_for_request
|
||||
|
||||
|
||||
def get_report_secret():
|
||||
return get_random_string(32, string.ascii_letters)
|
||||
|
||||
|
||||
class LocationById():
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.name = None
|
||||
self.cached_id = None
|
||||
self.cached_value = None
|
||||
|
||||
def __set_name__(self, owner, name):
|
||||
self.name = name
|
||||
|
||||
def __get__(self, instance, owner=None):
|
||||
value_id = getattr(instance, self.name+'_id')
|
||||
if value_id is None:
|
||||
self.cached_pk = None
|
||||
self.cached_value = None
|
||||
return None
|
||||
|
||||
if value_id == self.cached_id:
|
||||
return self.cached_value
|
||||
|
||||
value = get_location_by_id_for_request(value_id, getattr(instance, 'request', None))
|
||||
if value is None:
|
||||
raise ObjectDoesNotExist
|
||||
self.cached_id = value_id
|
||||
self.cached_value = value
|
||||
return value
|
||||
|
||||
def __set__(self, instance, value):
|
||||
self.cached_id = value.pk
|
||||
self.cached_value = value
|
||||
setattr(instance, self.name+'_id', value.pk)
|
||||
|
||||
|
||||
class Report(models.Model):
|
||||
CATEGORIES = (
|
||||
('location-issue', _('location issue')),
|
||||
('missing-location', _('missing location')),
|
||||
('route-issue', _('route issue')),
|
||||
)
|
||||
created = models.DateTimeField(auto_now_add=True, verbose_name=_('created'))
|
||||
category = models.CharField(max_length=20, db_index=True, choices=CATEGORIES, verbose_name=_('category'))
|
||||
author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT, verbose_name=_('author'))
|
||||
open = models.BooleanField(default=True, verbose_name=_('open'))
|
||||
last_update = models.DateTimeField(auto_now=True, verbose_name=_('last_update'))
|
||||
title = models.CharField(max_length=100, default='', verbose_name=_('title'),
|
||||
help_text=_('a short title for your report'))
|
||||
description = models.TextField(max_length=1000, default='', verbose_name=_('description'),
|
||||
help_text=_('tell us precisely what\'s wrong'))
|
||||
assigned_to = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT,
|
||||
related_name='assigned_reports', verbose_name=_('assigned to'))
|
||||
location = models.ForeignKey('mapdata.LocationSlug', null=True, on_delete=models.SET_NULL,
|
||||
related_name='reports', verbose_name=_('location'))
|
||||
coordinates_id = models.CharField(_('coordinates'), null=True, max_length=48)
|
||||
origin_id = models.CharField(_('origin'), null=True, max_length=48)
|
||||
destination_id = models.CharField(_('destination'), null=True, max_length=48)
|
||||
route_options = models.CharField(_('route options'), null=True, max_length=128)
|
||||
|
||||
created_title = I18nField(_('new location title'), plural_name='titles', blank=False, fallback_any=True,
|
||||
help_text=_('you have to supply a title in at least one language'))
|
||||
created_groups = models.ManyToManyField('mapdata.LocationGroup', verbose_name=_('location groups'), blank=True,
|
||||
limit_choices_to={'can_report_missing': True},
|
||||
help_text=_('select all groups that apply, if any'))
|
||||
secret = models.CharField(_('secret'), max_length=32, default=get_report_secret)
|
||||
|
||||
coordinates = LocationById()
|
||||
origin = LocationById()
|
||||
destination = LocationById()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Report')
|
||||
verbose_name_plural = _('Reports')
|
||||
default_related_name = 'report'
|
||||
|
||||
@property
|
||||
def form_cls(self):
|
||||
from c3nav.site.forms import ReportMissingLocationForm, ReportIssueForm
|
||||
return ReportMissingLocationForm if self.category == 'missing-location' else ReportIssueForm
|
||||
|
||||
@classmethod
|
||||
def qs_for_request(cls, request):
|
||||
if request.user.is_superuser:
|
||||
# todo: permissions!
|
||||
return cls.objects.all()
|
||||
elif request.user.is_authenticated:
|
||||
return cls.objects.filter(author=request.user)
|
||||
else:
|
||||
return cls.objects.none()
|
||||
|
||||
|
||||
class ReportUpdate(models.Model):
|
||||
report = models.ForeignKey(Report, on_delete=models.CASCADE)
|
||||
datetime = models.DateTimeField(auto_now_add=True, verbose_name=_('datetime'))
|
||||
author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT, verbose_name=_('author'))
|
||||
open = models.NullBooleanField(verbose_name=_('open'))
|
||||
comment = models.TextField(verbose_name=_('comment'))
|
||||
assigned_to = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.PROTECT,
|
||||
related_name='report_update_assigns', verbose_name=_('assigned to'))
|
||||
public = models.BooleanField(verbose_name=_('public'))
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Report update')
|
||||
verbose_name_plural = _('Report updates')
|
||||
default_related_name = 'reportupdate'
|
|
@ -418,3 +418,6 @@ class CustomLocation:
|
|||
@cached_property
|
||||
def subtitle(self):
|
||||
return self.title_subtitle[1]
|
||||
|
||||
def get_icon(self):
|
||||
return self.icon
|
||||
|
|
|
@ -174,6 +174,7 @@ class RouteOptions(models.Model):
|
|||
for choice_name, choice_title in field.choices
|
||||
],
|
||||
'value': self[name],
|
||||
'value_display': dict(field.choices)[self[name]],
|
||||
}
|
||||
for name, field in self.get_fields().items()
|
||||
]
|
||||
|
@ -181,6 +182,12 @@ class RouteOptions(models.Model):
|
|||
def serialize_string(self):
|
||||
return ','.join('%s=%s' % (key, val) for key, val in self.data.items())
|
||||
|
||||
@classmethod
|
||||
def unserialize_string(cls, data):
|
||||
return RouteOptions(
|
||||
data=dict(item.split('=') for item in data.split(','))
|
||||
)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.request is None or self.request.user.is_authenticated:
|
||||
self.user = self.request.user
|
||||
|
|
16
src/c3nav/site/forms.py
Normal file
16
src/c3nav/site/forms.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
from django.forms import ModelForm
|
||||
|
||||
from c3nav.mapdata.forms import I18nModelFormMixin
|
||||
from c3nav.mapdata.models.report import Report
|
||||
|
||||
|
||||
class ReportIssueForm(I18nModelFormMixin, ModelForm):
|
||||
class Meta:
|
||||
model = Report
|
||||
fields = ['title', 'description']
|
||||
|
||||
|
||||
class ReportMissingLocationForm(I18nModelFormMixin, ModelForm):
|
||||
class Meta:
|
||||
model = Report
|
||||
fields = ['title', 'description', 'created_title', 'created_groups']
|
|
@ -547,6 +547,9 @@ main.show-options #resultswrapper #route-options {
|
|||
padding: 5px 10px 5px 53px;
|
||||
height: 55px;
|
||||
}
|
||||
.location.location-form-value {
|
||||
margin: -10px -10px 5px -10px;
|
||||
}
|
||||
.location .icon {
|
||||
font-size: 36px;
|
||||
position: absolute;
|
||||
|
@ -1256,6 +1259,25 @@ main .narrow p, main .narrow form, main .narrow button {
|
|||
main .narrow form button {
|
||||
width: 100%;
|
||||
}
|
||||
main form > p, #modal form > p {
|
||||
margin-bottom: 15px;
|
||||
> :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.helptext {
|
||||
display: block;
|
||||
margin-top: -15px;
|
||||
font-style: italic;
|
||||
color: #999999;
|
||||
}
|
||||
textarea {
|
||||
resize: none;
|
||||
height: 100px;
|
||||
}
|
||||
select {
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-permissions-form label {
|
||||
font-weight: 400;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
<form method="post" action="{{ request.path_info }}?{{ request.META.QUERY_STRING }}">
|
||||
{% csrf_token %}
|
||||
{{ form }}
|
||||
{{ form.as_p }}
|
||||
<button type="submit">{{ title }}</button>
|
||||
{% if bottom_link_url %}
|
||||
<a href="{{ bottom_link_url }}?{{ request.META.QUERY_STRING }}">{{ bottom_link_text }}</a>
|
||||
|
|
5
src/c3nav/site/templates/site/fragment_location.html
Normal file
5
src/c3nav/site/templates/site/fragment_location.html
Normal file
|
@ -0,0 +1,5 @@
|
|||
<div class="location{% if form_value %} location-form-value{% endif %}">
|
||||
<i class="icon material-icons">{% if location.get_icon %}{{ location.get_icon }}{% else %}place{% endif %}</i>
|
||||
<span>{{ location.title }}</span>
|
||||
<small>{% if add_subtitle %}{{ add_subtitle }}, {% endif %}{{ location.subtitle }}</small>
|
||||
</div>
|
22
src/c3nav/site/templates/site/fragment_report_meta.html
Normal file
22
src/c3nav/site/templates/site/fragment_report_meta.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
{% load i18n %}
|
||||
{% if report.category == 'location-issue' %}
|
||||
<p><strong>{% trans 'You are reporting an issue with the following location:' %}</strong></p>
|
||||
{% include 'site/fragment_location.html' with form_value=1 location=report.location %}
|
||||
{% elif report.category == 'missing-location' %}
|
||||
<p><strong>{% trans 'You are reporting an missing location at the following position:' %}</strong></p>
|
||||
{% include 'site/fragment_location.html' with form_value=1 location=report.coordinates add_subtitle=report.coordinates_id %}
|
||||
{% elif report.category == 'route-issue' %}
|
||||
<p><strong>{% trans 'You are reporting an issue with the following route:' %}</strong></p>
|
||||
|
||||
<label>{% trans 'Origin' %}:</label>
|
||||
{% include 'site/fragment_location.html' with form_value=1 location=report.origin %}
|
||||
|
||||
<label>{% trans 'Destination' %}:</label>
|
||||
{% include 'site/fragment_location.html' with form_value=1 location=report.destination %}
|
||||
|
||||
<label>{% trans 'Route options' %}:</label>
|
||||
{% for option in options.serialize %}
|
||||
{{ option.label }}: {{ option.value_display }}<br>
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
|
@ -1,10 +0,0 @@
|
|||
{% extends 'site/base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<main class="account">
|
||||
<h2>{% trans 'Coming soon' %}</h2>
|
||||
|
||||
{% include 'site/fragment_messages.html' %}
|
||||
</main>
|
||||
{% endblock %}
|
16
src/c3nav/site/templates/site/report_create.html
Normal file
16
src/c3nav/site/templates/site/report_create.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
{% extends 'site/base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<main class="account">
|
||||
<h2>{% trans 'Report issue' %}</h2>
|
||||
{% include 'site/fragment_messages.html' %}
|
||||
|
||||
<form method="post" action="{{ request.path_info }}?{{ request.META.QUERY_STRING }}">
|
||||
{% csrf_token %}
|
||||
{% include 'site/fragment_report_meta.html' %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit">{% trans 'Submit' %}</button>
|
||||
</form>
|
||||
</main>
|
||||
{% endblock %}
|
44
src/c3nav/site/templates/site/report_detail.html
Normal file
44
src/c3nav/site/templates/site/report_detail.html
Normal file
|
@ -0,0 +1,44 @@
|
|||
{% extends 'site/base.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<main class="account">
|
||||
<h2>{% trans 'Report' %}: {{ report.title }}</h2>
|
||||
<p><em>
|
||||
{% if report.open %}
|
||||
<strong class="green">{% trans 'open' %}</strong>
|
||||
{% else %}
|
||||
<strong class="red">{% trans 'closed' %}</strong>
|
||||
{% endif %}
|
||||
–
|
||||
{% if report.author %}
|
||||
{% trans 'anonymous submission' %}
|
||||
{% else %}
|
||||
{% trans 'by' %} {{ request.author.username }}
|
||||
{% endif %}
|
||||
–
|
||||
{{ report.created }}
|
||||
</em></p>
|
||||
{% include 'site/fragment_messages.html' %}
|
||||
{% include 'site/fragment_report_meta.html' %}
|
||||
|
||||
{% for field in form %}
|
||||
{% if field.name != 'title' %}
|
||||
<p>
|
||||
<strong>{{ field.label }}:</strong><br>
|
||||
{% if field.name == 'description' %}
|
||||
{{ report.description | linebreaksbr }}
|
||||
{% elif field.name == 'created_groups' %}
|
||||
{% for group in report.created_groups.all %}
|
||||
{{ group.title }}<br>
|
||||
{% empty %}
|
||||
<em>{% trans '(none)' %}</em>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{ field.value }}
|
||||
{% endif %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</main>
|
||||
{% endblock %}
|
|
@ -1,7 +1,7 @@
|
|||
from django.conf.urls import url
|
||||
|
||||
from c3nav.site.views import (about_view, access_redeem_view, account_view, change_password_view, choose_language,
|
||||
login_view, logout_view, map_index, qr_code, register_view, report_view)
|
||||
login_view, logout_view, map_index, qr_code, register_view, report_create, report_detail)
|
||||
|
||||
slug = r'(?P<slug>[a-z0-9-_.:]+)'
|
||||
coordinates = r'(?P<coordinates>[a-z0-9-_:]+:-?\d+(\.\d+)?:-?\d+(\.\d+)?)'
|
||||
|
@ -27,7 +27,10 @@ urlpatterns = [
|
|||
url(r'^lang/$', choose_language, name='site.language'),
|
||||
url(r'^about/$', about_view, name='site.about'),
|
||||
url(r'^report/$', about_view, name='site.about'),
|
||||
url(r'^report/l/%s/$' % coordinates, report_view, name='site.report'),
|
||||
url(r'^report/l/(?P<location>\d+)/$', report_view, name='site.report'),
|
||||
url(r'^report/r/(?P<origin>[^/]+)/(?P<destination>[^/]+)/(?P<options>[^/]+)/$', report_view, name='site.report'),
|
||||
url(r'^report/(?P<pk>\d+)/$', report_detail, name='site.report_detail'),
|
||||
url(r'^report/(?P<pk>\d+)/(?P<secret>[^/]+)/$', report_detail, name='site.report_detail'),
|
||||
url(r'^report/l/%s/$' % coordinates, report_create, name='site.report_create'),
|
||||
url(r'^report/l/(?P<location>\d+)/$', report_create, name='site.report_create'),
|
||||
url(r'^report/r/(?P<origin>[^/]+)/(?P<destination>[^/]+)/(?P<options>[^/]+)/$',
|
||||
report_create, name='site.report_create'),
|
||||
]
|
||||
|
|
|
@ -9,11 +9,12 @@ from django.contrib.auth import login, logout
|
|||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.forms import AuthenticationForm, PasswordChangeForm, UserCreationForm
|
||||
from django.contrib.auth.views import redirect_to_login
|
||||
from django.core.exceptions import ObjectDoesNotExist, SuspiciousOperation
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.db import transaction
|
||||
from django.http import HttpResponse, HttpResponseBadRequest
|
||||
from django.http import Http404, HttpResponse, HttpResponseBadRequest
|
||||
from django.middleware import csrf
|
||||
from django.shortcuts import redirect, render
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
@ -27,9 +28,12 @@ from c3nav.mapdata.grid import grid
|
|||
from c3nav.mapdata.models import Location, Source
|
||||
from c3nav.mapdata.models.access import AccessPermissionToken
|
||||
from c3nav.mapdata.models.locations import LocationRedirect, SpecificLocation
|
||||
from c3nav.mapdata.utils.locations import get_location_by_slug_for_request, levels_by_short_label_for_request
|
||||
from c3nav.mapdata.models.report import Report
|
||||
from c3nav.mapdata.utils.locations import (get_location_by_id_for_request, get_location_by_slug_for_request,
|
||||
levels_by_short_label_for_request)
|
||||
from c3nav.mapdata.utils.user import can_access_editor, get_user_data
|
||||
from c3nav.mapdata.views import set_tile_access_cookie
|
||||
from c3nav.routing.models import RouteOptions
|
||||
from c3nav.site.models import Announcement, SiteUpdate
|
||||
|
||||
|
||||
|
@ -350,6 +354,86 @@ def about_view(request):
|
|||
})
|
||||
|
||||
|
||||
def get_report_location_for_request(pk, request):
|
||||
location = get_location_by_id_for_request(pk, request)
|
||||
if location is None:
|
||||
raise Http404
|
||||
return location
|
||||
|
||||
|
||||
@never_cache
|
||||
def report_view(request, coordinates=None, location=None, origin=None, destination=None, options=None):
|
||||
return render(request, 'site/report.html', {})
|
||||
def report_create(request, coordinates=None, location=None, origin=None, destination=None, options=None):
|
||||
report = Report()
|
||||
report.request = request
|
||||
|
||||
if coordinates:
|
||||
report.category = 'missing-location'
|
||||
report.coordinates_id = coordinates
|
||||
try:
|
||||
report.coordinates
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404
|
||||
elif location:
|
||||
report.category = 'location-issue'
|
||||
report.location = get_report_location_for_request(location, request)
|
||||
if report.location is None:
|
||||
raise Http404
|
||||
report.location = location
|
||||
elif origin:
|
||||
report.category = 'route-issue'
|
||||
report.origin_id = origin
|
||||
report.destination_id = destination
|
||||
try:
|
||||
# noinspection PyStatementEffect
|
||||
report.origin
|
||||
# noinspection PyStatementEffect
|
||||
report.destination
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404
|
||||
try:
|
||||
options = RouteOptions.unserialize_string(options)
|
||||
except Exception:
|
||||
raise SuspiciousOperation
|
||||
report.options = options.serialize_string()
|
||||
|
||||
if request.method == 'POST':
|
||||
form = report.form_cls(instance=report, data=request.POST)
|
||||
if form.is_valid():
|
||||
report = form.instance
|
||||
if request.user.is_authenticated:
|
||||
report.author = request.user
|
||||
report.save()
|
||||
|
||||
success_messages = [_('Your report was submitted.')]
|
||||
success_kwargs = {'pk': report.pk}
|
||||
if request.user.is_authenticated:
|
||||
success_messages.append(_('You can keep track of it from your user dashboard.'))
|
||||
else:
|
||||
success_messages.append(_('You can keep track of it by revisiting the public URL mentioned below.'))
|
||||
success_kwargs = {'secret': report.secret}
|
||||
messages.success(request, ' '.join(str(s) for s in success_messages))
|
||||
return redirect(reverse('site.report_detail', kwargs=success_kwargs))
|
||||
else:
|
||||
form = report.form_cls(instance=report)
|
||||
|
||||
return render(request, 'site/report_create.html', {
|
||||
'report': report,
|
||||
'options': options,
|
||||
'form': form,
|
||||
})
|
||||
|
||||
|
||||
def report_detail(request, pk, secret=None):
|
||||
if secret:
|
||||
qs = Report.objects.filter(secret=secret)
|
||||
else:
|
||||
qs = Report.qs_for_request(request)
|
||||
report = get_object_or_404(qs, pk=pk)
|
||||
report.request = request
|
||||
|
||||
form = report.form_cls(instance=report)
|
||||
|
||||
return render(request, 'site/report_detail.html', {
|
||||
'report': report,
|
||||
'form': form,
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue