# encoding: utf-8 import csv import datetime import logging from string import lower import json import re import urllib2 from collections import OrderedDict import subprocess import os from ckan.common import config import ckan.lib.helpers as helpers import ckan.logic.action.create as create import ckan.model as model import ckan.plugins.toolkit as toolkit import ckanext.odsh.helpers as odsh_helpers log = logging.getLogger(__name__) CKAN_TYPES = {'http://dcat-ap.de/def/datasetTypes/collection': 'collection'} def map_dct_type_to_ckan_type(dct_type): ''' matches the field dct:type from a harvested rdf file to the corresponding ckan package type ''' ckan_type = CKAN_TYPES.get(dct_type) return ckan_type def map_ckan_type_to_dct_type(ckan_type): DCT_TYPES = _revert_dict(CKAN_TYPES) dct_type = DCT_TYPES.get(ckan_type) return dct_type def _revert_dict(d): d_inverse = {v: k for k, v in d.iteritems()} return d_inverse def add_pkg_to_collection(id_pkg, id_collection): if id_pkg and id_collection: relationship_dict = { 'subject': id_pkg, 'object': id_collection, 'type': 'child_of', } toolkit.get_action('package_relationship_create')(None, relationship_dict) def use_matomo(): '''Return the value of the use_matomo config setting. To enable using matomo, add this line to the [app:main] section of your CKAN config file:: ckanext.odsh.use_matomo = True Returns ``False`` by default, if the setting is not in the config file. :rtype: bool ''' value = config.get('ckanext.odsh.use_matomo', False) value = toolkit.asbool(value) return value def correct_missing_relationship(pkg_dict, pkg_relationships_from_model): ''' This function corrects missing relationship in show package. Note this fix is only good with one or non relationship. This error is well known but was not fixed. https://github.com/ckan/ckan/issues/3114 The error causes the deletation of relationships, because package_show is used in resource_create to get the package. ''' if pkg_relationships_from_model: relationship_from_model = pkg_relationships_from_model[0] relationship_list_from_dict = pkg_dict.get('relationships_as_subject') type_pkg = pkg_dict.get('type') needs_update = type_pkg == 'dataset' and not relationship_list_from_dict if needs_update: relationship_for_package = { '__extras': { 'object_package_id': relationship_from_model.object_package_id, 'revision_id': relationship_from_model.revision_id, 'subject_package_id': relationship_from_model.subject_package_id, }, 'comment': relationship_from_model.subject_package_id, 'id': relationship_from_model.id, 'type': relationship_from_model.type, } pkg_dict['relationships_as_subject'].append(relationship_for_package) return pkg_dict def get_pkg_relationships_from_model(pkg_dict): pkg_id = pkg_dict.get('id') return model.Package.get(pkg_id).get_relationships() def load_language_mapping(): with open(config.get('ckanext.odsh.language_mapping')) as language_mapping_json: 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 = load_json_to_ordered_dict(subject_mapping_json.read()) return SUBJECT_MAPPING def get_language_of_package(pkg_dict): LANGUAGE_MAPPING = load_language_mapping() language_id = _get_language_id(pkg_dict) if not language_id: return None language = LANGUAGE_MAPPING.get(language_id) return language def get_language_icon(pkg_dict): ICONS = { "http://publications.europa.eu/resource/authority/language/DAN": '/base/images/icon_lang_danish.png', "http://publications.europa.eu/resource/authority/language/ENG": '/base/images/icon_lang_english.png', } language_id = _get_language_id(pkg_dict) if not language_id: return None return ICONS.get(language_id) def _get_language_id(pkg_dict): language_id = odsh_helpers.odsh_extract_value_from_extras(pkg_dict.get('extras'), 'language') language_id = pkg_dict.get('language') if not language_id: language_id = odsh_helpers.odsh_extract_value_from_extras( pkg_dict.get('extras'), 'language' ) if not language_id: return None language_id_cleaned = re.sub('[\[\]\"]', '', language_id) return language_id_cleaned def get_spatial_for_selection(): mapping_path = config.get('ckanext.odsh.spatial.mapping') try: mapping_file = urllib2.urlopen(mapping_path) except urllib2.URLError: log.error('Could not load spatial mapping file') raise cr = csv.reader(mapping_file, delimiter="\t") spatial_mapping = list() for row in cr: key = row[0].decode('UTF-8') value = row[1].decode('UTF-8') spatial_mapping.append({'key':key, 'value':value}) spatial_mapping.append({'key':'', 'value':''}) return spatial_mapping def get_subject_for_selection(): SUBJECT_MAPPING = load_subject_mapping() dict_for_select_box = [{'key': 'empty', 'value':' '}, ] dict_for_select_box.extend( [{'key': key, 'value': SUBJECT_MAPPING[key]} for key in SUBJECT_MAPPING] ) return dict_for_select_box def get_language_for_selection(): LANGUAGE_MAPPING = load_language_mapping() dict_for_select_box = [{'key': key, 'value': LANGUAGE_MAPPING[key]} for key in LANGUAGE_MAPPING] return dict_for_select_box def get_package_dict(name): ''' raises ckan.logic.NotFound if not found ''' package_dict = toolkit.get_action('package_show')(None, {'id': name}) return package_dict def size_of_fmt(num, suffix='B'): for unit in ['',' k',' M',' G',' T',' P',' E',' Z']: if abs(num) < 1000.0: return "%3.1f%s%s" % (num, unit, suffix) num /= 1000.0 return "%.1f%s%s" % (num, 'Y', suffix) 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