44from pygeometa .schemas .iso19139 import ISO19139OutputSchema
55
66from .libs .helpers import get_anytext
7- from .settings import log
7+ from .settings import DMS_DATASETS_BASE , log
88
99app = typer .Typer ()
1010
1313
1414def to_iso19139 (metadata : dict ) -> str :
1515 loaded = orjson .loads (metadata )
16- log .debug (loaded , id = loaded .get ("identification" ).get ("identifier" ))
16+ log .debug (loaded , id = loaded .get ("identification" , {} ).get ("identifier" ))
1717 try :
1818 xml = iso .write (loaded )
1919 return xml
2020 except Exception as e :
21- log .exception (e , id = loaded .get ("identification" ).get ("identifier" ))
21+ log .exception (e , id = loaded .get ("identification" , {} ).get ("identifier" ))
2222 return ""
2323
2424
2525@app .command ()
26- def generate_csw_metadata (
27- base_url : str = "https://s3-int-1/dms-test/dms/tables/" , lang = "en"
28- ):
26+ def generate_csw_metadata (base_url : str = DMS_DATASETS_BASE , lang = "en" ):
2927 # TODO: localize the output based on the language in input
3028
3129 conn = duckdb .connect ()
@@ -87,31 +85,58 @@ def generate_csw_metadata(
8785
8886 log .debug (spatial )
8987
90- identification = resources .select ("""
91- id,
88+ descriptions_structure = datasets .aggregate (
89+ "json_group_structure(metadata->'$.descriptions[*]') as stucture"
90+ ).fetchone ()[0 ]
91+
92+ log .debug ("Generated schema of abstract" , structure = descriptions_structure )
93+
94+ descriptions = (
95+ resources .set_alias ("r" )
96+ .join (datasets .set_alias ("d" ), condition = "r.dataset_id = d.id" )
97+ .select (
98+ f"r.id, unnest(json_transform(d.metadata->'$.descriptions[*]', '{ descriptions_structure } '), recursive := true)" # noqa: E501
99+ )
100+ )
101+ log .debug (descriptions )
102+
103+ abstracts = descriptions .filter (
104+ (
105+ duckdb .ColumnExpression ("descriptionType" )
106+ == duckdb .ConstantExpression ("Abstract" )
107+ )
108+ and (duckdb .ColumnExpression ("lang" ) == duckdb .ConstantExpression (lang )),
109+ ).aggregate ("id, lang, string_agg(description, '\n ') as description" )
110+ log .debug (abstracts )
111+
112+ identification = conn .sql ("""
113+ from resources as r
114+ join datasets as d on r.dataset_id = d.id
115+ left join abstracts as a on a.id = r.id
116+ select
117+ r.id,
92118 {
93- identifier: id,
119+ identifier: r. id,
94120 -- TODO: these needs to be read from the dataset
95- language: metadata->'language',
121+ language: d. metadata->'$. language',
96122 -- TODO: these is probably a combination
97- title: title,
123+ title: r. title,
98124 fee: 'None',
99125 status: 'completed',
100126 -- TODO: these needs to be read from the dataset
101127 rights: '',
102- -- TODO: these needs to be read from the dataset
103- abstract: '',
104- url: uri,
128+ abstract: a.description,
129+ url: r.uri,
105130 dates: {
106- creation: created_at,
107- revision: last_modified_at
131+ creation: r. created_at,
132+ revision: r. last_modified_at
108133 },
109134 extents: {
110- spatial: case when extent is not null then [
135+ spatial: case when r. extent is not null then [
111136 {
112137 bbox: [
113- ST_XMIN(extent), ST_YMIN(extent),
114- ST_XMAX(extent), ST_YMAX(extent),
138+ ST_XMIN(r. extent), ST_YMIN(r. extent),
139+ ST_XMAX(r. extent), ST_YMAX(r. extent),
115140 ],
116141 crs: 4326
117142 }
@@ -126,13 +151,14 @@ def generate_csw_metadata(
126151 },
127152 license: {
128153 -- need to join with dataset to read those!
129- "name": coalesce(metadata->>'$.rightsList[0].rights', 'All rights reserved'),
130- "uri": coalesce(metadata->>'$.rightsList[0].rightsUri', ''),
154+ "name": coalesce('All rights reserved'),
155+ "uri": coalesce(''),
131156 },
132157 keywords: {
133158 "default": {
134- keywords_type: 'theme',
135- keywords: [],
159+ -- need to join with dataset to read those!
160+ keywords_type: 'theme',
161+ keywords: [],
136162 }
137163 },
138164 }::json as identification
@@ -181,6 +207,13 @@ def generate_csw_metadata(
181207 )
182208 )
183209
210+ contributors_csw = contributions .aggregate (
211+ "dataset_id, string_agg(last_name || ', ' || first_name, ';') as contributors" ,
212+ group_expr = "dataset_id" ,
213+ )
214+
215+ log .debug (contributors_csw )
216+
184217 log .debug (contacts )
185218
186219 distribution = resources .select ("""
@@ -203,7 +236,8 @@ def generate_csw_metadata(
203236
204237 res = conn .sql (
205238 """
206- select m.id, {
239+ select r.* rename (metadata as res_metadata),
240+ {
207241 mcf: { version: 1.0 },
208242 metadata: m.metadata,
209243 identification: i.identification,
@@ -212,22 +246,74 @@ def generate_csw_metadata(
212246 distribution: d.distribution,
213247 contact: c.contact
214248 }::json as metadata
215- from metadata as m
249+ from resources as r
250+ join metadata as m on r.id = m.id
216251 join identification as i on m.id = i.id
217252 join content_info as ci on ci.id = m.id
218253 join spatial as sp on sp.id = m.id
219254 join distribution as d on d.id = m.id
220255 join contacts as c on m.dataset_id = c.dataset_id
221-
222256 """
223257 )
224258 log .debug (res )
225259
226- iso_xml = res .select ("id , to_iso19139(metadata) as xml" )
260+ iso_xml = res .select ("* , to_iso19139(metadata) as xml" )
227261
228262 log .debug (iso_xml )
229263
230- log .debug (iso_xml .select ("*, xml_bag(xml) as fts_text" ))
264+ csw = conn .sql ("""
265+ select
266+ r.id as identifier,
267+ 'gmd:MD_Metadata' as typename,
268+ 'http://www.isotc211.org/2005/gmd' as schema,
269+ 'local' as mdsource,
270+ coalesce(
271+ strftime(r.created_at, '%Y-%m-%d'),
272+ ''
273+ ) as insert_date,
274+ r.title,
275+ coalesce(
276+ strftime(r.last_modified_at, '%Y-%m-%d'),
277+ ''
278+ ) as date_modified,
279+ 'dataset' as type,
280+ null::varchar as format,
281+ case
282+ when r.extent is not null then ST_AsText(r.extent)
283+ else st_makeEnvelope(4.99207807783, 58.0788841824, 31.29341841, 80.6571442736)
284+ end as wkt_geometry,
285+ r.xml as metadata,
286+ r.xml,
287+ coalesce(
288+ replace(
289+ list_aggregate(
290+ r.metadata->'$.identification.keywords.default.keywords[*]',
291+ 'string_agg',
292+ ','
293+ ), '"', ''),
294+ ''
295+ ) as keywords,
296+ 'application/xml' as metadata_type,
297+ xml_bag(r.xml) as anytext,
298+ coalesce(r.metadata->>'$.identification.abstract', '') as abstract,
299+ coalesce(
300+ strftime(r.last_modified_at, '%Y-%m-%d'),
301+ '',
302+ ) as date,
303+ 'Norsk institutt for naturforskning' as creator,
304+ 'Norsk institutt for naturforskning' as publisher,
305+ coalesce(c.contributors, '') as contributor,
306+ ([{
307+ name: r.title,
308+ url: r.uri,
309+ description: r.description,
310+ protocol: r.metadata->>'$.distribution.file.type'
311+ }]::json)::varchar as links
312+ from iso_xml as r
313+ left join contributors_csw as c on c.dataset_id = r.dataset_id
314+ """ ) # noqa: E501
315+
316+ log .debug (csw )
231317
232318
233319if __name__ == "__main__" :
0 commit comments