Código fuente para pydatajson.backup

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Módulo con funciones auxiliares para hacer backups de catálogos."""

from __future__ import unicode_literals
from __future__ import print_function
from __future__ import with_statement
import os

import pydatajson
from .helpers import ensure_dir_exists
from .download import download_to_file
from pprint import pprint

CATALOGS_DIR = ""


[documentos]def make_catalogs_backup(catalogs, local_catalogs_dir="", include_metadata=True, include_data=True, include_metadata_xlsx=False): """Realiza una copia local de los datos y metadatos de un catálogo. Args: catalogs (list or dict): Lista de catálogos (elementos que pueden ser interpretados por DataJson como catálogos) o diccionario donde las keys se interpretan como los catalog_identifier: { "modernizacion": "http://infra.datos.gob.ar/catalog/modernizacion/data.json" } Cuando es una lista, los ids se toman de catalog_identifer, y se ignoran los catálogos que no tengan catalog_identifier. Cuando se pasa un diccionario, los keys reemplazan a los catalog_identifier (estos no se leeen). catalog_id (str): Si se especifica, se usa este identificador para el backup. Si no se espedifica, se usa catalog["identifier"]. local_catalogs_dir (str): Directorio local en el cual se va a crear la carpeta "catalog/..." con todos los catálogos. include_metadata (bool): Si es verdadero, se generan los archivos data.json y catalog.xlsx. include_data (bool): Si es verdadero, se descargan todas las distribuciones de todos los catálogos. Return: None """ if isinstance(catalogs, list): for catalog in catalogs: try: make_catalog_backup( catalog, local_catalogs_dir=local_catalogs_dir, include_metadata=include_metadata, include_metadata_xlsx=include_metadata_xlsx, include_data=include_data) except Exception as e: print("ERROR en {}".format(catalog)) print(e) elif isinstance(catalogs, dict): for catalog_id, catalog in catalogs.iteritems(): try: make_catalog_backup( catalog, catalog_id, local_catalogs_dir=local_catalogs_dir, include_metadata=include_metadata, include_metadata_xlsx=include_metadata_xlsx, include_data=include_data) except Exception as e: print("ERROR en {} ({})".format(catalog, catalog_id)) print(e)
[documentos]def make_catalog_backup(catalog, catalog_id=None, local_catalogs_dir="", include_metadata=True, include_data=True, include_metadata_xlsx=True): """Realiza una copia local de los datos y metadatos de un catálogo. Args: catalog (dict or str): Representación externa/interna de un catálogo. Una representación _externa_ es un path local o una URL remota a un archivo con la metadata de un catálogo, en formato JSON o XLSX. La representación _interna_ de un catálogo es un diccionario. catalog_id (str): Si se especifica, se usa este identificador para el backup. Si no se espedifica, se usa catalog["identifier"]. local_catalogs_dir (str): Directorio local en el cual se va a crear la carpeta "catalog/..." con todos los catálogos. include_metadata (bool): Si es verdadero, se generan los archivos data.json y catalog.xlsx. include_data (bool): Si es verdadero, se descargan todas las distribuciones de todos los catálogos. Return: None """ catalog = pydatajson.DataJson(catalog) catalog_identifier = catalog_id if catalog_id else catalog["identifier"] if include_metadata: print("Descargando catálogo {}".format(catalog_identifier.ljust(30)), end="\r") # catálogo en json catalog_path = get_catalog_path(catalog_identifier, local_catalogs_dir) ensure_dir_exists(os.path.dirname(catalog_path)) catalog.to_json(catalog_path) if include_metadata_xlsx: # catálogo en xlsx catalog_path = get_catalog_path( catalog_identifier, local_catalogs_dir, fmt="xlsx") ensure_dir_exists(os.path.dirname(catalog_path)) catalog.to_xlsx(catalog_path) if include_data: distributions = catalog.distributions distributions_num = len(distributions) for index, distribution in enumerate(distributions): print("Descargando distribución {} de {} ({})".format( index + 1, distributions_num, catalog_identifier), end="\r") dataset_id = distribution["dataset_identifier"] distribution_id = distribution["identifier"] distribution_download_url = distribution["downloadURL"] # si no se especifica un file name, se toma de la URL distribution_file_name = distribution.get( "fileName", distribution_download_url[ distribution_download_url.rfind("/") + 1:] ) # genera el path local donde descargar el archivo file_path = get_distribution_path( catalog_id, dataset_id, distribution_id, distribution_file_name, local_catalogs_dir) ensure_dir_exists(os.path.dirname(file_path)) # decarga el archivo download_to_file(distribution_download_url, file_path)
[documentos]def get_distribution_dir(catalog_id, dataset_id, distribution_id, catalogs_dir=CATALOGS_DIR): """Genera el path estándar de un catálogo en un filesystem.""" catalog_path = os.path.join(catalogs_dir, "catalog", catalog_id) dataset_path = os.path.join(catalog_path, "dataset", dataset_id) distribution_dir = os.path.join(dataset_path, "distribution", distribution_id) return os.path.abspath(distribution_dir)
[documentos]def get_distribution_path(catalog_id, dataset_id, distribution_id, distribution_file_name, catalogs_dir=CATALOGS_DIR): """Genera el path estándar de un catálogo en un filesystem.""" distribution_dir = get_distribution_dir( catalog_id, dataset_id, distribution_id, catalogs_dir) distribution_file_path = os.path.join( distribution_dir, "download", distribution_file_name) return os.path.abspath(distribution_file_path)
[documentos]def get_catalog_path(catalog_id, catalogs_dir=CATALOGS_DIR, fmt="json"): """Genera el path estándar de un catálogo en un filesystem.""" base_path = os.path.join(catalogs_dir, "catalog", catalog_id) if fmt == "json": return os.path.join(base_path, "data.json") elif fmt == "xlsx": return os.path.join(base_path, "catalog.xlsx") else: raise NotImplementedError("El formato {} no está implementado.".format( fmt))
if __name__ == '__main__': make_catalog_backup(sys.argv[1], sys.argv[2])