diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3e20b46d5b2c9e7b7153e2af6c9bcad183335306 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# ckanext-odsh +Diese CKAN-Extension enthält die wichtigsten Features und das Layout für das Tranzparenzportal Schleswig-Holstein. +Sie ist eine Weiterentwicklung der gleichnamigen Extension, die im Zuge der Entwicklung des Open Data Portals Schleswig-Holstein entwickelt wurde. + +## Branches +### master +Dieser Branch enthält den aktuell auf den Stage- bzw. Prod-Servern laufenden Code. + +### dev +Dieser Branch enthält den aktuellsten Stand mit allen fertig entwickelten Features. + +### andere Branches +Für die Entwicklung neuer Features soll jeweils ein eigener Branch vom dev-Branch abgezweigt werden. Für den Branch soll ein sprechender Name gewählt werden. + +## Deployment auf Produktivsystem +Das Deployment auf das Produktivsystem geschieht über Ansible. Die dafür benötigten Skripte befinden sich im Repository `tpsh_deploy`. + +## Manuelle Installation + + +## Konfiguration +Die Extension benötigt Konfigurationsparameter in der CKAN-Konfigurationsdatei (z.B. `production.ini`). Die korrekten Parameter für das Produktivsystem befinden sich im Repository `tpsh_deploy` unter `resources/production.ini`. Folgende Parameter sollten für Enwicklungssysteme geändert werden: + +| Parameter | Erläuterung | Wert für Entwicklungssysteme | +|---------------------------------------|---------------------------------------------------------------|-------------------------------------------| +| ckanext.odsh.use_matomo | `true` schaltet das matomo-Tracking ein. | `false` | +| ckanext.odsh.skip_icap_virus_check | `false` schaltet den Virus-Check ein. | `true` | +| ckanext.odsh.showtestbanner | `true` schaltet das Banner "Testsystem" ein, Muss `false` für Production-Server sein. | - | \ No newline at end of file diff --git a/ckanext/odsh/fanstatic/tpsh_validate_password.js b/ckanext/odsh/fanstatic/tpsh_validate_password.js new file mode 100644 index 0000000000000000000000000000000000000000..f0f8f71b55e4f6a2cd9e52c6a39b09ab302d2dab --- /dev/null +++ b/ckanext/odsh/fanstatic/tpsh_validate_password.js @@ -0,0 +1,71 @@ +"use strict"; + +function isPasswordValid(password) { + if (password.length == 0) return true; + var minimumLength = 8; + var isValid = + (password.length >= minimumLength) && + (atLeastOneUpperCaseLetter(password)) && + (atLeastOneLowerCaseLetter(password)) && + (atLeastOneNoneLetter(password)); + return isValid + + function atLeastOneUpperCaseLetter(password) { + return (password !== password.toLowerCase()) + } + + function atLeastOneLowerCaseLetter(password) { + return (password !== password.toUpperCase()) + } + + function atLeastOneNoneLetter(password) { + return /[\W\d_]/.test(password) + } +} + + +function showPasswordStatus(isValid, inputElement) { + if (isValid) { + messageText = ''; + } else { + messageText = 'Passwörter müssen länger als 8 Zeichen sein und Großbuchstaben, Kleinbuchstaben und andere Zeichen enthalten.' + } + get_error_element(inputElement).innerHTML = messageText; + + function get_error_element(inputElement) { + // assumes that there is an element after input_element's parent that + // contains a class "inline-error" + var currentNode = inputElement.parentNode + do { + currentNode = currentNode.nextElementSibling; + } while ( + (currentNode !== null) && + !(currentNode.classList.contains('inline-error')) + ) + return currentNode + } +} + + +function setSubmitButtonState(isPasswordValid) { + var submitButton = document.getElementsByName('save')[0]; + submitButton.disabled = !isPasswordValid; +} + + +ckan.module('tpsh_validate_password', function ($) { + return { + initialize: function () { + $.proxyAll(this, /_on/); + this.el.on('input', this._onChange); + }, + + _onChange: function(event) { + var inputElement = event.target; + var newPassword = inputElement.value; + var isValid = isPasswordValid(newPassword); + showPasswordStatus(isValid, inputElement); + setSubmitButtonState(isValid); + } + }; +}); \ No newline at end of file diff --git a/ckanext/odsh/harvest_templates/source/search.html b/ckanext/odsh/harvest_templates/source/search.html index 674caf9b10ffe2283f76d36c37fd8c8eb1eef368..784caf4f62af9b4f0d6cb6bd2c89f4368bb6626a 100644 --- a/ckanext/odsh/harvest_templates/source/search.html +++ b/ckanext/odsh/harvest_templates/source/search.html @@ -69,14 +69,14 @@ <div class="module-content error-page"> <div class="error-title"> HTTP Status 404 - <div class="error-body"><h2>Seite nicht gefunden</h2> - <h3>Wie finde ich die gesuchten Inhalte im Landesportal?</h3> + <div class="error-body"><h2>Seite nicht gefunden</h2> + <h3>Wie finde ich die gesuchten Inhalte im Landesportal?</h3> - <p><a class="" href="http://www.schleswig-holstein.de/tpstart" title="Zur Startseite">Zur Startseite des Open-Data-Portals</a></p> + <p><a class="" href="http://www.schleswig-holstein.de/tpstart" title="Zur Startseite">Zur Startseite des Transparenzportals</a></p> - <h3>Kontakt</h3> - <p>Bei Fragen oder Problemen mit dem Open-Data-Portal schicken Sie bitte eine E-Mail an die Adresse opendata@lr.landsh.de oder verwenden das Kontaktformular:</p> - <p><a class="" href="https://www.schleswig-holstein.de/tpkontakt" title="Kontakt">Zum Kontaktformular</a></p> + <h3>Kontakt</h3> + <p>Bei Fragen oder Problemen mit dem Transparenzportal schicken Sie bitte eine E-Mail an die Adresse transparenz@lr.landsh.de oder verwenden das Kontaktformular:</p> + <p><a class="" href="https://www.schleswig-holstein.de/tpkontakt" title="Kontakt">Zum Kontaktformular</a></p> </div> </div> </div> diff --git a/ckanext/odsh/helpers_tpsh.py b/ckanext/odsh/helpers_tpsh.py index 7a046688d74ceb55599a7180b3fb0a315776678a..608c91016c353ca9de29934c3b06a0c52dd1c4d8 100644 --- a/ckanext/odsh/helpers_tpsh.py +++ b/ckanext/odsh/helpers_tpsh.py @@ -1,3 +1,5 @@ +# encoding: utf-8 + import csv import datetime import logging @@ -5,6 +7,7 @@ from string import lower import json import re import urllib2 +from collections import OrderedDict from ckan.common import config import ckan.lib.helpers as helpers @@ -99,9 +102,12 @@ def load_language_mapping(): LANGUAGE_MAPPING = json.loads(language_mapping_json.read()) return LANGUAGE_MAPPING +def load_json_to_ordered_dict(json_str): + return json.loads(json_str, object_pairs_hook=OrderedDict) + def load_subject_mapping(): with open(config.get('ckanext.odsh.subject_mapping')) as subject_mapping_json: - SUBJECT_MAPPING = json.loads(subject_mapping_json.read()) + SUBJECT_MAPPING = load_json_to_ordered_dict(subject_mapping_json.read()) return SUBJECT_MAPPING def get_language_of_package(pkg_dict): @@ -177,3 +183,29 @@ def get_resource_size(resource): resource_size = resource.get('size') if resource_size: return size_of_fmt(resource_size) + + +def get_address_org(organization): + list_extras = organization.get('extras') + address = dict() + if not list_extras: + return address + for extra in list_extras: + address.update({extra.get('key'):extra.get('value')}) + web = address.get('web') + if web and not web.startswith('http'): + web = 'http://' + web + address.update({'web':web}) + return address + + +def get_body_mail(organization, package): + package_name = package.get('name') + url = helpers.url_for(controller='package', action='read', id=package_name, qualified = True) + title = package.get('title') + anrede = "Sehr geehrte Damen und Herren," + "%0D%0A" + "%0D%0A" + "zu folgendem Eintrag habe ich eine Anmerkung/Frage:" + "%0D%0A" + "%0D%0A" + mail_titel = "Titel: " + title + "%0D%0A" + mail_document = "Dokument-ID: " + package_name + "%0D%0A" + mail_url = "URL: " + url + "%0D%0A" + "%0D%0A" + message = mail_titel + mail_document + mail_url + "Mein Kommentar:" + "%0D%0A" + "%0D%0A" + "%0D%0A" + "%0D%0A" + return anrede + message \ No newline at end of file diff --git a/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.mo b/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.mo index 5d92c5165b244dcc9893c7204ee7debfbe2156ae..e5231b5c445d99ba368944a4870058a2d41ed820 100644 Binary files a/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.mo and b/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.mo differ diff --git a/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.po b/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.po index 4f512dcb230c708c38f7f70841a93bcfbd8b098a..67d07054ce4865ff9540a1ace832104c2edeebca 100644 --- a/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.po +++ b/ckanext/odsh/i18n/de/LC_MESSAGES/ckanext-odsh.po @@ -348,10 +348,10 @@ msgid "Score" msgstr "Open-Data-Eigenschaften" msgid "Issued Ascending" -msgstr "Veröffentlichungsdatum aufsteigend" +msgstr "Veröffentlichungsdatum: Älteste zuerst" msgid "Issued Descending" -msgstr "Veröffentlichungsdatum absteigend" +msgstr "Veröffentlichungsdatum: Neueste zuerst" msgid "Name Resource" msgstr "Name Ressource" @@ -488,17 +488,18 @@ msgstr "Enddatum" msgid "main nav menu" msgstr "Navigations-Hauptmenü" -msgid "Start Date Ascending" -msgstr "Startdatum aufsteigend" msgid "Start Date Descending" -msgstr "Starttdatum absteigend" +msgstr "Startdatum: Neueste zuerst" -msgid "End Date Ascending" -msgstr "Enddatum aufsteigend" +msgid "Start Date Ascending" +msgstr "Startdatum: Älteste zuerst" msgid "End Date Descending" -msgstr "Enddatum absteigend" +msgstr "Enddatum: Neueste zuerst" + +msgid "End Date Ascending" +msgstr "Enddatum: Älteste zuerst" msgid "send an email" msgstr "E-Mail senden" @@ -534,4 +535,10 @@ msgstr[0] "Kategorie:" msgstr[1] "Kategorien:" msgid "Publisher" -msgstr "Herausgeber" \ No newline at end of file +msgstr "Herausgeber" + +msgid "Name Ascending" +msgstr "Name: A – Z" + +msgid "Name Descending" +msgstr "Name: Z – A" \ No newline at end of file diff --git a/ckanext/odsh/logic/action.py b/ckanext/odsh/logic/action.py index 3a92fcbb07ff8ad6fb0a5e21f4f043b0e3698d5e..481a72ac130bf8447c89be96dcc27f6ddde28832 100644 --- a/ckanext/odsh/logic/action.py +++ b/ckanext/odsh/logic/action.py @@ -1,4 +1,6 @@ import logging +import ckan.logic as logic +from ckan.logic.action.update import user_update from ckan.logic.action.create import package_create, user_create, group_member_create import ckan.model as model import ckan.lib.dictization.model_dictize as model_dictize @@ -44,13 +46,38 @@ def munge_increment_name(data_dict): data_dict['name'] = name +def check_password(password): + return (len(password) >= 8 and + any(c.islower() for c in password) and + any(c.isupper() for c in password) and + any((c.isalpha()==False) for c in password)) #Number or Special character + +PASSWORD_ERROR_MESSAGE = {'security': ['Passwort muss mindestens acht Zeichen, einen Gross-, einen Kleinbuchstaben und entweder eine Zahl oder ein Sondernzeichen enthalten!']} + def odsh_user_create(context, data_dict): model = context['model'] - user = user_create(context, data_dict) - groups = toolkit.get_action('group_list')(data_dict={'all_fields': False}) - for group in groups: - group_member_create(context, {'id': group, 'username': user.get('name'), 'role': 'member'}) - return model_dictize.user_dictize(model.User.get(user.get('name')), context) + password = data_dict.get('password') + if not password: + password = data_dict.get('password1') + if check_password(password): + user = user_create(context, data_dict) + groups = toolkit.get_action('group_list')(data_dict={'all_fields': False}) + + for group in groups: + group_member_create(context, {'id': group, 'username': user.get('name'), 'role': 'member'}) + return model_dictize.user_dictize(model.User.get(user.get('name')), context) + else: + raise logic.ValidationError(PASSWORD_ERROR_MESSAGE) + +def tpsh_user_update(context, data_dict): + password = data_dict.get('password') + if not password: + password = data_dict.get('password1') + if password and not check_password(password): + raise logic.ValidationError(PASSWORD_ERROR_MESSAGE) + return user_update(context, data_dict) + + @toolkit.side_effect_free diff --git a/ckanext/odsh/pdf_to_thumbnail/helpers.py b/ckanext/odsh/pdf_to_thumbnail/helpers.py index ceb4027c81c440f55e2b5c6ef9c017933242bb11..faddfaa0691b19f158df50b13b352e9ff2a642c5 100644 --- a/ckanext/odsh/pdf_to_thumbnail/helpers.py +++ b/ckanext/odsh/pdf_to_thumbnail/helpers.py @@ -1,13 +1,27 @@ -from ckan.lib.helpers import resource_display_name +from ckan.lib.helpers import is_url, url_for def thumbnail_namespace(filename): return "/" + filename -def get_name_from_last_pdf_upload(package): +def get_download_link_for_thumbnail(package): resources = package.get('resources') for resource in resources[::-1]: url_type =resource.get('url_type') mimetype = resource.get('mimetype') if url_type == 'upload' and mimetype == 'application/pdf': - return resource_display_name(resource) + package_id = resource.get('package_id') + resource_id = resource.get('id') + pre_resource_url = resource.get('url') + if is_url(pre_resource_url): + url_resource = pre_resource_url + else: + url_resource = url_for(controller='package', + action='resource_download', + id=package_id, + resource_id=resource_id, + filename=pre_resource_url, + qualified = True) + + + return url_resource diff --git a/ckanext/odsh/pdf_to_thumbnail/plugin.py b/ckanext/odsh/pdf_to_thumbnail/plugin.py index 4093236370ee85a821d1ae1d7caf4fdb434ce8ab..715235990b6515a9b9d86a2a4f063c8da5e2bf7e 100644 --- a/ckanext/odsh/pdf_to_thumbnail/plugin.py +++ b/ckanext/odsh/pdf_to_thumbnail/plugin.py @@ -22,8 +22,8 @@ class ThumbnailPlugin(plugins.SingletonPlugin): #IResourceController def after_create(self, context, resource): - _, size, filename = thumbnail.create_thumbnail(context, resource) - thumbnail.write_thumbnail_into_package(context, resource, size, filename) + _, filename = thumbnail.create_thumbnail(context, resource) + thumbnail.write_thumbnail_into_package(context, resource, filename) def after_update(self, context, resource): thumbnail.check_and_create_thumbnail_after_update(context, resource) @@ -54,5 +54,5 @@ class ThumbnailPlugin(plugins.SingletonPlugin): return { 'thumbnail_namespace':thumbnail_helpers.thumbnail_namespace, - 'thumbnail_get_name_from_last_pdf_upload':thumbnail_helpers.get_name_from_last_pdf_upload + 'thumbail_get_download_link':thumbnail_helpers.get_download_link_for_thumbnail } diff --git a/ckanext/odsh/pdf_to_thumbnail/thumbnail.py b/ckanext/odsh/pdf_to_thumbnail/thumbnail.py index 904e31704a487149a5814572015efeae85f8060b..ea0f06b32a7d8eba85a6ca9a486ebf1b7bf009b6 100644 --- a/ckanext/odsh/pdf_to_thumbnail/thumbnail.py +++ b/ckanext/odsh/pdf_to_thumbnail/thumbnail.py @@ -81,7 +81,7 @@ def create_thumbnail_from_file(file, old_filename): def create_thumbnail_from_url(resource, old_filename): - return False, None, None + return False, None ''' # Requests does not work on a server but on a local test enviroment. # With the given configuration of a wsgi server and apache it did not work @@ -114,15 +114,14 @@ def create_thumbnail_from_url(resource, old_filename): def create_thumbnail_from_memory(resource, old_filename): path = get_filepath_to_resource(resource) file_type = magic.from_file(path, mime = True) - resource_size = os.path.getsize(path) if file_type == 'application/pdf': with open(path, 'rb') as file: new_filename = create_thumbnail_from_file(file, old_filename) is_PDF = True - return is_PDF, resource_size, new_filename + return is_PDF, new_filename else: is_PDF = False - return is_PDF, resource_size, None + return is_PDF, None def remove_thumbnail(context): old_filename = get_filename_from_context(context) @@ -135,32 +134,33 @@ def create_thumbnail(context, resource): old_filename = get_filename_from_context(context) url_type = resource.get('url_type') if url_type == 'upload': - is_PDF, size, filename = create_thumbnail_from_memory(resource, old_filename) + is_PDF, filename = create_thumbnail_from_memory(resource, old_filename) else: - is_PDF, size, filename = create_thumbnail_from_url(resource, old_filename) - return is_PDF, size, filename + is_PDF, filename = create_thumbnail_from_url(resource, old_filename) + return is_PDF, filename def check_and_create_thumbnail_after_update(context, resource): package_id = resource.get('package_id') package = toolkit.get_action('package_show')(context, {'id': package_id}) resources = package.get('resources') - last_resource = resources.pop() - last_resource_id = last_resource.get('id') - resource_id = resource.get('id') + if len(resources) > 0: + last_resource = resources.pop() + last_resource_id = last_resource.get('id') + resource_id = resource.get('id') if last_resource_id == resource_id and resource.get('url_type') != 'upload': - is_PDF, size, filename = create_thumbnail(context, resource) + is_PDF, filename = create_thumbnail(context, resource) if is_PDF: - write_thumbnail_into_package(context, resource, size, filename) + write_thumbnail_into_package(context, resource, filename) def create_thumbnail_for_last_resource(context, resources): if len(resources) > 0: last_resource = resources.pop() - is_PDF, size, filename = create_thumbnail(context, last_resource) + is_PDF, filename = create_thumbnail(context, last_resource) if not is_PDF: create_thumbnail_for_last_resource(context, resources) else: - write_thumbnail_into_package(context, last_resource, size , filename) + write_thumbnail_into_package(context, last_resource, filename) else: remove_thumbnail(context) package = context.get('package') @@ -169,20 +169,9 @@ def create_thumbnail_for_last_resource(context, resources): package.update({'thumbnail': None}) toolkit.get_action('package_update')(context, package) -def update_last_resource_if_value_empty(context, resource, key, value): - package_id = resource.get('package_id') - package = toolkit.get_action('package_show')(context, {'id': package_id}) - resources = package.get('resources') - last_resource = resources.pop() - if not last_resource.get(key): - last_resource.update({key: value}) - resources.append(last_resource) - package.update({'resources': resources}) - return package - - -def write_thumbnail_into_package(context, resource, size, filename): - package = update_last_resource_if_value_empty(context, resource, 'size', size) +def write_thumbnail_into_package(context, resource, filename): + package_id = resource.get('package_id') + package = toolkit.get_action('package_show')(context, {'id': package_id}) if filename: package.update({'thumbnail': filename}) toolkit.get_action('package_update')(context, package) \ No newline at end of file diff --git a/ckanext/odsh/plugin.py b/ckanext/odsh/plugin.py index 02207d82131f7d73548df502b3fb4bbb592e4605..3dfc22ab246746e60cb7c1f9cc232f779e5e7e66 100644 --- a/ckanext/odsh/plugin.py +++ b/ckanext/odsh/plugin.py @@ -50,6 +50,7 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm def get_actions(self): return {'package_create': action.odsh_package_create, + 'user_update':action.tpsh_user_update, 'user_create': action.odsh_user_create} @@ -200,7 +201,11 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm def after_create(self, context, resource): if resource.get('package_id'): - tools.save_hash_into_resource(context, resource) + tools.add_attributes_resources(context, resource) + + def after_update(self, context, resource): + if resource.get('package_id'): + tools.add_attributes_resources(context, resource) @staticmethod def _update_is_new_in_pkg_dict(pkg_dict): @@ -290,7 +295,7 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm m.connect('/user/logged_in', action='logged_in') m.connect('/user/logged_out', action='logged_out') m.connect('/user/logged_out_redirect', action='logged_out_page') - m.connect('user_datasets', '/user/{id:.*}', action='read', + m.connect('user_datasets', '/user/{id:(?!(generate_key|activity)).*}', action='read', ckan_icon='sitemap') map.connect( @@ -356,6 +361,8 @@ class OdshPlugin(plugins.SingletonPlugin, DefaultTranslation, DefaultDatasetForm 'get_subject_for_selection': helpers_tpsh.get_subject_for_selection, 'get_language_for_selection': helpers_tpsh.get_language_for_selection, 'tpsh_get_resource_size': helpers_tpsh.get_resource_size, + 'tpsh_get_address_org':helpers_tpsh.get_address_org, + 'tpsh_get_body_mail':helpers_tpsh.get_body_mail, } diff --git a/ckanext/odsh/public/base/images/icon_phone.svg b/ckanext/odsh/public/base/images/icon_phone.svg new file mode 100644 index 0000000000000000000000000000000000000000..3f8189d6c89ee21adb6af5d2a895600fd0204756 --- /dev/null +++ b/ckanext/odsh/public/base/images/icon_phone.svg @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 52.5 (67469) - http://www.bohemiancoding.com/sketch --> + <title>local_phone</title> + <desc>Created with Sketch.</desc> + <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Rounded" transform="translate(-341.000000, -3213.000000)"> + <g id="Maps" transform="translate(100.000000, 3068.000000)"> + <g id="-Round-/-Maps-/-local_phone" transform="translate(238.000000, 142.000000)"> + <g> + <polygon id="Path" points="0 0 24 0 24 24 0 24"></polygon> + <path d="M19.23,15.26 L16.69,14.97 C16.08,14.9 15.48,15.11 15.05,15.54 L13.21,17.38 C10.38,15.94 8.06,13.63 6.62,10.79 L8.47,8.94 C8.9,8.51 9.11,7.91 9.04,7.3 L8.75,4.78 C8.63,3.77 7.78,3.01 6.76,3.01 L5.03,3.01 C3.9,3.01 2.96,3.95 3.03,5.08 C3.56,13.62 10.39,20.44 18.92,20.97 C20.05,21.04 20.99,20.1 20.99,18.97 L20.99,17.24 C21,16.23 20.24,15.38 19.23,15.26 Z" id="🔹-Icon-Color" fill="#003064"></path> + </g> + </g> + </g> + </g> + </g> +</svg> \ No newline at end of file diff --git a/ckanext/odsh/public/base/images/platzhalter.svg b/ckanext/odsh/public/base/images/platzhalter.svg new file mode 100644 index 0000000000000000000000000000000000000000..746fb2026e686850a5b0c295612f98768f866e28 --- /dev/null +++ b/ckanext/odsh/public/base/images/platzhalter.svg @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + id="svg10" + xml:space="preserve" + width="793.70074" + height="1122.5197" + viewBox="0 0 793.70074 1122.5197" + sodipodi:docname="platzhalter.svg" + inkscape:version="0.92.4 (unknown)"><metadata + id="metadata16"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs + id="defs14" /><sodipodi:namedview + pagecolor="#f1f1f1;" + bordercolor="#f1f1f1;" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1855" + inkscape:window-height="1056" + id="namedview12" + showgrid="false" + inkscape:zoom="0.81423964" + inkscape:cx="205.87465" + inkscape:cy="561.25983" + inkscape:window-x="65" + inkscape:window-y="24" + inkscape:window-maximized="1" + inkscape:current-layer="g18" /><g + id="g18" + inkscape:groupmode="layer" + inkscape:label="plazthalter" + transform="matrix(1.3333333,0,0,-1.3333333,0,1122.5197)"><g + id="g20"><g + id="g22" + transform="matrix(1,0,0,-1,0,841.88977)"><path + d="M 2.145,1.891 H 597.856 V 844.032 H 2.145 Z" + style="fill:#f1f1f1;fill-opacity:1;fill-rule:nonzero;stroke:#c8b7b7;stroke-width:0.75;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path24" + inkscape:connector-curvature="0" /></g></g></g></svg> \ No newline at end of file diff --git a/ckanext/odsh/public/odsh.css b/ckanext/odsh/public/odsh.css index 2c3874749d6ec14d69e138e017dfb478c89a8a99..47a567da70b96179e763434aadc828e8d5ee3194 100644 --- a/ckanext/odsh/public/odsh.css +++ b/ckanext/odsh/public/odsh.css @@ -79,6 +79,18 @@ h3{ font-size:20px; } +.skip-link { + position: fixed; + top: -200px; + text-decoration: none; + padding: 10px; + display: inline-block; + } + +.skip-link:focus { + top: 0; +} + .secondary h1.heading { color:black; font-weight: normal ; @@ -106,12 +118,16 @@ h3{ } @media (max-width: 767px) { - .container, - .masthead .container + .container { padding-right: 15px; padding-left: 15px; } + .masthead .container + { + padding-right: 0; + padding-left: 0; + } } .search-form, .odsh-dataset-heading { @@ -123,6 +139,36 @@ h3{ margin-bottom: 0px; } +@media (min-width: 1024px){ + .search-form, .odsh-dataset-heading { + border-bottom: none; + margin-bottom: 0px; + margin-left: -15px; + margin-right: -15px; + padding-bottom: 0; + } + + .search-form:after { + content: ""; + display: block; + margin: 0 auto; + width: calc(100% - 30px); + padding-top: 25px; + border-bottom: 4px solid #dbdbdb; + order: 100; + } + + .search-form h2 { + margin-left: 15px; + } + + .form-select.control-group.control-order-by { + margin-left: 15px; + margin-right: 15px; + } +} + + .organizaion-full-description{ padding-bottom: 50px; @@ -156,6 +202,7 @@ h3{ .odsh-dataset-heading .title { margin-top: 0px; + margin-bottom: 10px; margin-right: 22px; font-size: 24px; letter-spacing: 0.01em; @@ -199,7 +246,11 @@ section#dataset-preview p { display: flex; } -.container-preview-large > img { +.container-preview-large a { + margin-left: auto; +} + +.container-preview-large img { height: 100%; margin-left: auto; margin-right: auto; @@ -270,6 +321,35 @@ section#dataset-collection .button-container img { border-bottom: solid 3px #DBDBDB; } +.information-organisation { + margin-top: 20px; + font-size: 12px; + text-align: left; + letter-spacing: 0.12px; + color: #000000; +} + +.information-organisation p { + margin-bottom: 0; +} + +.information-organisation a { + color: inherit; +} + +.information-organisation .phone::before{ + content: ""; + display: inline-block; + background-image: url(/base/images/icon_phone.svg); + background-repeat: no-repeat; + background-size: .7rem .7rem; + background-position: 50% 50%; + width: 0.8rem; + height: 0.8rem; + vertical-align: middle; +} + + .module-narrow .module-footer { padding: 0; border: none; @@ -464,7 +544,8 @@ input[type=radio], input[type=checkbox] { .category-header { display: inline-block; - padding-right: 6px + padding-right: 6px; + vertical-align: top; } .category-icon-container { @@ -570,7 +651,8 @@ label.rangesearch.disabled { .controls input.rangesearch{ box-sizing: border-box; width: 100%; - padding: 12px 2px; + height: 1.5rem; + padding: 2px; font-style: normal; font-size: 12px; line-height: 1.16666667em; @@ -628,6 +710,9 @@ label.rangesearch.disabled { .odsh-dataset-item:hover { background-color: rgb(246,247,249); } +.odsh-dataset-item:last-child { + border-bottom: none; +} .preview-image-container { display: flex; @@ -642,7 +727,7 @@ label.rangesearch.disabled { } } -.preview-image-container > img { +.preview-image-container img { margin-top: auto; height: auto; max-width: 102px; @@ -748,8 +833,6 @@ ul.dataset-resources { } -element.style { -} .dataformat-label:hover { background-color: #d4004b!important; } @@ -760,10 +843,6 @@ element.style { margin-bottom: 10px; } - -.popover-content{ - -} .popover{ width: unset; display:inline-table!important; @@ -864,6 +943,11 @@ label:after { font-style: normal; } +input#field-username { + margin-bottom: 30px; + vertical-align: super; +} + .control-group.error input, .control-group.error select, .control-group.error .select2-choices, @@ -1158,15 +1242,10 @@ label:after { .footer a{ color:white; } -@media (max-width: 1023px){ -.footer{ - border-top:0px; - width: 100%; -} body { background-color: white; } -} + .footer .container{ width: 100%; max-width: 1000px; @@ -1208,6 +1287,50 @@ body { margin-top: 10px; } +@media (max-width: 1023px){ + .footer{ + border-top-width: 30px; + width: 100%; + } + .footer-line{ + border-top: 1px solid white; + } +} + +@media (max-width: 767px){ + .footer{ + border-top-width: 20px; + } + .footer .container { + padding-bottom: 0; + } + .footer-line{ + border-top: none; + margin-top: 0; + margin-bottom: 0; + } + .footer-content{ + box-sizing: border-box; + padding-bottom: 15px; + background-image: none; + height: 139px; + display: flex; + flex-direction: column-reverse; + } + .footer-first-row{ + padding-top: 0; + height: 0; + } + .footer-right{ + display: flex; + justify-content: space-between; + padding-bottom: 15px; + } + .footer-icon a{ + padding: 15px 0; + } +} + .toolbar .breadcrumb li:after { background-image: url(/base/images/arrow-right.png); background-repeat: no-repeat; @@ -1355,14 +1478,10 @@ body { text-align: center; } -element.style { -} .dataformat-label:hover { background-color: #d4004b!important; } - - .resource-title { float: left; margin-left: 5px; @@ -1385,10 +1504,16 @@ element.style { text-decoration: none } -.resource-title p{ +.resource-title p:first-of-type{ font-size: 12px; letter-spacing: 0.12px; padding-top: 12px; + margin-bottom: 0; +} +.resource-title p{ + font-size: 12px; + letter-spacing: 0.12px; + padding-top: 0; } .resource-title-container{ @@ -1852,6 +1977,10 @@ element.style { } } +#dataset-search-box-form{ + margin-bottom: 0; +} + @media (max-width: 767px){ .site-title{ display: none; @@ -1865,12 +1994,14 @@ element.style { #menu-button-and-title { display: flex; align-items: center; + padding-left: 15px; + padding-right: 15px; + background-color: #f2f2f2; } } #menu-button-and-title span { display: inline-block; color: #003064; - padding-left: 10px; padding-right: 20px; } #menu-button-and-title h1 { @@ -1885,11 +2016,23 @@ element.style { margin-left: 0; } +.search-form .filter-list { + width: 100% +} + .filter-list .filtered.pill, .filter-list .filtered.pill .fa{ background-color: #003064; color:white; } + +@media (min-width: 1024px){ + .search-form .filter-list { + margin-left: 15px; + margin-right: 15px; + } +} + .filtered.pill.error{ background-color: #d4004b; } diff --git a/ckanext/odsh/public/odsh_header.css b/ckanext/odsh/public/odsh_header.css index 8160230bd2cbe9f8ebd692b1ffc57cd724935841..f32a5f642ec764496f478f8f70d69e73ef82b161 100644 --- a/ckanext/odsh/public/odsh_header.css +++ b/ckanext/odsh/public/odsh_header.css @@ -38,6 +38,7 @@ padding-right: 0; position: relative; top: 0; + left: 18px; padding: 1em 0; } diff --git a/ckanext/odsh/templates/error_document_template.html b/ckanext/odsh/templates/error_document_template.html index 1cfdb218ec14cc889c7f3d5d27769f3f51cc1442..45911fe2f67f355879f5809b315e55984ec9e03f 100644 --- a/ckanext/odsh/templates/error_document_template.html +++ b/ckanext/odsh/templates/error_document_template.html @@ -15,10 +15,10 @@ {% endif %} <h3>Wie finde ich die gesuchten Inhalte im Landesportal?</h3> - <p><a class="" href="http://www.schleswig-holstein.de/tpstart" title="Zur Startseite">Zur Startseite des Open-Data-Portals</a></p> + <p><a class="" href="http://www.schleswig-holstein.de/tpstart" title="Zur Startseite">Zur Startseite des Transparenzportals</a></p> <h3>Kontakt</h3> - <p>Bei Fragen oder Problemen mit dem Open-Data-Portal schicken Sie bitte eine E-Mail an die Adresse opendata@lr.landsh.de oder verwenden das Kontaktformular:</p> + <p>Bei Fragen oder Problemen mit dem Transparenzportal schicken Sie bitte eine E-Mail an die Adresse transparenz@lr.landsh.de oder verwenden das Kontaktformular:</p> <p><a class="" href="https://www.schleswig-holstein.de/tpkontakt" title="Kontakt">Zum Kontaktformular</a></p> </div> {% endif %} diff --git a/ckanext/odsh/templates/footer.html b/ckanext/odsh/templates/footer.html index b1212dba15b04d860702804730bf8ee107168b81..03764a7c7b58782fb85faee0af0af365732205df 100644 --- a/ckanext/odsh/templates/footer.html +++ b/ckanext/odsh/templates/footer.html @@ -8,11 +8,11 @@ <div class='footer-line'></div> <div class="footer-left"> <div class="footer-icon">© {{g.site_title}}</div> - <div class="footer-right"> - <div class='footer-icon'><a href='http://www.schleswig-holstein.de/tpkontakt'>Kontakt</a></div> - <div class='footer-icon'><a href='http://www.schleswig-holstein.de/tpimpressum'>Impressum</a></div> - <div class='footer-icon last'><a href='http://www.schleswig-holstein.de/tpdatenschutz'>Datenschutz</a></div> - </div> + </div> + <div class="footer-right"> + <div class='footer-icon'><a href='http://www.schleswig-holstein.de/tpkontakt'>Kontakt</a></div> + <div class='footer-icon'><a href='http://www.schleswig-holstein.de/tpimpressum'>Impressum</a></div> + <div class='footer-icon last'><a href='http://www.schleswig-holstein.de/tpdatenschutz'>Datenschutz</a></div> </div> </div> </div> diff --git a/ckanext/odsh/templates/header.html b/ckanext/odsh/templates/header.html index 662acfe5ab63466e0c799db0464492c5dfb44d00..f7419ab93400a1b6850cd432045dcd65e1d3e823 100644 --- a/ckanext/odsh/templates/header.html +++ b/ckanext/odsh/templates/header.html @@ -39,7 +39,7 @@ <ul class="nav nav-pills"> <li class="header-menu-mobile" data-module="tpsh_toggle_menu"> <a>Menü</a> - <img src="/base/images/icon_close_white.svg"> + <img src="/base/images/icon_close_white.svg" alt="Menü schließen" aria-label="Menü schließen"> </li> {% block header_site_navigation_tabs %} {{ @@ -66,21 +66,21 @@ d="M42.5,44.5h-31v-6.4c0-4.7,3.9-8.6,8.6-8.6h13.9c4.7,0,8.6,3.9,8.6,8.6V44.5z" /> </svg> {{name}}</a> - <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel"> + <ul class="dropdown-menu" role="menu"> <li> <svg class='user-icon-small' viewBox="0 0 54 54"> <circle cx="27" cy="17" r="7.5" /> <path d="M42.5,44.5h-31v-6.4c0-4.7,3.9-8.6,8.6-8.6h13.9c4.7,0,8.6,3.9,8.6,8.6V44.5z" /> </svg> - <a href="{{ h.url_for('/user/') }}" title="logout"> + <a href="{{ h.url_for('/user/') }}" title="logout" role="menuitem"> <span class="text"> Mein Profil einsehen </span> </a> </li> <li> - <a href="{{ h.url_for('/user/edit') }}" title="logout"> + <a href="{{ h.url_for('/user/edit') }}" title="logout" role="menuitem"> <i class='fa fa-edit'></i> <span class="text"> Mein Profil bearbeiten @@ -88,7 +88,7 @@ </a> </li> <li> - <a href="{{ h.url_for('/user/_logout') }}" title="logout"> + <a href="{{ h.url_for('/user/_logout') }}" title="logout" role="menuitem"> <i class='fa fa-sign-out'></i> <span class="text">Logout</span> </a> diff --git a/ckanext/odsh/templates/macros/form.html b/ckanext/odsh/templates/macros/form.html index f774803b99f93455019caa9d16c5899821852301..862c69eee75b6e20effeb981da4e4287fec103c3 100644 --- a/ckanext/odsh/templates/macros/form.html +++ b/ckanext/odsh/templates/macros/form.html @@ -95,6 +95,21 @@ is_required=false) %} </div> {% endmacro %} + +{% macro select(name, id='', label='', options='', selected='', error='', classes=[], attrs={'class': 'form-control'}, is_required=false) %} +{% set classes = (classes|list) %} +{% do classes.append('control-select') %} + +{%- set extra_html = caller() if caller -%} +{% call input_block(id or name, label or name, error, classes, extra_html=extra_html, is_required=is_required) %} +<select id="{{ id or name }}" name="{{ name }}" {{ attributes(attrs) }}> + {% for option in options %} +<option value="{{ option.value }}"{% if option.value == selected %} selected{% endif %}>{{ option.text or option.value }}</option> +{% endfor %} +</select> +{% endcall %} +{% endmacro %} + {# Creates all the markup required for an select element. Handles matching labels to inputs and error messages. @@ -119,7 +134,7 @@ Examples: selected=2011, error=errors.year) }} #} -{% macro select(name, id='', label='', options='', selected='', error='', classes=[], attrs={}, +{% macro tpsh_select(name, id='', label='', options='', selected='', error='', classes=[], attrs={}, is_required=false) %} {% set classes = (classes|list) %} {% do classes.append('control-select') %} @@ -346,6 +361,22 @@ is_required=is_required) %} {% endcall %} {% endmacro %} + + +{% macro input_address(field, label, value='', index='', placeholder='', type='text', attrs={}) %} +{%- set _type = 'text' if type=='date' and not value else type -%} +{%- set onFocus = 'onfocus=(this.type=\'date\')' if type=='date' and not value else '' -%} +<div class="row-fluid"> + <div class="span6"> + <label class="address-label"> {{ label }} </label> + <input id="field-{{field}}-key" type="hidden" name="extras__{{index}}__key" value="{{field}}" /> + <input id="field-{{field}}-value" type="{{_type}}" name="extras__{{index}}__value" value="{{value | empty_and_escape }}" placeholder="{{ placeholder }}" {{ onFocus }} {{ attributes(attrs) }}/> +</div> +</div> +{% endmacro %} + + + {# A generic input_block for providing the default markup for CKAN form elements. It is expected to be called using a {% call %} block, the contents of which diff --git a/ckanext/odsh/templates/organization/snippets/organization_form.html b/ckanext/odsh/templates/organization/snippets/organization_form.html index 4028d04852a5a92661fad71deaa3ed069504c2fd..364433fb5a1841e363507669c15fecdaf52598dc 100644 --- a/ckanext/odsh/templates/organization/snippets/organization_form.html +++ b/ckanext/odsh/templates/organization/snippets/organization_form.html @@ -25,32 +25,23 @@ {{ form.image_upload(data, errors, is_upload_enabled=h.uploads_enabled(), is_url=is_url, is_upload=is_upload) }} {% endblock %} - - {% block custom_fields %} - {% for extra in data.extras %} - {% set prefix = 'extras__%d__' % loop.index0 %} - {{ form.custom( - names=(prefix ~ 'key', prefix ~ 'value', prefix ~ 'deleted'), - id='field-extras-%d' % loop.index, - label=_('Custom Field'), - values=(extra.key, extra.value, extra.deleted), - error=errors[prefix ~ 'key'] or errors[prefix ~ 'value'] - ) }} - {% endfor %} - - {# Add a max if 3 empty columns #} - {% for extra in range(data.extras|count, 3) %} - {% set index = (loop.index0 + data.extras|count) %} - {% set prefix = 'extras__%d__' % index %} - {{ form.custom( - names=(prefix ~ 'key', prefix ~ 'value', prefix ~ 'deleted'), - id='field-extras-%d' % index, - label=_('Custom Field'), - values=(extra.key, extra.value, extra.deleted), - error=errors[prefix ~ 'key'] or errors[prefix ~ 'value'] - ) }} - {% endfor %} - {% endblock %} + + + + + {% set extras = h.tpsh_get_address_org(data) %} + + {{ form.input_address('person','Ansprechpartner', value= extras.person , index=0, placeholder='', type='text', attrs={}) }} + + {{ form.input_address('street','Straße', value= extras.street, index=1, placeholder='', type='text', attrs={}) }} + + {{ form.input_address('location','Stadt', value=extras.location, index=2, placeholder='', type='text', attrs={}) }} + + {{ form.input_address('telephone','Tel.-Nr.:', value=extras.telephone, index=3, placeholder='', type='text', attrs={}) }} + + {{ form.input_address('mail','e-mail', value=extras.mail, index=4, placeholder='', type='text', attrs={}) }} + + {{ form.input_address('web','Website', value=extras.web, index=5, placeholder='', type='text', attrs={}) }} {{ form.required_message() }} diff --git a/ckanext/odsh/templates/package/read.html b/ckanext/odsh/templates/package/read.html index cbb909f9d10622feee9212dc3c338003fc541e3c..c4943693413f50a0c40d8cb566c364fc67da9f66 100644 --- a/ckanext/odsh/templates/package/read.html +++ b/ckanext/odsh/templates/package/read.html @@ -5,7 +5,7 @@ {% set successor_url = h.collection_get_successor(pkg) %} {% set predecessor_url = h.collection_get_predecessor(pkg) %} {% set latest_collection_member = h.collection_get_latest_member(pkg) %} -{% set thumbnail_name = h.thumbnail_get_name_from_last_pdf_upload(pkg) %} +{% set thumbnail_url = h.thumbail_get_download_link(pkg) %} {% block breadcrumb_content %} {% if pkg %} @@ -80,7 +80,10 @@ <section id="dataset-preview"> <h3>{{ _('Preview') }}:</h3> <div class="container-preview-large"> - <img src= "{{ picture }}" alt= "Vorschau"/> + <a href="{{ thumbnail_url }}"> + + <img src= "{{ picture }}" alt= "Vorschau"/> + </a> </div> </section> {% endif %} diff --git a/ckanext/odsh/templates/package/read_base.html b/ckanext/odsh/templates/package/read_base.html index 24a3111d6c979d80fea6133b0dc684cfe8679b3a..99cb65fdda0f56337edb14a2135016b73955fbd5 100644 --- a/ckanext/odsh/templates/package/read_base.html +++ b/ckanext/odsh/templates/package/read_base.html @@ -12,7 +12,7 @@ {% snippet "package/snippets/close_mobile_sidebar_button.html" %} {% if pkg.organization %} {% set org = h.get_organization(pkg.organization.name) %} -{% snippet "snippets/organization.html", organization=org, has_context_title=true, hide_description=true %} +{% snippet "snippets/organization.html", package=pkg, organization=org, has_context_title=true, hide_description=true %} {% endif %} {% endblock %} diff --git a/ckanext/odsh/templates/package/snippets/close_mobile_sidebar_button.html b/ckanext/odsh/templates/package/snippets/close_mobile_sidebar_button.html index 87a19511442d1923bfef6b2c4f2e36a2f05dbadf..5e30ade9262d6db85bd7ed8792b3f92091950b7a 100644 --- a/ckanext/odsh/templates/package/snippets/close_mobile_sidebar_button.html +++ b/ckanext/odsh/templates/package/snippets/close_mobile_sidebar_button.html @@ -1,3 +1,3 @@ <div class="container-fluid hide-filters-style"> - <a class="no-text hide-filters"><img src="/base/images/icon_close.svg"><span class="text">close</span></a> + <a class="no-text hide-filters"><img src="/base/images/icon_close.svg" alt="Filterdialog schließen"><span class="text">close</span></a> </div> \ No newline at end of file diff --git a/ckanext/odsh/templates/package/snippets/info.html b/ckanext/odsh/templates/package/snippets/info.html index 08a1aef652005ac7a98d2fa95ea463de4c1a1d05..721cc4042219ee5b8e1ab618d347dea3bbc6f3f0 100644 --- a/ckanext/odsh/templates/package/snippets/info.html +++ b/ckanext/odsh/templates/package/snippets/info.html @@ -45,6 +45,7 @@ Example: {% endblock language %} {% block groups %} {# aka categories #} + {% if pkg.groups|length %} <div class="info-detail groups-detail"> <div> {% trans category_count=pkg.groups|length %} @@ -64,14 +65,17 @@ Example: </span> {% endfor %} </div> + {% endif %} {% endblock groups %} {% block timerange %} + {% if daterange %} <div class="timerange-detail info-detail"> <div>{{ _('timerange') }}:</div> - <p>{{ daterange if daterange else '-' }}</p> + <p>{{ daterange }}</p> </div> + {% endif %} {% endblock timerange %} diff --git a/ckanext/odsh/templates/package/snippets/package_basic_fields.html b/ckanext/odsh/templates/package/snippets/package_basic_fields.html index 9bffe6536e75185dd25201cc8d9e331ca58e24cd..7d24841fd6593de73512134cd155be2f54311251 100644 --- a/ckanext/odsh/templates/package/snippets/package_basic_fields.html +++ b/ckanext/odsh/templates/package/snippets/package_basic_fields.html @@ -82,7 +82,7 @@ dataset_is_draft)) %} {# field subject #} {% set before_selected = data.get('subject') or 'empty' %} -{{ form.select('subject', label=_('subject'), options=h.get_subject_for_selection(), selected=before_selected , error=errors.subject, is_required=True, classes=['control-full']) }} +{{ form.tpsh_select('subject', label=_('subject'), options=h.get_subject_for_selection(), selected=before_selected , error=errors.subject, is_required=True, classes=['control-full']) }} {# field license #} @@ -234,7 +234,7 @@ dataset_is_draft)) %} {# field language #} {% set before_selected = data.get('language') or h.odsh_extract_value_from_extras(data.extras, 'language') or 'http://publications.europa.eu/resource/authority/language/DEU' %} -{{ form.select('language', label=_('language'), options=h.get_language_for_selection(), selected=before_selected , error=errors.language, is_required=False, classes=['control-full']) }} +{{ form.tpsh_select('language', label=_('language'), options=h.get_language_for_selection(), selected=before_selected , error=errors.language, is_required=False, classes=['control-full']) }} {# field spatial_uri #} diff --git a/ckanext/odsh/templates/package/snippets/package_form.html b/ckanext/odsh/templates/package/snippets/package_form.html index aea803a5c2b19298971b253295fa8a2de5e196f5..0763b3b9712ea4ca274d0fe87d9db04b0655ba50 100644 --- a/ckanext/odsh/templates/package/snippets/package_form.html +++ b/ckanext/odsh/templates/package/snippets/package_form.html @@ -25,13 +25,7 @@ <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 controller='package', action='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 %} + {% 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/package/snippets/resource_form.html b/ckanext/odsh/templates/package/snippets/resource_form.html index 963e6046aa75b85d24c365305e6fc43d59b130fc..5176dcb0b81bf217c161622b2ee6cfbba562ccd9 100644 --- a/ckanext/odsh/templates/package/snippets/resource_form.html +++ b/ckanext/odsh/templates/package/snippets/resource_form.html @@ -88,15 +88,7 @@ {% endif %} </div> <div class="form-actions"> - {% block delete_button %} - {% if data.id %} - {% if h.check_access('resource_delete', {'id': data.id}) %} - <a class="btn btn-danger pull-left" href="{% url_for controller='package', action='resource_delete', resource_id=data.id, id=pkg_name %}" - data-module="confirm-action" data-module-content="{{ _('Are you sure you want to delete this resource?') }}">{% - block delete_button_text %}{{ _('Delete') }}{% endblock %}</a> - {% endif %} - {% endif %} - {% endblock %} + {% if stage %} {% block save_button %} <input type='hidden' name='save' value='go-metadata'/> diff --git a/ckanext/odsh/templates/package/snippets/resource_item.html b/ckanext/odsh/templates/package/snippets/resource_item.html index d58b339c686481ba91f7c2ac1edb9b4981de4dd7..74c3657cb07692f37fbfe7c11981566ad08533c4 100644 --- a/ckanext/odsh/templates/package/snippets/resource_item.html +++ b/ckanext/odsh/templates/package/snippets/resource_item.html @@ -16,7 +16,11 @@ </a> {% endif %} {% if resource_size %} - <p>Dateigröße: {{ resource_size }}</p> + <p>Dateigröße: {{ resource_size }}</p> + {% endif %} + {% set number_of_pages = res.get('number_of_pages') %} + {% if number_of_pages%} + <p>Seitenanzahl: {{ number_of_pages }}</p> {% endif %} </div> <div class="resource-icons"> diff --git a/ckanext/odsh/templates/page.html b/ckanext/odsh/templates/page.html index 6e958cacd443657ef4eb249533197cc046b8e413..134079dd6ced8e52b3e01a7eec0fcef0a3db1a22 100644 --- a/ckanext/odsh/templates/page.html +++ b/ckanext/odsh/templates/page.html @@ -1,5 +1,10 @@ {% ckan_extends %} +{% block skip %} + <a class="skip-link" href="#content"> + Zum Inhalt springen. + </a> +{% endblock skip %} {%- block content %} <div class="blur-layer"></div> diff --git a/ckanext/odsh/templates/snippets/facet_list.html b/ckanext/odsh/templates/snippets/facet_list.html index ab0d8af05fdd028f4697ff60895f02d88120ddd2..d2b8521998aa412d9b20b7e92d7443c2bfa84bff 100644 --- a/ckanext/odsh/templates/snippets/facet_list.html +++ b/ckanext/odsh/templates/snippets/facet_list.html @@ -38,8 +38,8 @@ > </span> {% if name=='groups' %} - <span class='group-icon-container'> - <img src="/base/images/icon_kat_{{item.name}}.svg"/> + <span class="group-icon-container" aria-hidden="true"> + <img src="/base/images/icon_kat_{{item.name}}.svg" alt=""/> </span> {% endif %} diff --git a/ckanext/odsh/templates/snippets/organization.html b/ckanext/odsh/templates/snippets/organization.html index 93145b244f63030875e6ba9e085dbb2b2537b8ca..df7bda0041df1b7cc4f988683ee0d9dd98ae4bc7 100644 --- a/ckanext/odsh/templates/snippets/organization.html +++ b/ckanext/odsh/templates/snippets/organization.html @@ -15,7 +15,6 @@ Example: #} {% set truncate = truncate or 0 %} -{% set url = h.url_for(controller='organization', action='read', id=organization.name) %} {% block info %} <div class="module module-narrow module-shallow context-info"> @@ -25,17 +24,61 @@ Example: [{{ _('Deleted') }}] {% endif %} </h1> - {% endblock %} + {% endblock heading%} <section id="section-org" class="module-content"> {% block inner %} {% block image %} <div class="image"> - <a href="{{ url }}"> - <img src="{{ organization.image_display_url or h.url_for_static('/base/images/placeholder-organization.png') }}" - width="200" alt="{{ organization.name }}" /> - </a> + <img src="{{ organization.image_display_url or h.url_for_static('/base/images/placeholder-organization.png') }}" + width="200" alt="{{ organization.name }}" /> </div> - {% endblock %} + + <div class="information-organisation"> + {% set address = h.tpsh_get_address_org(organization) %} + {% set street = address.get('street') %} + {% set location = address.get('location') %} + {% set mail = address.get('mail') %} + {% set telephone = address.get('telephone') %} + {% set web = address.get('web') %} + + {% if person %} + <p> + {{ person }} + </p> + {% endif %} {# person #} + + {% if street and location %} + <p>{{ street }}</p> + <p>{{ location }}</p> + {% endif %} {# street and location #} + + {% if mail %} + {% if package %} + {% set package_name = package.get('name') %} + {% set betreff = "Transparenzportal Dokument: "+ package_name%} + {% set body_mail = h.tpsh_get_body_mail(organization, package) %} + {% else %} + {% set betreff = "Transparenzportal" %} + {% endif %} {# package #} + <p> + <a href="mailto:{{ mail }}?subject={{betreff}}&body={{body_mail}}Viele Grüße">{{ mail }}</a> + </p> + {% endif %} {# mail #} + + {% if telephone %} + <p class="phone"> + {{ telephone }} + </p> + {% endif %} {# telephone #} + + {% if web %} + <p> + <a href="{{address.web}}">{{ address.web }}</a> + </p> + {% endif %} {# web #} + </div> + {% endblock image%} + {% if not hide_description %} {% block description %} {% if organization.description %} @@ -46,7 +89,7 @@ Example: {% else %} <p class="empty">{{ _('There is no description for this organization') }}</p> {% endif %} - {% endblock %} + {% endblock description %} {% endif %} {% if show_nums %} {% block nums %} @@ -60,14 +103,14 @@ Example: <dd>{{ h.SI_number_span(organization.package_count) }}</dd> </dl> </div> - {% endblock %} + {% endblock nums%} {% block follow %} <div class="follow_button"> {{ h.follow_button('group', organization.id) }} </div> - {% endblock %} + {% endblock follow %} {% endif %} - {% endblock %} + {% endblock inner %} </section> </div> {% endblock %} \ No newline at end of file diff --git a/ckanext/odsh/templates/snippets/package_item.html b/ckanext/odsh/templates/snippets/package_item.html index a0800747a092e58fa0f9ede98d643e257ddd064a..419e685bc6eedfcb77f671a559ec19f408fbee75 100644 --- a/ckanext/odsh/templates/snippets/package_item.html +++ b/ckanext/odsh/templates/snippets/package_item.html @@ -35,8 +35,15 @@ Example: <div class="odsh-dataset-item"> <div class="preview-image-container"> {% if thumbnail %} - <img src= "{{ thumbnail }}" alt= "Vorschau" /> - {% endif%} + <a href={{ h.url_for(controller='package', action='read', id=package.name) }}> + <img src= "{{ thumbnail }}" alt= "Vorschau" /> + </a> + + {% else %} + <a href={{ h.url_for(controller='package', action='read', id=package.name) }}> + <img src="/base/images/platzhalter.svg" alt= "keine Vorschau verfügbar" /> + </a> + {% endif%} </div> {% block content %} <div class="dataset-content"> @@ -91,6 +98,7 @@ Example: {% endblock banner%} {% block notes %} + {% if package.groups|length %} <p class='package-info-category'> <span class='category-header'> {% trans category_count=package.groups|length %} @@ -101,8 +109,8 @@ Example: </span> {% for category in package.groups %} <span class='category-with-icon'> - <span class='category-icon-container'> - <img src="/base/images/icon_kat_{{category.name}}.svg" /> + <span class='category-icon-container' aria-hidden='true'> + <img src="/base/images/icon_kat_{{category.name}}.svg" alt=""/> </span> <span class="category-name"> {{ category.display_name }} @@ -110,6 +118,7 @@ Example: </span> {% endfor %} </p> + {% endif %} <p class='package-info-subject'>{{ _('subject') }}: {{ subject_text }} </p> <p class='package-info-issued'>{{ _('issued') }}: {{issued}} </p> {% endblock notes %} diff --git a/ckanext/odsh/templates/snippets/search_form.html b/ckanext/odsh/templates/snippets/search_form.html index 63e349690619a542ca4b14d96b89e1f50b0b8268..9e1ea9ed0bb4d3b4941c5f72d83dcbeca6e9521a 100644 --- a/ckanext/odsh/templates/snippets/search_form.html +++ b/ckanext/odsh/templates/snippets/search_form.html @@ -12,11 +12,11 @@ (_('Name Ascending'), 'title_string asc'), (_('Name Descending'), 'title_string desc'), (_('Issued Ascending'), 'extras_issued asc'), - (_('Issued Descending'), 'extras_issued desc'), - (_('Start Date Descending'), 'temporal_start desc'), + (_('Issued Descending'), 'extras_issued desc'), (_('Start Date Ascending'), 'temporal_start asc'), - (_('End Date Descending'), 'temporal_end desc'), + (_('Start Date Descending'), 'temporal_start desc'), (_('End Date Ascending'), 'temporal_end asc'), + (_('End Date Descending'), 'temporal_end desc'), (_('Popular'), 'views_recent desc') if g.tracking_enabled else (false, false) ] %} {% endif %} diff --git a/ckanext/odsh/templates/user/edit_user_form.html b/ckanext/odsh/templates/user/edit_user_form.html new file mode 100644 index 0000000000000000000000000000000000000000..9ceda7c7afc8e093149537317040f080d943afef --- /dev/null +++ b/ckanext/odsh/templates/user/edit_user_form.html @@ -0,0 +1,59 @@ +{% import 'macros/form.html' as form %} +{% resource 'odsh/tpsh_validate_password.js' %} + + +<form id="user-edit-form" class="dataset-form form-horizontal" method="post" action="{{ action }}"> + {{ form.errors(error_summary) }} + + <fieldset> + <legend>{{ _('Change details') }}</legend> + {{ form.input('name', label=_('Username'), id='field-username', value=data.name, error=errors.name, classes=['control-medium'], is_required=true) }} + + {{ form.input('fullname', label=_('Full name'), id='field-fullname', value=data.fullname, error=errors.fullname, placeholder=_('eg. Joe Bloggs'), classes=['control-medium']) }} + + {{ form.input('email', label=_('Email'), id='field-email', type='email', value=data.email, error=errors.email, placeholder=_('eg. joe@example.com'), classes=['control-medium'], is_required=true) }} + + {{ form.markdown('about', label=_('About'), id='field-about', value=data.about, error=errors.about, placeholder=_('A little information about yourself')) }} + + {% if c.show_email_notifications %} + {% call form.checkbox('activity_streams_email_notifications', label=_('Subscribe to notification emails'), id='field-activity-streams-email-notifications', value=True, checked=c.userobj.activity_streams_email_notifications) %} + {% set helper_text = _("You will receive notification emails from {site_title}, e.g. when you have new activities on your dashboard."|string) %} + {{ form.info(helper_text.format(site_title=g.site_title), classes=['info-help-tight']) }} + {% endcall %} + {% endif %} + + </fieldset> + + <fieldset> + <legend>{{ _('Change password') }}</legend> + {{ form.input('old_password', + type='password', + label=_('Sysadmin Password') if c.is_sysadmin else _('Old Password'), + id='field-password', + value=data.oldpassword, + error=errors.oldpassword, + classes=['control-medium'], + attrs={'autocomplete': 'off'} + ) }} + + {{ form.input( + 'password1', type='password', label=_('Password'), id='field-password', value=data.password1, error=errors.password1, classes=['control-medium'], attrs={'autocomplete': 'off', 'data-module': 'tpsh_validate_password'} ) }} + + {{ form.input('password2', type='password', label=_('Confirm Password'), id='field-password-confirm', value=data.password2, error=errors.password2, classes=['control-medium'], attrs={'autocomplete': 'off'}) }} + </fieldset> + + <div class="form-actions"> + {% block delete_button %} + {% if h.check_access('user_delete', {'id': data.id}) %} + <a class="btn btn-danger pull-left" href="{% url_for controller='user', action='delete', id=data.id %}" data-module="confirm-action" data-module-content="{{ _('Are you sure you want to delete this User?') }}">{% block delete_button_text %}{{ _('Delete') }}{% endblock %}</a> + {% endif %} + {% endblock %} + {% block generate_button %} + {% if h.check_access('user_generate_apikey', {'id': data.id}) %} + <a class="btn btn-warning" href="{% url_for controller='user', action='generate_apikey', id=data.id %}" data-module="confirm-action" data-module-content="{{ _('Are you sure you want to regenerate the API key?') }}">{% block generate_button_text %}{{ _('Regenerate API Key') }}{% endblock %}</a> + {% endif %} + {% endblock %} + {{ form.required_message() }} + <button class="btn btn-primary" type="submit" name="save">{{ _('Update Profile') }}</button> + </div> +</form> \ No newline at end of file diff --git a/ckanext/odsh/tests_tpsh/resources/__init__.py b/ckanext/odsh/tests_tpsh/resources/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ckanext/odsh/tests_tpsh/resources/org_dicts.py b/ckanext/odsh/tests_tpsh/resources/org_dicts.py new file mode 100644 index 0000000000000000000000000000000000000000..5948d7658b0e626459a3cef62392c124f8b3f723 --- /dev/null +++ b/ckanext/odsh/tests_tpsh/resources/org_dicts.py @@ -0,0 +1,87 @@ +# encoding: utf-8 + +organization_with_address = { + 'approval_status': u'approved', + 'created': '2019-07-29T08:11:32.697127', + 'description': u'', + 'display_name': u'Test-Organisation', + 'extras': [ + { + 'group_id': u'63c87e74-60a9-4a4a-a980-d7983c47f92b', + 'id': u'b31c1b27-8c4e-46d7-b533-30bc4cc93d0e', + 'key': u'location', + 'revision_id': u'5e9677a3-ddab-4306-850f-cfd4fad3d676', + 'state': u'active', + 'value': u'Müllerdorf' + }, + { + 'group_id': u'63c87e74-60a9-4a4a-a980-d7983c47f92b', + 'id': u'7302c660-871e-44f0-92f4-18bc5b8953ec', + 'key': u'mail', + 'revision_id': u'5e9677a3-ddab-4306-850f-cfd4fad3d676', + 'state': u'active', + 'value': u'mueller@mueller.de' + }, + { + 'group_id': u'63c87e74-60a9-4a4a-a980-d7983c47f92b', + 'id': u'6d3e02ba-b721-4362-92f3-985ed50f6c42', + 'key': u'person', + 'revision_id': u'5e9677a3-ddab-4306-850f-cfd4fad3d676', + 'state': u'active', + 'value': u'Michael Müller' + }, + { + 'group_id': u'63c87e74-60a9-4a4a-a980-d7983c47f92b', + 'id': u'baf92ac2-21e2-49f5-96f8-e48c7fd50cf0', + 'key': u'street', + 'revision_id': u'5e9677a3-ddab-4306-850f-cfd4fad3d676', + 'state': u'active', + 'value': u'Müllergasse 10' + }, + { + 'group_id': u'63c87e74-60a9-4a4a-a980-d7983c47f92b', + 'id': u'd5ce2972-487e-444b-95ba-c6a8db238c67', + 'key': u'telephone', + 'revision_id': u'5e9677a3-ddab-4306-850f-cfd4fad3d676', + 'state': u'active', + 'value': u'040 123456' + }, + { + 'group_id': u'63c87e74-60a9-4a4a-a980-d7983c47f92b', + 'id': u'00d1d308-6718-4d90-81ae-25ee3f0b76f7', + 'key': u'web', + 'revision_id': u'5e9677a3-ddab-4306-850f-cfd4fad3d676', + 'state': u'active', + 'value': u'mueller.de' + } + ], + 'groups': [], + 'id': u'63c87e74-60a9-4a4a-a980-d7983c47f92b', + 'image_display_url': u'', + 'image_url': u'', + 'is_organization': True, + 'name': u'test-organisation', + 'num_followers': 0L, + 'package_count': 51, + 'revision_id': u'3040af6c-d3f6-462d-b48a-329d63e17a28', + 'state': u'active', + 'tags': [], + 'title': u'Test-Organisation', + 'type': u'organization', + 'users': [{ + 'about': u'', + 'activity_streams_email_notifications': False, + 'capacity': u'admin', + 'created': '2019-06-05T06:19:17.576291', + 'display_name': u'ckanuser', + 'email_hash': 'b28744113bd1ae8dc4f6e17aefe3bd9b', + 'fullname': u'', + 'id': u'ff8d002d-3908-45e5-ba7b-445381860957', + 'name': u'ckanuser', + 'number_created_packages': 13L, + 'number_of_edits': 456L, + 'openid': None, + 'state': u'active', + 'sysadmin': True + }] + } \ No newline at end of file diff --git a/ckanext/odsh/tests_tpsh/resources/subject_mapping_for_tests.json b/ckanext/odsh/tests_tpsh/resources/subject_mapping_for_tests.json new file mode 100644 index 0000000000000000000000000000000000000000..2e8bd946d9237ed177f8d3759defc4732d2f8ddf --- /dev/null +++ b/ckanext/odsh/tests_tpsh/resources/subject_mapping_for_tests.json @@ -0,0 +1,26 @@ +{ + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Verwaltungsvorschrift" : "Verwaltungsvorschrift", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Organisationsplan" : "Organisationsplan", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Geschaeftsverteilungsplan" : "Geschäftsverteilungsplan", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Aktenplan" : "Aktenplan", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Richtlinie" : "Richtlinie und Runderlass", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Statistik" : "amtliche Statistik", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Taetigkeitsbericht" : "Tätigkeitsbericht", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Broschuere" : "Broschüre", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Gutachten" : "Gutachten", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Studie" : "Studie", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Haushaltsplan" : "Haushaltsplan", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Stellenplan" : "Stellenplan", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Wirtschaftsplan" : "Wirtschaftsplan", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#ZuwendungAnPerson" : "Übersicht über Zuwendungen an juristische Personen des Privatrechts", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#ZuwendungAnLand" : "Übersicht über Zuwendungen an das Land Schleswig-Holstein", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#IZGAntwort" : "IZG/GvgV-Auskunft", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Gerichtsurteil" : "Gerichtsurteil", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#GesetzvorlageLandtag" : "Gesetzesvorlage an den Landtag", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#MitteilungLandtag" : "Mitteilung an den Landtag", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Unternehmensdaten" : "wesentliche Unternehmensdaten von Beteiligungen des Landes", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#VergütungsOG" : "jährliche Vergütungen nach dem VergütungsOG", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#Vertrag" : "Vertrag", + "http://transparenz.schleswig-holstein.de/informationsgegenstand#sonstiges" : "sonstiges" +} + \ No newline at end of file diff --git a/ckanext/odsh/tests_tpsh/test_checksum.py b/ckanext/odsh/tests_tpsh/test_checksum.py index e3e4afc81f3877f47b6fe7944ee5466293ae41d5..6bff5d4fe469025e396c8b7e291e0d99106aad36 100644 --- a/ckanext/odsh/tests_tpsh/test_checksum.py +++ b/ckanext/odsh/tests_tpsh/test_checksum.py @@ -1,6 +1,6 @@ from mock import patch, mock_open import nose.tools as nt -from ckanext.odsh.lib.uploader import _raise_validation_error_if_hash_values_differ, _calculate_hash +from ckanext.odsh.lib.uploader import _raise_validation_error_if_hash_values_differ, calculate_hash import ckantoolkit as ct import ckan.logic as logic import hashlib @@ -51,7 +51,7 @@ class testHashException(object): # md5sum test.pdf expected_hash_pdf = '66123edf64fabf1c073fc45478bf4a57' with open(dir_path + '/resources/test.pdf') as f: - hash = _calculate_hash(f) + hash = calculate_hash(f) nt.assert_equal(hash, expected_hash_pdf) diff --git a/ckanext/odsh/tests_tpsh/test_helpers_tpsh.py b/ckanext/odsh/tests_tpsh/test_helpers_tpsh.py index ecba0d5bd430bc29883945c29ba27b83037433ba..78c106081ea654955449b41e79412f5c7563e33a 100644 --- a/ckanext/odsh/tests_tpsh/test_helpers_tpsh.py +++ b/ckanext/odsh/tests_tpsh/test_helpers_tpsh.py @@ -1,9 +1,13 @@ -from collections import namedtuple +# encoding: utf-8 + +import os +from collections import namedtuple, OrderedDict import datetime import nose.tools as nt from mock import patch from ckan.common import config import ckan.logic.action.create as create +from ckanext.odsh.tests_tpsh.resources import org_dicts from ckanext.odsh.helpers_tpsh import ( @@ -11,7 +15,11 @@ from ckanext.odsh.helpers_tpsh import ( map_ckan_type_to_dct_type, add_pkg_to_collection, correct_missing_relationship, - get_language_of_package + get_language_of_package, + get_address_org, + load_json_to_ordered_dict, + load_subject_mapping, + get_subject_for_selection ) @@ -191,4 +199,83 @@ class Test_get_language_of_package(object): def test_it_returns_None_if_language_not_in_pkg_dict(self): test_package = {} nt.assert_equal(get_language_of_package(test_package), None) + + +class Test_get_address_org(object): + def test_it_returns_address_for_org_with_address(self): + organization = org_dicts.organization_with_address + address = get_address_org(organization) + nt.assert_equal(address.get('location'), u'Müllerdorf') + nt.assert_equal(address.get('person'), u'Michael Müller') + nt.assert_equal(address.get('mail'), u'mueller@mueller.de') + nt.assert_equal(address.get('street'), u'Müllergasse 10') + nt.assert_equal(address.get('telephone'), u'040 123456') + nt.assert_equal(address.get('web'), u'http://mueller.de') + + def test_it_returns_empty_dict_if_called_via_organization_new(self): + organization = dict() + address = get_address_org(organization) + assert type(address) is dict + nt.assert_equal(len(address), 0) + + +def _add_subject_mapping_file_to_config(): + path_current_file = os.path.dirname(os.path.abspath(__file__)) + path_to_subject_mapping_file = path_current_file + '/resources/subject_mapping_for_tests.json' + config.update({'ckanext.odsh.subject_mapping': path_to_subject_mapping_file}) + +class Test_load_json_to_ordered_dict(object): + def setUp(self): + json_str = '{"A": 1, "B": 2, "D": 3, "C":4, "E": 0}' + self.result = load_json_to_ordered_dict(json_str) + + def test_it_does_not_crash(self): + pass + + def test_it_returns_ordered_dict(self): + nt.assert_is(type(self.result), OrderedDict) + + def test_it_preserves_order_of_keys(self): + keys = self.result.keys() + nt.assert_equal(keys, [u'A', u'B', u'D', u'C', u'E']) + + def test_it_preserves_order_of_values(self): + values = self.result.values() + nt.assert_equal(values, [1, 2, 3, 4, 0]) + +class Test_load_subject_mapping(object): + def setUp(self): + _add_subject_mapping_file_to_config() + self.SUBJECT_MAPPING = load_subject_mapping() + + def tearDown(self): + config.clear() + + def test_it_returns_an_ordered_dictionary(self): + nt.assert_is(type(self.SUBJECT_MAPPING), OrderedDict) + + def test_it_preserves_order_of_json_file(self): + keys = self.SUBJECT_MAPPING.keys() + nt.assert_equal(keys[0], u'http://transparenz.schleswig-holstein.de/informationsgegenstand#Verwaltungsvorschrift') + nt.assert_equal(keys[1], u'http://transparenz.schleswig-holstein.de/informationsgegenstand#Organisationsplan') + nt.assert_equal(keys[2], u'http://transparenz.schleswig-holstein.de/informationsgegenstand#Geschaeftsverteilungsplan') + nt.assert_equal(keys[3], u'http://transparenz.schleswig-holstein.de/informationsgegenstand#Aktenplan') + +class Test_get_subject_for_selection(object): + def setUp(self): + _add_subject_mapping_file_to_config() + self.result = get_subject_for_selection() + + def tearDown(self): + config.clear() + def test_it_returns_a_list(self): + assert type(self.result) is list + + def test_first_element_is_empty(self): + nt.assert_equal(self.result[0], {'key': 'empty', 'value': ' '}) + + def test_it_contains_more_than_one_element(self): + nt.assert_greater(len(self.result), 1) + + diff --git a/ckanext/odsh/tests_tpsh/test_password_validation.py b/ckanext/odsh/tests_tpsh/test_password_validation.py new file mode 100644 index 0000000000000000000000000000000000000000..c999b3974784df07d2da8c3d40ac1d9e11e8026d --- /dev/null +++ b/ckanext/odsh/tests_tpsh/test_password_validation.py @@ -0,0 +1,35 @@ +# encoding: utf-8 + +import nose.tools as nt +from ckanext.odsh.logic.action import check_password + +class Test_PasswordValidation(object): + + @staticmethod + def assert_password_invalid(password): + assert not check_password(password) + + @staticmethod + def assert_password_valid(password): + assert check_password(password) + + def test_valid_password(self): + self.assert_password_valid('Passwort1 :) :P :D') + + def test_umlaute(self): + self.assert_password_valid('Pässword') + + def test_no_uppercase(self): + self.assert_password_invalid('passwort1') + + def test_no_lowercase(self): + self.assert_password_invalid('PASSWORT1') + + def test_no_letters(self): + self.assert_password_invalid('37459073245!!?===))/=$§äüöÄÜÖ') + + def test_only_letters(self): + self.assert_password_invalid('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz') + + def test_to_short(self): + self.assert_password_invalid('Pw123') \ No newline at end of file diff --git a/ckanext/odsh/tools.py b/ckanext/odsh/tools.py index ca7d69a7cfacb82981da9fed6125de04a6fed67e..ab7c1ba60885d1a4589b1bc533f9d22e4d74d27b 100644 --- a/ckanext/odsh/tools.py +++ b/ckanext/odsh/tools.py @@ -1,17 +1,45 @@ import os -from ckanext.odsh.pdf_to_thumbnail.thumbnail import get_filepath_to_resource, update_last_resource_if_value_empty +from ckanext.odsh.pdf_to_thumbnail.thumbnail import get_filepath_to_resource from ckanext.odsh.lib.uploader import calculate_hash import ckan.plugins.toolkit as toolkit +import magic +import pdftotext -def save_hash_into_resource(context, resource): - path = get_filepath_to_resource(resource) - if os.path.exists(path): - with open(path, 'rb') as file: - hash = calculate_hash(file) - package = update_last_resource_if_value_empty(context, resource, 'hash', hash) - toolkit.get_action('package_update')(context, package) - - - - +def add_attributes_resources(context, resource): + package_id = resource.get('package_id') + package = toolkit.get_action('package_show')(context, {'id': package_id}) + resources = package.get('resources') + i = 0 + for item in resources: + if item.get('id') == resource.get('id'): + path = get_filepath_to_resource(resource) + if os.path.exists(path): + with open(path, 'rb') as file: + + #size + if not item.get('size'): + resource_size = os.path.getsize(path) + item.update({'size': resource_size}) + + #hash + file.seek(0) + hash = calculate_hash(file) + item.update({'hash':hash}) + + #hash algorithm + item.update({'hash_algorithm': 'http://dcat-ap.de/def/hashAlgorithms/md/5'}) + + + #number of pages + file_type = magic.from_file(path, mime = True) + if file_type == 'application/pdf': + file.seek(0) + pdf = pdftotext.PDF(file) + number_of_pages = len(pdf) + item.update({'number_of_pages':number_of_pages}) + resources[i] = item + break + i = i + 1 + package.update({'resources':resources}) + toolkit.get_action('package_update')(context, package) diff --git a/ckanext/odsh/validation.py b/ckanext/odsh/validation.py index a2a7905f79fb5e6dbde74aa06929769ced0f3cf3..7fa35f8bfdfcdc215a6e92bb543acabc52b55121 100644 --- a/ckanext/odsh/validation.py +++ b/ckanext/odsh/validation.py @@ -79,6 +79,8 @@ def validate_extras(key, data, errors, context): errors=extra_errors ) + is_date_start_before_date_end(data, extra_errors) + validate_extra_date_new( key=key, field='issued', @@ -104,6 +106,12 @@ def validate_extras(key, data, errors, context): if len(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') + if start_date and end_date: + 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 diff --git a/requirements.txt b/requirements.txt index 1448613d1d5732db5c204fd4cf340429bcaff465..524de62fd1f8a0134be3fbf616914c1e64692ac9 100755 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ multiline-log-formatter filehash==0.1.dev3 pdf2image==1.9.0 pathlib +pdftotext