diff --git a/compensation/tests/compensation/test_workflow.py b/compensation/tests/compensation/test_workflow.py index 3f024483..7b6c89a0 100644 --- a/compensation/tests/compensation/test_workflow.py +++ b/compensation/tests/compensation/test_workflow.py @@ -54,7 +54,7 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase): post_data = { "identifier": test_id, "title": test_title, - "geom": geom_json, + "output": geom_json, "intervention": self.intervention.id, } pre_creation_intervention_log_count = self.intervention.log.count() @@ -94,7 +94,7 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase): post_data = { "identifier": test_id, "title": test_title, - "geom": geom_json, + "output": geom_json, } pre_creation_intervention_log_count = self.intervention.log.count() @@ -150,7 +150,7 @@ class CompensationWorkflowTestCase(BaseWorkflowTestCase): "title": new_title, "intervention": self.intervention.id, # just keep the intervention as it is "comment": new_comment, - "geom": geojson, + "output": geojson, } self.client_user.post(url, post_data) self.compensation.refresh_from_db() diff --git a/compensation/tests/ecoaccount/test_workflow.py b/compensation/tests/ecoaccount/test_workflow.py index 27eb0a99..efbd6342 100644 --- a/compensation/tests/ecoaccount/test_workflow.py +++ b/compensation/tests/ecoaccount/test_workflow.py @@ -46,7 +46,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase): post_data = { "identifier": test_id, "title": test_title, - "geom": geom_json, + "output": geom_json, "surface": test_deductable_surface, "conservation_office": test_conservation_office.id } @@ -103,7 +103,7 @@ class EcoAccountWorkflowTestCase(BaseWorkflowTestCase): "identifier": new_identifier, "title": new_title, "comment": new_comment, - "geom": self.create_geojson(new_geometry), + "output": self.create_geojson(new_geometry), "surface": test_deductable_surface, "conservation_office": test_conservation_office.id } diff --git a/compensation/views/compensation/compensation.py b/compensation/views/compensation/compensation.py index 158495cc..15bac1f8 100644 --- a/compensation/views/compensation/compensation.py +++ b/compensation/views/compensation/compensation.py @@ -27,7 +27,7 @@ from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.message_templates import COMPENSATION_REMOVED_TEMPLATE, DATA_CHECKED_PREVIOUSLY_TEMPLATE, \ RECORDED_BLOCKS_EDIT, CHECK_STATE_RESET, FORM_INVALID, PARAMS_INVALID, IDENTIFIER_REPLACED, \ - COMPENSATION_ADDED_TEMPLATE, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED + COMPENSATION_ADDED_TEMPLATE, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE @login_required @@ -103,11 +103,19 @@ def new_view(request: HttpRequest, intervention_id: str = None): ) ) messages.success(request, COMPENSATION_ADDED_TEMPLATE.format(comp.identifier)) - if geom_form.geometry_simplified: + if geom_form.has_geometry_simplified(): messages.info( request, GEOMETRY_SIMPLIFIED ) + + num_ignored_geometries = geom_form.get_num_geometries_ignored() + if num_ignored_geometries > 0: + messages.info( + request, + GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries) + ) + return redirect("compensation:detail", id=comp.id) else: messages.error(request, FORM_INVALID, extra_tags="danger",) @@ -179,11 +187,19 @@ def edit_view(request: HttpRequest, id: str): if intervention_is_checked: messages.info(request, CHECK_STATE_RESET) messages.success(request, _("Compensation {} edited").format(comp.identifier)) - if geom_form.geometry_simplified: + if geom_form.has_geometry_simplified(): messages.info( request, GEOMETRY_SIMPLIFIED ) + + num_ignored_geometries = geom_form.get_num_geometries_ignored() + if num_ignored_geometries > 0: + messages.info( + request, + GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries) + ) + return redirect("compensation:detail", id=comp.id) else: messages.error(request, FORM_INVALID, extra_tags="danger",) diff --git a/compensation/views/eco_account/eco_account.py b/compensation/views/eco_account/eco_account.py index 798e73c0..28dbfc10 100644 --- a/compensation/views/eco_account/eco_account.py +++ b/compensation/views/eco_account/eco_account.py @@ -23,7 +23,7 @@ from konova.forms import SimpleGeomForm from konova.settings import ETS_GROUP, DEFAULT_GROUP, ZB_GROUP from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.message_templates import CANCEL_ACC_RECORDED_OR_DEDUCTED, RECORDED_BLOCKS_EDIT, FORM_INVALID, \ - IDENTIFIER_REPLACED, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED + IDENTIFIER_REPLACED, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE @login_required @@ -84,11 +84,19 @@ def new_view(request: HttpRequest): ) ) messages.success(request, _("Eco-Account {} added").format(acc.identifier)) - if geom_form.geometry_simplified: + if geom_form.has_geometry_simplified(): messages.info( request, GEOMETRY_SIMPLIFIED ) + + num_ignored_geometries = geom_form.get_num_geometries_ignored() + if num_ignored_geometries > 0: + messages.info( + request, + GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries) + ) + return redirect("compensation:acc:detail", id=acc.id) else: messages.error(request, FORM_INVALID, extra_tags="danger",) @@ -156,11 +164,19 @@ def edit_view(request: HttpRequest, id: str): # The data form takes the geom form for processing, as well as the performing user acc = data_form.save(request.user, geom_form) messages.success(request, _("Eco-Account {} edited").format(acc.identifier)) - if geom_form.geometry_simplified: + if geom_form.has_geometry_simplified(): messages.info( request, GEOMETRY_SIMPLIFIED ) + + num_ignored_geometries = geom_form.get_num_geometries_ignored() + if num_ignored_geometries > 0: + messages.info( + request, + GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries) + ) + return redirect("compensation:acc:detail", id=acc.id) else: messages.error(request, FORM_INVALID, extra_tags="danger",) diff --git a/ema/tests/test_workflow.py b/ema/tests/test_workflow.py index 7fb3c6a3..f99e080b 100644 --- a/ema/tests/test_workflow.py +++ b/ema/tests/test_workflow.py @@ -46,7 +46,7 @@ class EmaWorkflowTestCase(BaseWorkflowTestCase): post_data = { "identifier": test_id, "title": test_title, - "geom": geom_json, + "output": geom_json, "conservation_office": test_conservation_office.id } self.client_user.post(new_url, post_data) @@ -99,7 +99,7 @@ class EmaWorkflowTestCase(BaseWorkflowTestCase): "identifier": new_identifier, "title": new_title, "comment": new_comment, - "geom": self.create_geojson(new_geometry), + "output": self.create_geojson(new_geometry), "conservation_office": test_conservation_office.id } self.client_user.post(url, post_data) diff --git a/ema/tests/unit/test_forms.py b/ema/tests/unit/test_forms.py index d66fd14b..40865bb8 100644 --- a/ema/tests/unit/test_forms.py +++ b/ema/tests/unit/test_forms.py @@ -48,7 +48,7 @@ class NewEmaFormTestCase(BaseTestCase): ) geom_form_data = json.loads(geom_form_data) geom_form_data = { - "geom": json.dumps(geom_form_data) + "output": json.dumps(geom_form_data) } geom_form = SimpleGeomForm(geom_form_data) @@ -116,7 +116,7 @@ class EditEmaFormTestCase(BaseTestCase): ) geom_form_data = json.loads(geom_form_data) geom_form_data = { - "geom": json.dumps(geom_form_data) + "output": json.dumps(geom_form_data) } geom_form = SimpleGeomForm(geom_form_data) diff --git a/ema/views/ema.py b/ema/views/ema.py index 4136e916..5322b5ef 100644 --- a/ema/views/ema.py +++ b/ema/views/ema.py @@ -24,7 +24,7 @@ from konova.forms.modals import RemoveModalForm from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.message_templates import RECORDED_BLOCKS_EDIT, IDENTIFIER_REPLACED, FORM_INVALID, \ - DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED + DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED, GEOMETRIES_IGNORED_TEMPLATE @login_required @@ -84,11 +84,17 @@ def new_view(request: HttpRequest): ) ) messages.success(request, _("EMA {} added").format(ema.identifier)) - if geom_form.geometry_simplified: + if geom_form.has_geometry_simplified(): messages.info( request, GEOMETRY_SIMPLIFIED ) + num_ignored_geometries = geom_form.get_num_geometries_ignored() + if num_ignored_geometries > 0: + messages.info( + request, + GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries) + ) return redirect("ema:detail", id=ema.id) else: @@ -215,11 +221,19 @@ def edit_view(request: HttpRequest, id: str): # The data form takes the geom form for processing, as well as the performing user ema = data_form.save(request.user, geom_form) messages.success(request, _("EMA {} edited").format(ema.identifier)) - if geom_form.geometry_simplified: + if geom_form.has_geometry_simplified(): messages.info( request, GEOMETRY_SIMPLIFIED ) + + num_ignored_geometries = geom_form.get_num_geometries_ignored() + if num_ignored_geometries > 0: + messages.info( + request, + GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries) + ) + return redirect("ema:detail", id=ema.id) else: messages.error(request, FORM_INVALID, extra_tags="danger",) diff --git a/intervention/tests/test_workflow.py b/intervention/tests/test_workflow.py index 4bd61d92..962aead2 100644 --- a/intervention/tests/test_workflow.py +++ b/intervention/tests/test_workflow.py @@ -60,7 +60,7 @@ class InterventionWorkflowTestCase(BaseWorkflowTestCase): post_data = { "identifier": test_id, "title": test_title, - "geom": geom_json, + "output": geom_json, } response = self.client_user.post( new_url, diff --git a/intervention/tests/unit/test_forms.py b/intervention/tests/unit/test_forms.py index 6435e21e..20a6d749 100644 --- a/intervention/tests/unit/test_forms.py +++ b/intervention/tests/unit/test_forms.py @@ -62,7 +62,7 @@ class NewInterventionFormTestCase(BaseTestCase): ) geom_form_data = json.loads(geom_form_data) geom_form_data = { - "geom": json.dumps(geom_form_data) + "output": json.dumps(geom_form_data) } geom_form = SimpleGeomForm(geom_form_data) @@ -104,7 +104,7 @@ class EditInterventionFormTestCase(NewInterventionFormTestCase): ) geom_form_data = json.loads(geom_form_data) geom_form_data = { - "geom": json.dumps(geom_form_data) + "output": json.dumps(geom_form_data) } geom_form = SimpleGeomForm(geom_form_data) diff --git a/intervention/views/intervention.py b/intervention/views/intervention.py index be89056c..0d6cc369 100644 --- a/intervention/views/intervention.py +++ b/intervention/views/intervention.py @@ -23,7 +23,8 @@ from konova.forms.modals import RemoveModalForm from konova.settings import DEFAULT_GROUP, ZB_GROUP, ETS_GROUP from konova.sub_settings.context_settings import TAB_TITLE_IDENTIFIER from konova.utils.message_templates import DATA_CHECKED_PREVIOUSLY_TEMPLATE, RECORDED_BLOCKS_EDIT, \ - CHECK_STATE_RESET, FORM_INVALID, IDENTIFIER_REPLACED, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED + CHECK_STATE_RESET, FORM_INVALID, IDENTIFIER_REPLACED, DO_NOT_FORGET_TO_SHARE, GEOMETRY_SIMPLIFIED, \ + GEOMETRIES_IGNORED_TEMPLATE @login_required @@ -88,11 +89,19 @@ def new_view(request: HttpRequest): ) ) messages.success(request, _("Intervention {} added").format(intervention.identifier)) - if geom_form.geometry_simplified: + if geom_form.has_geometry_simplified(): messages.info( request, GEOMETRY_SIMPLIFIED ) + + num_ignored_geometries = geom_form.get_num_geometries_ignored() + if num_ignored_geometries > 0: + messages.info( + request, + GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries) + ) + return redirect("intervention:detail", id=intervention.id) else: messages.error(request, FORM_INVALID, extra_tags="danger",) @@ -236,11 +245,19 @@ def edit_view(request: HttpRequest, id: str): messages.success(request, _("Intervention {} edited").format(intervention.identifier)) if intervention_is_checked: messages.info(request, CHECK_STATE_RESET) - if geom_form.geometry_simplified: + if geom_form.has_geometry_simplified(): messages.info( request, GEOMETRY_SIMPLIFIED ) + + num_ignored_geometries = geom_form.get_num_geometries_ignored() + if num_ignored_geometries > 0: + messages.info( + request, + GEOMETRIES_IGNORED_TEMPLATE.format(num_ignored_geometries) + ) + return redirect("intervention:detail", id=intervention.id) else: messages.error(request, FORM_INVALID, extra_tags="danger",) diff --git a/konova/forms/geometry_form.py b/konova/forms/geometry_form.py index c8c49113..66be2bb3 100644 --- a/konova/forms/geometry_form.py +++ b/konova/forms/geometry_form.py @@ -25,8 +25,8 @@ class SimpleGeomForm(BaseForm): """ A geometry form for rendering geometry read-only using a widget """ - read_only = True - geometry_simplified = False + read_only: bool = True + _geometry_simplified: bool = False output = JSONField( label=_("Geometry"), help_text=_(""), @@ -34,6 +34,7 @@ class SimpleGeomForm(BaseForm): required=False, disabled=False, ) + _num_geometries_ignored: int = 0 def __init__(self, *args, **kwargs): self.read_only = kwargs.pop("read_only", True) @@ -48,6 +49,7 @@ class SimpleGeomForm(BaseForm): raise AttributeError geojson = self.instance.geometry.as_feature_collection(srid=DEFAULT_SRID_RLP) + self._set_geojson_properties(geojson, title=self.instance.identifier or None) geom = json.dumps(geojson) except AttributeError: # If no geometry exists for this form, we simply set the value to None and zoom to the maximum level @@ -61,7 +63,7 @@ class SimpleGeomForm(BaseForm): is_valid = True # Get geojson from form - geom = self.data["output"] + geom = self.data.get("output", None) if geom is None or len(geom) == 0: # empty geometry is a valid geometry self.cleaned_data["output"] = MultiPolygon(srid=DEFAULT_SRID_RLP).ewkt @@ -100,7 +102,13 @@ class SimpleGeomForm(BaseForm): is_valid &= False return is_valid - is_valid &= self.__is_area_valid(g) + is_area_valid = self.__is_area_valid(g) + if not is_area_valid: + # Geometries with an invalid size will not be saved to the db + # We assume these are malicious snippets which are not supposed to be in the geometry in the first place + self._num_geometries_ignored += 1 + continue + g = Polygon.from_ewkt(g.ewkt) is_valid &= g.valid if not g.valid: @@ -147,15 +155,6 @@ class SimpleGeomForm(BaseForm): """ is_area_valid = geom.area > 1 # > 1m² (SRID:25832) - - if not is_area_valid: - self.add_error( - "output", - _("Geometry must be greater than 1m². Currently is {}m²").format( - float(geom.area) - ) - ) - return is_area_valid def __simplify_geometry(self, geom, max_vert: int): @@ -208,13 +207,29 @@ class SimpleGeomForm(BaseForm): if not is_vertices_num_valid: geometry.geom = self.__simplify_geometry(geometry.geom, max_vert=GEOM_MAX_VERTICES) geometry.save() - self.geometry_simplified = True + self._geometry_simplified = True # Start parcel update and geometry conflict checking procedure in a background process celery_update_parcels.delay(geometry.id) celery_check_for_geometry_conflicts.delay(geometry.id) return geometry + def get_num_geometries_ignored(self): + """ Returns the number of geometries which had to be ignored for various reasons + + Returns: + + """ + return self._num_geometries_ignored + + def has_geometry_simplified(self): + """ Returns whether the geometry has been simplified or not. + + Returns: + + """ + return self._geometry_simplified + def __flatten_geom_to_2D(self, geom): """ Enforces a given OGRGeometry from higher dimensions into 2D @@ -225,11 +240,12 @@ class SimpleGeomForm(BaseForm): geom = gdal.OGRGeometry(g_wkt) return geom - def _set_properties(self, geojson: dict, title: str): + def _set_geojson_properties(self, geojson: dict, title: str = None): """ Toggles the editable property of the geojson for proper handling in map client Args: geojson (dict): The GeoJson + title (str): An alternative title for the geometry Returns: geojson (dict): The altered GeoJson diff --git a/konova/tests/test_geometries.py b/konova/tests/test_geometries.py index 047e285d..7850ac7d 100644 --- a/konova/tests/test_geometries.py +++ b/konova/tests/test_geometries.py @@ -124,6 +124,7 @@ class GeometryTestCase(BaseTestCase): { "type": "Feature", "geometry": json.loads(p.json), + "properties": {} } for p in polygons ] diff --git a/konova/utils/message_templates.py b/konova/utils/message_templates.py index e5e71557..ba44934b 100644 --- a/konova/utils/message_templates.py +++ b/konova/utils/message_templates.py @@ -83,6 +83,7 @@ EDITED_GENERAL_DATA = _("Edited general data") # Geometry GEOMETRY_CONFLICT_WITH_TEMPLATE = _("Geometry conflict detected with {}") GEOMETRY_SIMPLIFIED = _("The geometry contained more than {} vertices. It had to be simplified to match the allowed limit of {} vertices.").format(GEOM_MAX_VERTICES, GEOM_MAX_VERTICES) +GEOMETRIES_IGNORED_TEMPLATE = _("The geometry contained {} parts which have been detected as invalid (e.g. too small to be valid). These parts have been removed. Please check the stored geometry.") # INTERVENTION INTERVENTION_HAS_REVOCATIONS_TEMPLATE = _("This intervention has {} revocations") diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index b56f73a1..4f5c1c6c 100644 Binary files a/locale/de/LC_MESSAGES/django.mo and b/locale/de/LC_MESSAGES/django.mo differ diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index ee08ee81..6f308995 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -45,7 +45,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-05-12 14:22+0200\n" +"POT-Creation-Date: 2025-10-15 09:11+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1298,13 +1298,13 @@ msgid "Compensation {} edited" msgstr "Kompensation {} bearbeitet" #: compensation/views/compensation/compensation.py:196 -#: compensation/views/eco_account/eco_account.py:173 ema/views/ema.py:232 +#: compensation/views/eco_account/eco_account.py:173 ema/views/ema.py:238 #: intervention/views/intervention.py:253 msgid "Edit {}" msgstr "Bearbeite {}" #: compensation/views/compensation/report.py:35 -#: compensation/views/eco_account/report.py:35 ema/views/report.py:35 +#: compensation/views/eco_account/report.py:36 ema/views/report.py:35 #: intervention/views/report.py:35 msgid "Report {}" msgstr "Bericht {}" @@ -1325,7 +1325,7 @@ msgstr "Ökokonto {} bearbeitet" msgid "Eco-account removed" msgstr "Ökokonto entfernt" -#: ema/forms.py:42 ema/tests/unit/test_forms.py:27 ema/views/ema.py:102 +#: ema/forms.py:42 ema/tests/unit/test_forms.py:27 ema/views/ema.py:108 msgid "New EMA" msgstr "Neue EMA hinzufügen" @@ -1361,11 +1361,11 @@ msgstr "EMAs - Übersicht" msgid "EMA {} added" msgstr "EMA {} hinzugefügt" -#: ema/views/ema.py:217 +#: ema/views/ema.py:223 msgid "EMA {} edited" msgstr "EMA {} bearbeitet" -#: ema/views/ema.py:256 +#: ema/views/ema.py:262 msgid "EMA removed" msgstr "EMA entfernt" @@ -1815,10 +1815,6 @@ msgid "Only surfaces allowed. Points or lines must be buffered." msgstr "" "Nur Flächen erlaubt. Punkte oder Linien müssen zu Flächen gepuffert werden." -#: konova/forms/geometry_form.py:153 -msgid "Geometry must be greater than 1m². Currently is {}m²" -msgstr "Geometrie muss größer als 1m² sein. Aktueller Flächeninhalt: {}m²" - #: konova/forms/modals/document_form.py:37 msgid "When has this file been created? Important for photos." msgstr "Wann wurde diese Datei erstellt oder das Foto aufgenommen?" @@ -2266,24 +2262,33 @@ msgstr "" "Die Geometrie enthielt mehr als {} Eckpunkte. Sie musste vereinfacht werden " "um die Obergrenze von {} erlaubten Eckpunkten einzuhalten." -#: konova/utils/message_templates.py:88 +#: konova/utils/message_templates.py:86 +msgid "" +"The geometry contained {} parts which have been detected as invalid (e.g. " +"too small to be valid). These parts have been removed. Please check the " +"stored geometry." +msgstr "" +"Die Geometrie enthielt {} invalide Bestandteile (z.B. unaussagekräftige Kleinstflächen)." +"Diese Bestandteile wurden automatisch entfernt. Bitte überprüfen Sie die angepasste Geometrie." + +#: konova/utils/message_templates.py:89 msgid "This intervention has {} revocations" msgstr "Dem Eingriff liegen {} Widersprüche vor" -#: konova/utils/message_templates.py:91 +#: konova/utils/message_templates.py:92 msgid "Checked on {} by {}" msgstr "Am {} von {} geprüft worden" -#: konova/utils/message_templates.py:92 +#: konova/utils/message_templates.py:93 msgid "Data has changed since last check on {} by {}" msgstr "" "Daten wurden nach der letzten Prüfung geändert. Letzte Prüfung am {} durch {}" -#: konova/utils/message_templates.py:93 +#: konova/utils/message_templates.py:94 msgid "Current data not checked yet" msgstr "Momentane Daten noch nicht geprüft" -#: konova/utils/message_templates.py:96 +#: konova/utils/message_templates.py:97 msgid "New token generated. Administrators need to validate." msgstr "Neuer Token generiert. Administratoren sind informiert." @@ -2313,14 +2318,6 @@ msgstr "Home" msgid "Log" msgstr "Log" -#: konova/views/map_proxy.py:84 -msgid "" -"The external service is currently unavailable.
Please try again in a few " -"moments..." -msgstr "" -"Der externe Dienst ist zur Zeit nicht erreichbar.
Versuchen Sie es in ein " -"paar Sekunden nochmal." - #: konova/views/record.py:30 msgid "{} unrecorded" msgstr "{} entzeichnet" @@ -2377,17 +2374,19 @@ msgstr "Alle" msgid "News" msgstr "Neuigkeiten" -#: templates/400.html:7 +#: templates/400.html:12 msgid "Request was invalid" msgstr "Anfrage fehlerhaft" -#: templates/400.html:10 +#: templates/400.html:17 msgid "There seems to be a problem with the link you opened." msgstr "Es scheint ein Problem mit dem Link zu geben, den Sie geöffnet haben." -#: templates/400.html:11 +#: templates/400.html:18 msgid "Make sure the URL is valid (no whitespaces, properly copied, ...)." -msgstr "Stellen Sie sicher, dass die URL gültig ist (keine Leerzeichen, fehlerfrei kopiert, ...)." +msgstr "" +"Stellen Sie sicher, dass die URL gültig ist (keine Leerzeichen, fehlerfrei " +"kopiert, ...)." #: templates/404.html:7 msgid "Not found" @@ -2401,11 +2400,11 @@ msgstr "Die angeforderten Daten existieren nicht." msgid "Make sure the URL is valid (no whitespaces, ...)." msgstr "Stellen Sie sicher, dass die URL gültig ist (keine Leerzeichen, ...)." -#: templates/500.html:7 +#: templates/500.html:12 msgid "Server Error" msgstr "" -#: templates/500.html:10 +#: templates/500.html:17 msgid "Something happened. Admins have been informed. We are working on it!" msgstr "" "Irgendetwas ist passiert. Die Administratoren wurden informiert. Wir "