Skip to content

Commit

Permalink
Merge c73609f into 9eec443
Browse files Browse the repository at this point in the history
  • Loading branch information
lrromero committed Mar 27, 2019
2 parents 9eec443 + c73609f commit 79ecd5a
Show file tree
Hide file tree
Showing 7 changed files with 871 additions and 79 deletions.
6 changes: 4 additions & 2 deletions pydatajson/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1063,10 +1063,12 @@ def _extract_datasets_to_harvest(cls, report):
return datasets_to_harvest

def generate_catalogs_indicators(self, catalogs=None,
central_catalog=None):
central_catalog=None,
identifier_search=False):
catalogs = catalogs or self
return indicators.generate_catalogs_indicators(
catalogs, central_catalog, validator=self.validator)
catalogs, central_catalog, identifier_search=identifier_search,
validator=self.validator)

def _count_fields_recursive(self, dataset, fields):
"""Cuenta la información de campos optativos/recomendados/requeridos
Expand Down
227 changes: 157 additions & 70 deletions pydatajson/indicators.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def generate_numeric_indicators(catalog, validator=None):


def generate_catalogs_indicators(catalogs, central_catalog=None,
identifier_search=False,
validator=None):
"""Genera una lista de diccionarios con varios indicadores sobre
los catálogos provistos, tales como la cantidad de datasets válidos,
Expand Down Expand Up @@ -81,8 +82,8 @@ def generate_catalogs_indicators(catalogs, central_catalog=None,
fields_count, result = _generate_indicators(
catalog, validator=validator)
if central_catalog:
result.update(_federation_indicators(catalog,
central_catalog))
result.update(_federation_indicators(
catalog, central_catalog, identifier_search=identifier_search))
if not indicators_list:
# La primera iteracion solo copio el primer resultado
network_indicators = result.copy()
Expand Down Expand Up @@ -155,7 +156,8 @@ def _generate_indicators(catalog, validator=None, only_numeric=False):
return fields_count, result


def _federation_indicators(catalog, central_catalog):
def _federation_indicators(catalog, central_catalog,
identifier_search=False):
"""Cuenta la cantidad de datasets incluídos tanto en la lista
'catalogs' como en el catálogo central, y genera indicadores a partir
de esa información.
Expand Down Expand Up @@ -183,74 +185,10 @@ def _federation_indicators(catalog, central_catalog):
logger.error(msg)
return result

federados = 0 # En ambos catálogos
no_federados = 0
dist_federadas = 0
datasets_federados_eliminados_cant = 0
datasets_federados = []
datasets_no_federados = []
datasets_federados_eliminados = []
generator = FederationIndicatorsGenerator(central_catalog, catalog,
id_based=identifier_search)

# busca c/dataset del catálogo específico a ver si está en el central
for dataset in catalog.get('dataset', []):
found = False
for central_dataset in central_catalog.get('dataset', []):
new_dataset = (dataset.get('title'), dataset.get('landingPage'))
if (datasets_equal(dataset, central_dataset) and
new_dataset not in datasets_federados):
found = True
federados += 1
datasets_federados.append(new_dataset)
dist_federadas += len(dataset.get('distribution', []))
break
if not found:
no_federados += 1
datasets_no_federados.append((dataset.get('title'),
dataset.get('landingPage')))

# busca c/dataset del central cuyo publisher podría pertenecer al
# catálogo específico, a ver si está en el catálogo específico
# si no está, probablemente signifique que fue eliminado
filtered_central = _filter_by_likely_publisher(
central_catalog.get('dataset', []),
catalog.get('dataset', [])
)
for central_dataset in filtered_central:
found = False
for dataset in catalog.get('dataset', []):
if datasets_equal(dataset, central_dataset):
found = True
break
if not found:
datasets_federados_eliminados_cant += 1
datasets_federados_eliminados.append(
(central_dataset.get('title'),
central_dataset.get('landingPage'))
)

if federados or no_federados: # Evita división por 0
federados_pct = float(federados) / (federados + no_federados)
else:
federados_pct = 0

result.update({
'datasets_federados_cant':
federados,
'datasets_no_federados_cant':
no_federados,
'datasets_federados_eliminados_cant':
datasets_federados_eliminados_cant,
'datasets_federados_eliminados':
datasets_federados_eliminados,
'datasets_no_federados':
datasets_no_federados,
'datasets_federados':
datasets_federados,
'datasets_federados_pct':
round(federados_pct, 4),
'distribuciones_federadas_cant':
dist_federadas
})
result.update(generator.federation_indicators())
return result


Expand Down Expand Up @@ -709,3 +647,152 @@ def count_fields(targets, field):
"""Cuenta la cantidad de values en el key
especificado de una lista de diccionarios"""
return Counter([target.get(field) or 'None' for target in targets])


class FederationIndicatorsGenerator(object):
def __init__(self, central_catalog, catalog, id_based=False):
if id_based:
calculator = IdBasedIndicatorCalculator
else:
calculator = TitleBasedIndicatorCalculator

self.calculator = calculator(central_catalog, catalog)

def datasets_federados(self):
return self.calculator.datasets_federados()

def datasets_federados_cant(self):
return len(self.calculator.datasets_federados())

def datasets_no_federados(self):
return self.calculator.datasets_no_federados()

def datasets_no_federados_cant(self):
return len(self.calculator.datasets_no_federados())

def distribuciones_federadas_cant(self):
return self.calculator.distribuciones_federadas_cant()

def datasets_federados_eliminados(self):
return self.calculator.datasets_federados_eliminados()

def datasets_federados_eliminados_cant(self):
return len(self.datasets_federados_eliminados())

def datasets_federados_pct(self):
federados = self.datasets_federados_cant()
no_federados = self.datasets_no_federados_cant()
if federados or no_federados: # Evita división por 0
federados_pct = float(federados) / (federados + no_federados)
else:
federados_pct = 0
return round(federados_pct, 4)

def federation_indicators(self):
return {
'datasets_federados_cant':
self.datasets_federados_cant(),
'datasets_no_federados_cant':
self.datasets_no_federados_cant(),
'datasets_federados_eliminados_cant':
self.datasets_federados_eliminados_cant(),
'datasets_federados_eliminados':
self.datasets_federados_eliminados(),
'datasets_no_federados':
self.datasets_no_federados(),
'datasets_federados':
self.datasets_federados(),
'datasets_federados_pct':
self.datasets_federados_pct(),
'distribuciones_federadas_cant':
self.distribuciones_federadas_cant()
}


class IdBasedIndicatorCalculator(object):
def __init__(self, central_catalog, catalog):
self.central_catalog = readers.read_catalog(central_catalog)
self.catalog = readers.read_catalog(catalog)
self.central_datasets = {ds['identifier'] for ds in
self.central_catalog.get('dataset', [])}
self.catalog_datasets = {catalog['identifier'] + '_' + ds['identifier']
for ds in catalog.get('dataset', [])}
self.federated_ids = self.catalog_datasets & self.central_datasets
self.filtered_central = _filter_by_likely_publisher(
self.central_catalog.get('dataset', []),
self.catalog.get('dataset', []))

def distribuciones_federadas_cant(self):
return sum([len(ds.get('distribution', [])) for ds in
self.central_catalog.get('dataset', []) if
ds['identifier'] in self.federated_ids])

def datasets_federados_eliminados(self):
return [(ds.get('title'), ds.get('landingPage')) for ds in
self.filtered_central if ds['identifier'] not in
self.federated_ids]

def datasets_no_federados(self):
return [(ds.get('title'), ds.get('landingPage')) for
ds in self.catalog.get('dataset', []) if
self.catalog['identifier'] + '_' + ds['identifier']
not in self.federated_ids]

def datasets_federados(self):
return [(ds.get('title'), ds.get('landingPage')) for
ds in self.catalog.get('dataset', []) if
self.catalog['identifier'] + '_' + ds['identifier']
in self.federated_ids]


class TitleBasedIndicatorCalculator(object):

def __init__(self, central_catalog, catalog):
self.central_catalog = readers.read_catalog(central_catalog)
self.catalog = readers.read_catalog(catalog)
self.filtered_central = _filter_by_likely_publisher(
self.central_catalog.get('dataset', []),
self.catalog.get('dataset', []))

def datasets_federados(self):
datasets_federados = []
for dataset in self.catalog.get('dataset', []):
for central_dataset in self.central_catalog.get('dataset', []):
new_dataset = (dataset.get('title'),
dataset.get('landingPage'))
if (datasets_equal(dataset, central_dataset) and
new_dataset not in datasets_federados):
datasets_federados.append(new_dataset)
return datasets_federados

def datasets_no_federados(self):
datasets_federados = self.datasets_federados()
datasets_no_federados = []
for dataset in self.catalog.get('dataset', []):
if not (dataset.get('title'), dataset.get('landingPage')) \
in datasets_federados:
datasets_no_federados.append((dataset.get('title'),
dataset.get('landingPage')))
return datasets_no_federados

def datasets_federados_eliminados(self):
datasets_federados = self.datasets_federados()
datasets_federados_eliminados = []
for central_dataset in self.filtered_central:
if (central_dataset.get('title'),
central_dataset.get('landingPage'))\
not in datasets_federados:
datasets_federados_eliminados.append(
(central_dataset.get('title'),
central_dataset.get('landingPage'))
)
return datasets_federados_eliminados

def distribuciones_federadas_cant(self):
datasets_federados = self.datasets_federados()
distribuciones_federadas = 0
for dataset in self.catalog.get('dataset', []):
if (dataset.get('title'), dataset.get('landingPage')) \
in datasets_federados:
distribuciones_federadas += len(dataset['distribution'])
return distribuciones_federadas

0 comments on commit 79ecd5a

Please sign in to comment.