Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP GobiertoData add dcat catalog endpoint #3846

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
8 changes: 8 additions & 0 deletions app/controllers/gobierto_data/api/v1/datasets_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ class DatasetsController < BaseController
skip_before_action :authenticate_in_site, only: [:new, :create, :update, :destroy]
skip_before_action :set_admin_with_token, except: [:new, :create, :update, :destroy]

# GET /api/v1/data/catalog.xml
def catalog
@catalog = DatasetPresenter.new(current_site).build_catalog
respond_to do |format|
format.xml
end
end

# GET /api/v1/data/datasets
# GET /api/v1/data/datasets.json
# GET /api/v1/data/datasets.csv
Expand Down
3 changes: 3 additions & 0 deletions app/models/gobierto_data/dataset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class Dataset < ApplicationRecord
include GobiertoAttachments::Attachable
include GobiertoCommon::Collectionable
include GobiertoCommon::Searchable
include GobiertoCommon::HasCustomFieldRecords

multisearchable(
against: [:name_translations ,:name_en, :name_es],
Expand All @@ -30,6 +31,8 @@ class Dataset < ApplicationRecord
has_many :visualizations, dependent: :destroy, class_name: "GobiertoData::Visualization"

scope :sorted, -> { order(data_updated_at: :desc) }
scope :sorted_by_creation, -> { order(created_at: :desc) }
scope :visibles, -> { where(visibility_level: "active") }

translates :name

Expand Down
115 changes: 115 additions & 0 deletions app/presenters/gobierto_data/dataset_presenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
module GobiertoData
class DatasetPresenter
include ActionView::Helpers::UrlHelper
include ActionView::Helpers::TranslationHelper

attr_reader :site

def initialize(site)
@site = site
end

def build_catalog
Hash.new.tap do |catalog|
catalog[:languages] = site.configuration.available_locales
catalog[:identifier_uri] = url_helpers.gobierto_data_root_url(host: site.domain)
site.configuration.available_locales.each do |locale|
catalog["title_#{locale}".to_sym] = I18n.t('presenters.gobierto_data.catalog.title',site: site, locale: locale)
catalog["description_#{locale}".to_sym] = I18n.t('presenters.gobierto_data.catalog.description',site: site, publisher_url: url_helpers.gobierto_data_root_url(host: site.domain), locale: locale)
end
catalog[:issued] = site.created_at.iso8601
catalog[:modified] = site.updated_at.iso8601
catalog[:homepage] = url_helpers.gobierto_data_root_url(host: site.domain)
catalog[:publisher] = site.configuration.configuration_variables["gobierto_data_catalog_organism"] || ""
catalog[:spatials] = site.configuration.configuration_variables["gobierto_data_spatials"] || []
catalog[:theme] = site.configuration.configuration_variables["gobierto_data_theme_taxonomy"] || ""
catalog[:datasets] = build_datasets_for_catalog
end
end

private

def build_datasets_for_catalog
site.datasets.visibles.sorted_by_creation.map do |dataset|
build_dataset_for_catalog(dataset)
end
end

def build_dataset_for_catalog(dataset)
Hash.new.tap do |dataset_presenter|
dataset_presenter[:url] = url_helpers.gobierto_data_datasets_url(host: site.domain, id: dataset.slug)
site.configuration.available_locales.each do |locale|
dataset_presenter["title_#{locale}".to_sym] = dataset.name(locale: locale)
dataset_presenter["description_#{locale}".to_sym] = description_from_custom_field_record(dataset)[locale]
end
dataset_presenter[:keywords] = category_from_custom_field_record(dataset)
dataset_presenter[:issued] = dataset.created_at.iso8601
dataset_presenter[:modified] = dataset.updated_at.iso8601
dataset_presenter[:update_frequency] = frecuency_from_custom_field_record(dataset).first
dataset_presenter[:update_frequency_in_days] = frecuency_from_custom_field_record(dataset).last
dataset_presenter[:license_url] = license_url_from_custom_field_record(dataset)
dataset_presenter[:distributions] = build_distribution_for_catalog(dataset)
end
end

def build_distribution_for_catalog(dataset)
[
Hash.new.tap do |distribution|
site.configuration.available_locales.each do |locale|
distribution["title_#{locale}_extended".to_sym] = "#{dataset.name(locale: locale)} #{I18n.t('presenters.gobierto_data.catalog.at_format')} application/csv"
end
distribution[:format] = 'application/csv'
distribution[:download_url] = url_helpers.download_gobierto_data_api_v1_dataset_url(slug: dataset.slug, host: site.domain)
distribution[:csv_size] = dataset.size&.[](:csv)
end
]
end

def url_helpers
Rails.application.routes.url_helpers
end

def site_locale
site.configuration.default_locale
end

def description_from_custom_field_record(dataset)
if dataset.custom_field_record_with_uid("description")
dataset.custom_field_record_with_uid("description").payload["description"]
else
""
end
end

def license_url_from_custom_field_record(dataset)
custom_field_record = dataset.custom_field_record_with_uid('dataset-license')
if !custom_field_record.nil? && !custom_field_record.payload["dataset-license"].blank?
site.terms.find_by(id: custom_field_record.payload["dataset-license"])[:description_translations][site_locale]
else
""
end
end

def category_from_custom_field_record(dataset)
custom_field_record = dataset.custom_field_record_with_uid("category")
if !custom_field_record.nil? && !custom_field_record.payload["category"].blank?
site.terms.find_by(id: custom_field_record.payload["category"])[:name_translations]
else
""
end
end

def frecuency_from_custom_field_record(dataset)
custom_field_record = dataset.custom_field_record_with_uid("frequency")
if !custom_field_record.nil? && !custom_field_record.payload["frequency"].blank?
term = site.terms.find_by(id: custom_field_record.payload["frequency"])
[
term[:name_translations]["en"],
term[:description_translations]["en"]
]
else
["", ""]
end
end
end
end
84 changes: 84 additions & 0 deletions app/views/gobierto_data/api/v1/datasets/catalog.xml.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
xmlns:time="http://www.w3.org/2006/time#"
xmlns:dct="http://purl.org/dc/terms/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dcat="http://www.w3.org/ns/dcat#"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:tema="http://datos.gob.es/kos/sector-publico/sector/"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<dcat:Catalog rdf:about="<%= @catalog[:identifier_uri] %>">
<dct:identifier><%= @catalog[:identifier_uri] %></dct:identifier>
<% @catalog[:languages].each do |locale| -%>
<dct:title xml:lang="<%= locale %>"><%= @catalog["title_#{locale}".to_sym] %></dct:title>
<dct:description xml:lang="<%= locale %>"><%= @catalog["description_#{locale}".to_sym] %></dct:description>
<% end -%>
<dct:publisher rdf:resource="<%= @catalog[:publisher] %>" />
<dct:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime"><%= @catalog[:issued] %></dct:issued>
<dct:modified rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime"><%= @catalog[:modified] %></dct:modified>
<% @catalog[:languages].each do |locale| -%>
<dc:language><%= locale %></dc:language>
<% end -%>
<% @catalog[:spatials].each do |spatial| -%>
<dct:spatial rdf:resource="<%= spatial%>" />
<% end -%>
<dcat:themeTaxonomy rdf:resource="<%= @catalog[:theme] %>" /><!-- search at: http://datos.gob.es/kos/sector-publico/sector/ -->
<foaf:homepage rdf:resource="<%= @catalog[:homepage] %>" />
<% @catalog[:datasets].each do |dataset| -%>
<dcat:dataset>
<dcat:Dataset rdf:about="<%= dataset[:url]%>">
<dct:identifier><%= dataset[:url]%></dct:identifier>
<% @catalog[:languages].each do |locale| -%>
<dct:title xml:lang="<%= locale %>"><%= dataset["title_#{locale}".to_sym] %></dct:title>
<dct:description xml:lang="<%= locale %>"><%= dataset["description_#{locale}".to_sym] %></dct:description>
<dcat:keyword xml:lang="<%= locale %>"><%= dataset[:keywords][locale] %></dcat:keyword>
<% end -%>
<dct:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime"><%= dataset[:issued] %></dct:issued> <!-- Formato YYYY-MM-DDTHH:MM:SS -->
<dct:modified rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime"><%= dataset[:modified] %></dct:modified> <!-- Formato YYYY-MM-DDTHH:MM:SS -->
<% if !dataset[:update_frequency].blank? && !dataset[:update_in_days].blank? -%>
<dct:accrualPeriodicity>
<dct:Frequency>
<rdf:value>
<time:DurationDescription>
<rdfs:label><%= dataset[:update_frequency] %></rdfs:label>
<time:days rdf:datatype="http://www.w3.org/2001/XMLSchema#integer"><%= dataset[:update_frequency_in_days] %></time:days> <!-- puede ser days, weeks, months, years,...-->
</time:DurationDescription>
</rdf:value>
</dct:Frequency>
</dct:accrualPeriodicity>
<% end -%>
<% @catalog[:languages].each do |locale| -%>
<dc:language><%= locale %></dc:language>
<% end -%>
<dct:publisher rdf:resource="<%= @catalog[:publisher] %>" />
<dct:license rdf:resource="<%= dataset[:license_url] %>" />
<% @catalog[:spatials].each do |spatial| -%>
<dct:spatial rdf:resource="<%= spatial%>" />
<% end -%>
<% dataset[:distributions].each do |distribution| -%>
<dcat:distribution>
<dcat:Distribution>
<dct:identifier><%= dataset[:url] %></dct:identifier><!-- La url de la identificacion de la distribucion no puede ser la misma que la de accessURL -->
<% @catalog[:languages].each do |locale| -%>
<dct:title xml:lang="<%= locale %>"><%= dataset["title_#{locale}_extended"] %></dct:title>
<% end -%>
<dcat:accessURL rdf:datatype="http://www.w3.org/2001/XMLSchema#anyURI"><%= distribution[:download_url] %></dcat:accessURL>
<% unless distribution[:csv_size].blank? -%>
<dcat:byteSize rdf:datatype="http://www.w3.org/2001/XMLSchema#decimal"><%= distribution[:csv_size] %></dcat:byteSize>
<% end -%>
<dct:format>
<dct:IMT>
<rdf:value><%= distribution[:format] %></rdf:value>
<rdfs:label>Comma-separated values (CSV)</rdfs:label>
</dct:IMT>
</dct:format>
</dcat:Distribution>
</dcat:distribution>
<% end -%>
</dcat:Dataset>
</dcat:dataset>
<% end -%>
</dcat:Catalog>
</rdf:RDF>
4 changes: 2 additions & 2 deletions config/locales/defaults/ca.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ ca:
- dv
- ds
abbr_month_names:
-
-
- gen
- feb
- mar
Expand Down Expand Up @@ -43,7 +43,7 @@ ca:
short: "%d %b"
shortest: "%d %b %y"
month_names:
-
-
- gener
- febrer
- març
Expand Down
4 changes: 2 additions & 2 deletions config/locales/defaults/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ en:
- Fri
- Sat
abbr_month_names:
-
-
- Jan
- Feb
- Mar
Expand Down Expand Up @@ -43,7 +43,7 @@ en:
short: "%b %d %Y"
shortest: "%d %b %y"
month_names:
-
-
- January
- February
- March
Expand Down
4 changes: 2 additions & 2 deletions config/locales/defaults/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ es:
- vie
- sáb
abbr_month_names:
-
-
- ene
- feb
- mar
Expand Down Expand Up @@ -43,7 +43,7 @@ es:
short: "%d %b %Y"
shortest: "%d %b %y"
month_names:
-
-
- enero
- febrero
- marzo
Expand Down
9 changes: 9 additions & 0 deletions config/locales/gobierto_data/presenters/ca.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
ca:
presenters:
gobierto_data:
catalog:
at_format: en format
description: Catàleg public de dades dels conjunts de dades publicades per%
{site}, a través de la URL %{publisher_url}
title: Catàleg DCAT de conjunts de dades de %{site} en format rdf/xml dcat
9 changes: 9 additions & 0 deletions config/locales/gobierto_data/presenters/en.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
en:
presenters:
gobierto_data:
catalog:
at_format: at format
description: Public catalog with datasets published by %{site}, through URL
%{publisher_url}
title: Catalog for datasets of %{site} into format rdf/xml dcat
10 changes: 10 additions & 0 deletions config/locales/gobierto_data/presenters/es.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
es:
presenters:
gobierto_data:
catalog:
at_format: en formato
description: Catalogo publico de datos los conjuntos de datos publicados por
%{site}, a través de la URL %{publisher_url}
title: Catalogo DCAT para los conjuntos de datos de %{site} en formato rdf/xml
dcat
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,7 @@
resources :favorites, only: [:index]
collection do
get :meta
get :catalog
end
member do
get "meta" => "datasets#dataset_meta"
Expand Down
29 changes: 25 additions & 4 deletions db/seeds/gobierto_seeds/gobierto_data/recipe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ def self.run(site)
if vocabulary.new_record?
vocabulary.name_translations = { ca: "Freqüència de conjunt de dades", en: "Dataset frequency", es: "Frecuencia de conjunto de datos" }
vocabulary.save
vocabulary.terms.create(name_translations: { ca: "Anual", en: "Annual", es: "Anual" }, position: 1)
vocabulary.terms.create(name_translations: { ca: "Trimestral", en: "Quarterly", es: "Trimestral" }, position: 2)
vocabulary.terms.create(name_translations: { ca: "Mensual", en: "Monthly", es: "Mensual" }, position: 3)
vocabulary.terms.create(name_translations: { ca: "Diària", en: "Daily", es: "Diaria" }, position: 4)
vocabulary.terms.create(name_translations: { ca: "Anual", en: "Annual", es: "Anual" }, description_translations: { ca: 365, en: 365, es: 365 }, position: 1)
vocabulary.terms.create(name_translations: { ca: "Trimestral", en: "Quarterly", es: "Trimestral" }, description_translations: { ca: 120, en: 120, es: 120 }, position: 2)
vocabulary.terms.create(name_translations: { ca: "Mensual", en: "Monthly", es: "Mensual" }, description_translations: { ca: 30, en: 30, es: 30 }, position: 3)
vocabulary.terms.create(name_translations: { ca: "Diària", en: "Daily", es: "Diaria" }, description_translations: { ca: 1, en: 1, es: 1 }, position: 4)
end
frequency.name_translations = { ca: "Freqüència", en: "Frequency", es: "Frecuencia" }
frequency.position = 2
Expand Down Expand Up @@ -212,7 +212,28 @@ def self.run(site)
dataset_default_geometry.options = { configuration: {} }
dataset_default_geometry.save
end

unless site.configuration.configuration_variables["gobierto_data_catalog_organism"].present?
extra_conf = {"gobierto_data_catalog_organism" => "https://datos.gob.es/es/recurso/sector-publico/org/Organismo/"}
existing_conf = YAML.load(site.configuration.raw_configuration_variables) || {}
site.configuration.raw_configuration_variables = existing_conf.merge(extra_conf).to_yaml
site.save
end
unless site.configuration.configuration_variables["gobierto_data_spatials"].present?
extra_conf = { "gobierto_data_spatials" => [ "http://datos.gob.es/recurso/sector-publico/territorio/Pais/España", "http://datos.gob.es/recurso/sector-publico/territorio/Autonomia/Madrid", "http://datos.gob.es/recurso/sector-publico/territorio/Provincia/Madrid", "https://datos.gob.es/recurso/sector-publico/territorio/Ciudad/Getafe" ] }
existing_conf = YAML.load(site.configuration.raw_configuration_variables) || {}
site.configuration.raw_configuration_variables = existing_conf.merge(extra_conf).to_yaml
site.save
end
unless site.configuration.configuration_variables["gobierto_data_theme_taxonomy"].present?
extra_conf = { "gobierto_data_theme_taxonomy" => "http://datos.gob.es/kos/sector-publico/sector/sector-publico"}
existing_conf = YAML.load(site.configuration.raw_configuration_variables) || {}
site.configuration.raw_configuration_variables = existing_conf.merge(extra_conf).to_yaml
site.save
end

end

end
end
end
Loading