diff --git a/CHANGELOG.md b/CHANGELOG.md index 328feecccf5f2d112bfeedf6d2875cef086fb840..9b599258d14ffaaacab150b353a5a9a9cfdc45f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.3.1] + +### Added + +- Municipality geometries for cities (Flensburg, Kiel, Lübeck, and Neumünster) have been incorporated into [sh_bb.csv](./ckanext/odsh/resources/sh_bb.csv). + +### Removed + +- The flash message for ODaG evaluation has been removed. + +### Fixed + +- The delete button for packages is now visible again. It was inadvertently missing in a previous update and has been rectified. + +- Fixed missing license properties (`od_conformance`, `ods_conformance`) in the [license configuration](./ckanext/odsh/resources/licenses.json). + ## [2.3.0] ### Added diff --git a/ckanext/odsh/resources/licenses.json b/ckanext/odsh/resources/licenses.json index d30b92ffcd3b5d01243c1d3f252ca915c44ae7ef..e27147fbef3a8d8812c71dee54bb6d9026a296b4 100644 --- a/ckanext/odsh/resources/licenses.json +++ b/ckanext/odsh/resources/licenses.json @@ -154,8 +154,8 @@ }, { "id": "http://dcat-ap.de/def/licenses/cc-by-nd", - "is_okd_compliant": false, - "is_osi_compliant": false, + "od_conformance": "not reviewed", + "osd_conformance": "not reviewed", "status": "active", "title": "Creative Commons Namensnennung -- Keine Bearbeitung (CC BY-ND)", "url": "http://creativecommons.org/licenses/by-nd/3.0/" diff --git a/ckanext/odsh/resources/sh_bb.csv b/ckanext/odsh/resources/sh_bb.csv index 18edb60f24af6645240fb8cbb16da1a9198fcc19..7d31c85bf8a90f3cc721e9252e3d2c2fbda4dc7e 100644 --- a/ckanext/odsh/resources/sh_bb.csv +++ b/ckanext/odsh/resources/sh_bb.csv @@ -1218,6 +1218,10 @@ http://dcat-ap.de/def/politicalGeocoding/regionalKey/010605086 Amt Trave-Land {" http://dcat-ap.de/def/politicalGeocoding/regionalKey/010625270 Amt Trittau {"type":"Feature","properties":{"name":"Amt Trittau"},"geometry":{"type":"Polygon","coordinates":[[[10.2981,53.5543],[10.2981,53.6783],[10.5153,53.6783],[10.5153,53.5543],[10.2981,53.5543]]]}} http://dcat-ap.de/def/politicalGeocoding/regionalKey/010545453 Amt Viöl {"type":"Feature","properties":{"name":"Amt Viöl"},"geometry":{"type":"Polygon","coordinates":[[[9.0925,54.4778],[9.0925,54.6585],[9.3123,54.6585],[9.3123,54.4778],[9.0925,54.4778]]]}} http://dcat-ap.de/def/politicalGeocoding/regionalKey/010615179 Amt Wilstermarsch {"type":"Feature","properties":{"name":"Amt Wilstermarsch"},"geometry":{"type":"Polygon","coordinates":[[[9.1985,53.8085],[9.1985,53.9863],[9.4483,53.9863],[9.4483,53.8085],[9.1985,53.8085]]]}} +http://dcat-ap.de/def/politicalGeocoding/municipalityKey/01001000 Stadt Flensburg {"type":"Feature","properties":{"name":"Stadt Flensburg"},"geometry":{"type":"Polygon","coordinates":[[[9.3573,54.7521],[9.3573,54.8236],[9.5065,54.8236],[9.5065,54.7521],[9.3573,54.7521]]]}} +http://dcat-ap.de/def/politicalGeocoding/municipalityKey/01002000 Stadt Kiel {"type":"Feature","properties":{"name":"Stadt Kiel"},"geometry":{"type":"Polygon","coordinates":[[[10.0327,54.2508],[10.0327,54.4314],[10.2186,54.4314],[10.2186,54.2508],[10.0327,54.2508]]]}} +http://dcat-ap.de/def/politicalGeocoding/municipalityKey/01003000 Stadt Lübeck {"type":"Feature","properties":{"name":"Stadt Lübeck"},"geometry":{"type":"Polygon","coordinates":[[[10.5547,53.7682],[10.5547,53.9937],[10.9671,53.9937],[10.9671,53.7682],[10.5547,53.7682]]]}} +http://dcat-ap.de/def/politicalGeocoding/municipalityKey/01004000 Stadt Neumünster {"type":"Feature","properties":{"name":"Stadt Neumünster"},"geometry":{"type":"Polygon","coordinates":[[[9.9256,54.0178],[9.9256,54.1497],[10.0585,54.1497],[10.0585,54.0178],[9.9256,54.0178]]]}} http://dcat-ap.de/def/politicalGeocoding/municipalityKey/01051001 Gemeinde Albersdorf {"type":"Feature","properties":{"name":"Gemeinde Albersdorf"},"geometry":{"type":"Polygon","coordinates":[[[9.2427,54.111],[9.2427,54.1602],[9.3138,54.1602],[9.3138,54.111],[9.2427,54.111]]]}} http://dcat-ap.de/def/politicalGeocoding/municipalityKey/01051002 Gemeinde Arkebek {"type":"Feature","properties":{"name":"Gemeinde Arkebek"},"geometry":{"type":"Polygon","coordinates":[[[9.2287,54.1446],[9.2287,54.177],[9.2838,54.177],[9.2838,54.1446],[9.2287,54.1446]]]}} http://dcat-ap.de/def/politicalGeocoding/municipalityKey/01051003 Gemeinde Averlak {"type":"Feature","properties":{"name":"Gemeinde Averlak"},"geometry":{"type":"Polygon","coordinates":[[[9.1632,53.9189],[9.1632,53.9587],[9.2287,53.9587],[9.2287,53.9189],[9.1632,53.9189]]]}} @@ -2329,4 +2333,4 @@ http://dcat-ap.de/def/politicalGeocoding/municipalityKey/01062093 Gemeinde Feldh http://dcat-ap.de/def/politicalGeocoding/municipalityKey/01062094 Gemeinde Wesenberg {"type":"Feature","properties":{"name":"Gemeinde Wesenberg"},"geometry":{"type":"Polygon","coordinates":[[[10.5065,53.8095],[10.5065,53.8567],[10.5652,53.8567],[10.5652,53.8095],[10.5065,53.8095]]]}} http://dcat-ap.de/def/politicalGeocoding/municipalityKey/01056025 Gemeinde Helgoland {"type":"Feature","properties":{"name":"Gemeinde Helgoland"},"geometry":{"type":"Polygon","coordinates":[[[7.8685,54.1693],[7.8685,54.1931],[7.9228,54.1931],[7.9228,54.1693],[7.8685,54.1693]]]}} http://dcat-ap.de/def/politicalGeocoding/municipalityKey/01059189 Gemeinde Broderby-Goltoft {"type":"Feature","properties":{"name":"Gemeinde Broderby-Goltoft"},"geometry":{"type":"Polygon","coordinates":[[[9.6709,54.5153],[9.6709,54.5653],[9.7413,54.5653],[9.7413,54.5153],[9.6709,54.5153]]]}} -http://dcat-ap.de/def/politicalGeocoding/municipalityKey/01059188 Gemeinde Stapel {"type":"Feature","properties":{"name":"Gemeinde Stapel"},"geometry":{"type":"Polygon","coordinates":[[[9.1715,54.3157,9.3099],[9.1715,54.3157,],[54.386],],[54.386],9.3099],[9.1715,54.3157,9.3099]]]}} +http://dcat-ap.de/def/politicalGeocoding/municipalityKey/01059188 Gemeinde Stapel {"type":"Feature","properties":{"name":"Gemeinde Stapel"},"geometry":{"type":"Polygon","coordinates":[[[9.1715,54.3157],[9.1715,54.386],[9.3099,54.386],[9.3099,54.3157],[9.1715,54.3157]]]}} diff --git a/ckanext/odsh/templates/package/snippets/package_form.html b/ckanext/odsh/templates/package/snippets/package_form.html index 9120161850af053e5bf38d15b46a270859d1d3c6..37ef706909c1670e40887bd4b6e294ab620fe416 100644 --- a/ckanext/odsh/templates/package/snippets/package_form.html +++ b/ckanext/odsh/templates/package/snippets/package_form.html @@ -26,13 +26,11 @@ <div class="form-actions"> <div class="row-fluid"> <div class="span6"> - {% block delete_button %} - {% if h.check_access('package_delete', {'id': data.id}) and not data.state == 'deleted' %} - <a class="btn btn-danger pull-left" href="{% url_for 'dataset.delete', id=data.id %}" - data-module="confirm-action" data-module-content="{{ _('Are you sure you want to delete this dataset?') }}"> - {% block delete_button_text %}{{ _('Delete') }}{% endblock %}</a> - {% endif %} - {% endblock %} + {% if h.check_access('package_delete', {'id': data.id}) and not data.state == 'deleted' %} + <a class="btn btn-danger pull-left" href="{% url_for 'dataset.delete', id=data.id %}" + data-module="confirm-action" data-module-content="{{ _('Are you sure you want to delete this dataset?') }}"> + {% block delete_button_text %}{{ _('Delete') }}{% endblock %}</a> + {% endif %} {% block save_button %} <button class="btn btn-primary btn-arrow-right" type="submit" name="save"> {% block save_button_text %}{{ diff --git a/ckanext/odsh/templates/page.html b/ckanext/odsh/templates/page.html index e761bb02ccf3b0af92ffe2f6aeb986169bfec04e..caa2ed27d46c5b3f7fd3734cc66c56780a6ed38c 100644 --- a/ckanext/odsh/templates/page.html +++ b/ckanext/odsh/templates/page.html @@ -20,21 +20,6 @@ {% block flash %} {{ super() }} - - {% if not request.referrer or not request.referrer.startswith(h.odsh_public_url()) %} - <div class="alert alert-info alert-dismissible fade show" role="alert"> - <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button> - <span aria-hidden="true"></span> - </button> - <h4 class="alert-heading">Evaluation des Offene-Daten-Gesetzes (ODaG)</h4> - <p>Für die Evaluation des Offene-Daten-Gesetzes (ODaG) lassen wir eine Umfrage zur Nutzung des Open-Data-Portals durchführen. Wir würden uns freuen, wenn möglichst viele Nutzerinnen und Nutzer an der Umfrage teilnehmen würden:</p> - <p style="margin-top: 15px;"> - <a href="https://insight.uni-speyer.de/ODSH/" class="btn">zum Fragebogen</a><br> - <small>(extern beim Deutschen Forschungsinstitut für öffentliche Verwaltung Speyer).</small> - </p> - </div> - {% endif %} - {% endblock %} {% block toolbar %} diff --git a/ckanext/odsh/validation.py b/ckanext/odsh/validation.py index 14151edb6910e859fd6f7294376f70af70805f55..c850252966e648148639e25a7c671e7951550370 100644 --- a/ckanext/odsh/validation.py +++ b/ckanext/odsh/validation.py @@ -2,7 +2,9 @@ import logging import csv import re -import urllib.request, urllib.error, urllib.parse +import urllib.request +import urllib.error +import urllib.parse import json import ckan.logic as logic @@ -69,27 +71,28 @@ def validate_extra_groups(data, requireAtLeastOne, errors): def validate_extras(key, data, errors, context): log.debug("Validating extras") extra_errors = {} - + isStaNord = ('id',) in data and data[('id',)][:7] == 'StaNord' - harvesting = ('ignore_auth' in context) and (context['ignore_auth'] == True) + harvesting = ('ignore_auth' in context) and ( + context['ignore_auth'] == True) owner_org = data[('owner_org',)] - lenient_with = tk.config.get('ckanext.odsh.lenient_with','') + lenient_with = tk.config.get('ckanext.odsh.lenient_with', '') is_optional_temporal_start = toolkit.asbool( tk.config.get('ckanext.odsh.is_optional_temporal_start', False) - ) or ( harvesting and (owner_org in lenient_with) ) + ) or (harvesting and (owner_org in lenient_with)) require_at_least_one_category = toolkit.asbool( tk.config.get('ckanext.odsh.require_at_least_one_category', False) ) validate_extra_groups( - data=data, - requireAtLeastOne=require_at_least_one_category, + data=data, + requireAtLeastOne=require_at_least_one_category, errors=extra_errors ) - + is_date_start_before_date_end(data, extra_errors) - + validate_extra_date_new( key=key, field='issued', @@ -101,7 +104,7 @@ def validate_extras(key, data, errors, context): key=key, field='temporal_start', data=data, - optional=is_optional_temporal_start, + optional=is_optional_temporal_start, errors=extra_errors ) validate_extra_date_new( @@ -115,6 +118,7 @@ def validate_extras(key, data, errors, context): if len(list(extra_errors.values())): raise toolkit.Invalid(extra_errors) + def is_date_start_before_date_end(data, extra_errors): start_date = _extract_value(data, 'temporal_start') end_date = _extract_value(data, 'temporal_end') @@ -122,6 +126,7 @@ def is_date_start_before_date_end(data, extra_errors): if start_date > end_date: extra_errors['temporal_start'] = extra_errors['temporal_end'] = 'Please enter a valid period of time.' + def _set_value(data, field, value): key = None for k in list(data.keys()): @@ -209,7 +214,7 @@ def known_spatial_uri(key, data, errors, context): poly = pkg.extras.get('spatial', None) if (not poly) and require_spatial_uri: raise toolkit.Invalid(error_message_spatial_uri_empty) - #if has_old_uri and require_spatial_uri: + # if has_old_uri and require_spatial_uri: # raise toolkit.Invalid(error_message_spatial_uri_empty) else: if poly: @@ -219,23 +224,28 @@ def known_spatial_uri(key, data, errors, context): return extension_path = pkg_resources.resource_filename('ckanext.odsh', '') - mapping_path = tk.config.get('ckanext.odsh.spatial.mapping', extension_path + '/resources/schleswig-holstein_geojson.csv') + mapping_path = tk.config.get('ckanext.odsh.spatial.mapping', + extension_path + '/resources/schleswig-holstein_geojson.csv') not_found = True spatial_text = str() spatial = str() - with open(mapping_path, newline='') as mapping_file: - cr = csv.reader(mapping_file, delimiter="\t") - for row in cr: - if row[0] == value: - not_found = False - spatial_text = row[1] - loaded = json.loads(row[2]) - spatial = json.dumps(loaded['geometry']) - break - if not_found: - raise toolkit.Invalid( - 'spatial_uri: uri unknown') + + try: + with open(mapping_path, newline='') as mapping_file: + cr = csv.reader(mapping_file, delimiter="\t") + for row in cr: + if row and len(row) > 2 and row[0] == value: + not_found = False + spatial_text = row[1] + loaded = json.loads(row[2]) + spatial = json.dumps(loaded.get('geometry', {})) + break + if not_found: + raise toolkit.Invalid('spatial_uri: uri unknown') + except (IOError, json.decoder.JSONDecodeError, KeyError) as e: + log.error(f"Error processing spatial mapping: {e}") + raise toolkit.Invalid("Error processing spatial mapping") new_index = next_extra_index(data) @@ -261,7 +271,7 @@ def _copy_spatial_uri_temp_to_extras(data): data[('extras', next_index, 'value')] = spatial_uri else: _set_value(data, 'spatial_uri', spatial_uri) - + def next_extra_index(data): current_indexes = [k[1] for k in list(data.keys()) @@ -275,7 +285,8 @@ def validate_relatedPackage(data): try: get_package_dict(data) except logic.NotFound: - raise toolkit.Invalid("relatedPackage: package '{}' not found".format(data)) + raise toolkit.Invalid( + "relatedPackage: package '{}' not found".format(data)) def validate_formats(data, errors): @@ -283,7 +294,8 @@ def validate_formats(data, errors): raise toolkit.Invalid('Missing format.') if not any(data.upper() == obj['key'] for obj in odsh_resource_formats()): - raise toolkit.Invalid(_('Only formats on the list of the EU Publications Office are allowed.')) + raise toolkit.Invalid( + _('Only formats on the list of the EU Publications Office are allowed.')) return data @@ -293,7 +305,8 @@ def tag_name_validator(value, context): """ tagname_match = re.compile(r'^(?=.*[^\n])[^\n]*$', re.UNICODE) if not tagname_match.match(value): - raise toolkit.Invalid(_('Invalid tag: "%s". Tags cannot contain line breaks.') % (value)) + raise toolkit.Invalid( + _('Invalid tag: "%s". Tags cannot contain line breaks.') % (value)) return value @@ -302,7 +315,7 @@ def get_validators(): 'known_spatial_uri': known_spatial_uri, 'odsh_validate_extras': validate_extras, 'validate_licenseAttributionByText': validate_licenseAttributionByText, - 'validate_relatedPackage': validate_relatedPackage, + 'validate_relatedPackage': validate_relatedPackage, 'odsh_validate_format': validate_formats, 'tag_name_validator': tag_name_validator, }