# Path: pydatajson/helpers.py
# def clean_str(s):
#     replacements = {"á": "a", "é": "e", "í": "i", "ó": "o", "ú": "u",
#                     ":": "", ".": ""}
#     for old, new in iteritems(replacements):
#         s = s.replace(old, new)
#     return s.lower().strip()
# 
# def title_to_name(title, decode=True, max_len=None, use_complete_words=True):
#     """Convierte un título en un nombre normalizado para generar urls."""
#     # decodifica y pasa a minúsculas
#     if decode:
#         title = unidecode(title)
#     title = title.lower()
# 
#     # remueve caracteres no permitidos
#     filtered_title = re.sub(r'[^a-z0-9- ]+', '', title)
# 
#     # remueve stop words y espacios y une palabras sólo con un "-"
#     normalized_title = '-'.join([word for word in filtered_title.split()
#                                  if word not in STOP_WORDS])
# 
#     # recorto el titulo normalizado si excede la longitud máxima
#     if max_len and len(normalized_title) > max_len:
# 
#         # busco la última palabra completa
#         if use_complete_words:
#             last_word_index = normalized_title.rindex("-", 0, max_len)
#             normalized_title = normalized_title[:last_word_index]
# 
#         # corto en el último caracter
#         else:
#             normalized_title = normalized_title[:max_len]
# 
#     return normalized_title
# 
# Path: pydatajson/custom_exceptions.py
# class NonParseableCatalog(ValueError):
#     """No se puede leer un data.json a partir del parámetro pasado"""
#     def __init__(self, catalog, error):
#         msg = "Error parseando el datajson {}: {}".format(catalog, error)
#         super(NonParseableCatalog, self).__init__(msg)


import os.path
import logging
import json
import time
import urllib3
from six.moves.urllib_parse import urljoin
from six import iteritems
from requests.exceptions import RequestException
from ckanapi import RemoteCKAN
from ckanapi.errors import CKANAPIError
from .helpers import clean_str, title_to_name
from .custom_exceptions import NonParseableCatalog
        for package_key, contact_key in iteritems(contact_point_mapping):
            try:
                dataset['contactPoint'][contact_key] = package[package_key]
            except BaseException:
                logger.exception("""
                La clave '%s' no está en el endpoint 'package_show' para el
                package '%s'. No se puede completar
                dataset['contactPoint']['%s'].""",
                                 package_key, package['name'], contact_key)

    # Si existen campos extras en la información del package, busco las claves
    # "Frecuencia de actualización" y "Temática global" para completar los
    # campos "accrualPeriodicity" y "superTheme" del dataset, respectivamente.
    if "extras" in package:
        add_accrualPeriodicity(dataset, package)
        add_superTheme(dataset, package)
        add_temporal(dataset, package)

    dataset["distribution"] = map_resources_to_distributions(resources,
                                                             portal_url)
    dataset["theme"] = [grp['name'] for grp in groups]
    dataset['keyword'] = [tag['name'] for tag in tags]

    return dataset


def add_temporal(dataset, package):
    # "Cobertura temporal" => "temporal"
    temporal = [
        extra["value"] for extra in package["extras"] if

# Path: pydatajson/helpers.py
# def clean_str(s):
#     replacements = {"á": "a", "é": "e", "í": "i", "ó": "o", "ú": "u",
#                     ":": "", ".": ""}
#     for old, new in iteritems(replacements):
#         s = s.replace(old, new)
#     return s.lower().strip()
# 
# def title_to_name(title, decode=True, max_len=None, use_complete_words=True):
#     """Convierte un título en un nombre normalizado para generar urls."""
#     # decodifica y pasa a minúsculas
#     if decode:
#         title = unidecode(title)
#     title = title.lower()
# 
#     # remueve caracteres no permitidos
#     filtered_title = re.sub(r'[^a-z0-9- ]+', '', title)
# 
#     # remueve stop words y espacios y une palabras sólo con un "-"
#     normalized_title = '-'.join([word for word in filtered_title.split()
#                                  if word not in STOP_WORDS])
# 
#     # recorto el titulo normalizado si excede la longitud máxima
#     if max_len and len(normalized_title) > max_len:
# 
#         # busco la última palabra completa
#         if use_complete_words:
#             last_word_index = normalized_title.rindex("-", 0, max_len)
#             normalized_title = normalized_title[:last_word_index]
# 
#         # corto en el último caracter
#         else:
#             normalized_title = normalized_title[:max_len]
# 
#     return normalized_title
# 
# Path: pydatajson/custom_exceptions.py
# class NonParseableCatalog(ValueError):
#     """No se puede leer un data.json a partir del parámetro pasado"""
#     def __init__(self, catalog, error):
#         msg = "Error parseando el datajson {}: {}".format(catalog, error)
#         super(NonParseableCatalog, self).__init__(msg)


# Path: pydatajson/ckan_reader.py
import os.path
import logging
import json
import time
import urllib3
from six.moves.urllib_parse import urljoin
from six import iteritems
from requests.exceptions import RequestException
from ckanapi import RemoteCKAN
from ckanapi.errors import CKANAPIError
from .helpers import clean_str, title_to_name
from .custom_exceptions import NonParseableCatalog

        for package_key, contact_key in iteritems(contact_point_mapping):
            try:
                dataset['contactPoint'][contact_key] = package[package_key]
            except BaseException:
                logger.exception("""
                La clave '%s' no está en el endpoint 'package_show' para el
                package '%s'. No se puede completar
                dataset['contactPoint']['%s'].""",
                                 package_key, package['name'], contact_key)

    # Si existen campos extras en la información del package, busco las claves
    # "Frecuencia de actualización" y "Temática global" para completar los
    # campos "accrualPeriodicity" y "superTheme" del dataset, respectivamente.
    if "extras" in package:
        add_accrualPeriodicity(dataset, package)
        add_superTheme(dataset, package)
        add_temporal(dataset, package)

    dataset["distribution"] = map_resources_to_distributions(resources,
                                                             portal_url)
    dataset["theme"] = [grp['name'] for grp in groups]
    dataset['keyword'] = [tag['name'] for tag in tags]

    return dataset


def add_temporal(dataset, package):
    # "Cobertura temporal" => "temporal"
    temporal = [
        extra["value"] for extra in package["extras"] if

        title_to_name(extra["key"]) == title_to_name("Cobertura temporal")