From f4a484f4a05f169e1105493835c23dbc0df30075 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Mon, 4 Mar 2024 13:43:40 +0100 Subject: [PATCH 01/18] adds 'alias' field to the dataset schema --- datalad_catalog/catalog/schema/jsonschema_dataset.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/datalad_catalog/catalog/schema/jsonschema_dataset.json b/datalad_catalog/catalog/schema/jsonschema_dataset.json index 9adcca39..963b8c64 100644 --- a/datalad_catalog/catalog/schema/jsonschema_dataset.json +++ b/datalad_catalog/catalog/schema/jsonschema_dataset.json @@ -31,6 +31,11 @@ "title": "Short name", "type": "string" }, + "alias": { + "description": "An alias of the dataset, used for shortened URL access within the catalog", + "title": "Alias", + "type": "string" + }, "description": { "description": "A 1-2 paragraph description of the dataset", "title": "Description", From dbe68ec345caedc244c43ce47135eb640797b0a2 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Mon, 4 Mar 2024 13:44:17 +0100 Subject: [PATCH 02/18] update demo catalog metadata with names and alias fields, and associated metadata_source --- .../dfb/cb2533c8e474498f9451d63d385c0.json | 10 ++++++++++ .../cc9/4e43626749e8e368f1526a44a8fcf.json | 9 +++++++++ .../db7/6b24cdbea351b8052cf00c1a1d898.json | 10 ++++++++++ .../58a/fe240bdb862d1a2bab36fd679efb4.json | 10 ++++++++++ .../e3a/40711c6157b40133f72c8598b00a2.json | 9 +++++++++ .../84f/2098de82902d61066fa8c5aaa0f79.json | 10 ++++++++++ .../ed9/46e96a98769a46c7cb92b89d071a7.json | 9 +++++++++ .../d6c/4a0834f9bbceb0fda32d2abb93f95.json | 9 +++++++++ .../a31/1d8af93457571bdccbdd53ee77cc5.json | 10 ++++++++++ .../d3e/3a9e40f3f36a138a58e79c33a22de.json | 10 ++++++++++ .../0.1.0/cad/486b905182ab9d7cee7d80ea1173d.json | 11 ++++++++++- .../b90/35a1c54a01f9ac941818f3f3a73f6.json | 13 ++++++++++++- .../261/eb908246b1cc2d056ef050fd8b75a.json | 10 ++++++++++ .../ddb/8aa081e7afeb3831fe007a3816dce.json | 9 +++++++++ 14 files changed, 137 insertions(+), 2 deletions(-) diff --git a/datalad_catalog/catalog/metadata/0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307/c74b66cf37c0d4ed8914296c6d7792b2d25696aa/dfb/cb2533c8e474498f9451d63d385c0.json b/datalad_catalog/catalog/metadata/0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307/c74b66cf37c0d4ed8914296c6d7792b2d25696aa/dfb/cb2533c8e474498f9451d63d385c0.json index 68e4d0bf..5e18497f 100644 --- a/datalad_catalog/catalog/metadata/0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307/c74b66cf37c0d4ed8914296c6d7792b2d25696aa/dfb/cb2533c8e474498f9451d63d385c0.json +++ b/datalad_catalog/catalog/metadata/0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307/c74b66cf37c0d4ed8914296c6d7792b2d25696aa/dfb/cb2533c8e474498f9451d63d385c0.json @@ -2,6 +2,8 @@ "dataset_id": "0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307", "dataset_version": "c74b66cf37c0d4ed8914296c6d7792b2d25696aa", "type": "dataset", + "name": "conversion-qa", + "alias": "conversion-qa", "children": [], "url": [ "https://datapub.fz-juelich.de/studyforrest/studyforrest.ria/0f6/6b1ba-e9a9-46fd-b9d9-2e64fe94d307" @@ -30,6 +32,14 @@ "source_time": 1652857127.245356, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] } diff --git a/datalad_catalog/catalog/metadata/1882e2e6-fbbf-4ade-a65f-3a1615235f51/e5d2f8368fc5f6717d8ef131041c6d943298d0c7/cc9/4e43626749e8e368f1526a44a8fcf.json b/datalad_catalog/catalog/metadata/1882e2e6-fbbf-4ade-a65f-3a1615235f51/e5d2f8368fc5f6717d8ef131041c6d943298d0c7/cc9/4e43626749e8e368f1526a44a8fcf.json index b60df80d..4f7be763 100644 --- a/datalad_catalog/catalog/metadata/1882e2e6-fbbf-4ade-a65f-3a1615235f51/e5d2f8368fc5f6717d8ef131041c6d943298d0c7/cc9/4e43626749e8e368f1526a44a8fcf.json +++ b/datalad_catalog/catalog/metadata/1882e2e6-fbbf-4ade-a65f-3a1615235f51/e5d2f8368fc5f6717d8ef131041c6d943298d0c7/cc9/4e43626749e8e368f1526a44a8fcf.json @@ -43,10 +43,19 @@ "source_time": 1652857178.8397892, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] }, "name": "Studyforrest Structural MRI scans", + "alias": "3T_structural_mri", "description": [ { "source": "datacite_gin", diff --git a/datalad_catalog/catalog/metadata/2d05f277-94b0-470b-8e11-4e56691d5b89/78e04a00fedbe3e055f86c2f9127aa48e1133d55/db7/6b24cdbea351b8052cf00c1a1d898.json b/datalad_catalog/catalog/metadata/2d05f277-94b0-470b-8e11-4e56691d5b89/78e04a00fedbe3e055f86c2f9127aa48e1133d55/db7/6b24cdbea351b8052cf00c1a1d898.json index d50eb198..78fc0eae 100644 --- a/datalad_catalog/catalog/metadata/2d05f277-94b0-470b-8e11-4e56691d5b89/78e04a00fedbe3e055f86c2f9127aa48e1133d55/db7/6b24cdbea351b8052cf00c1a1d898.json +++ b/datalad_catalog/catalog/metadata/2d05f277-94b0-470b-8e11-4e56691d5b89/78e04a00fedbe3e055f86c2f9127aa48e1133d55/db7/6b24cdbea351b8052cf00c1a1d898.json @@ -2,6 +2,8 @@ "dataset_id": "2d05f277-94b0-470b-8e11-4e56691d5b89", "dataset_version": "78e04a00fedbe3e055f86c2f9127aa48e1133d55", "type": "dataset", + "name": "retinotopic-maps", + "alias": "retinotopic-maps", "children": [], "url": [ "http://psydata.ovgu.de/studyforrest/retinotopy/.git", @@ -39,6 +41,14 @@ "source_time": 1652857142.5423129, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] } diff --git a/datalad_catalog/catalog/metadata/3304e775-5f5f-435a-b68e-d98c9f5fb72a/aaac44e047d375cd8f791b1b6fe2b739f02c83b2/58a/fe240bdb862d1a2bab36fd679efb4.json b/datalad_catalog/catalog/metadata/3304e775-5f5f-435a-b68e-d98c9f5fb72a/aaac44e047d375cd8f791b1b6fe2b739f02c83b2/58a/fe240bdb862d1a2bab36fd679efb4.json index 60c2edd1..51ba9568 100644 --- a/datalad_catalog/catalog/metadata/3304e775-5f5f-435a-b68e-d98c9f5fb72a/aaac44e047d375cd8f791b1b6fe2b739f02c83b2/58a/fe240bdb862d1a2bab36fd679efb4.json +++ b/datalad_catalog/catalog/metadata/3304e775-5f5f-435a-b68e-d98c9f5fb72a/aaac44e047d375cd8f791b1b6fe2b739f02c83b2/58a/fe240bdb862d1a2bab36fd679efb4.json @@ -2,6 +2,8 @@ "dataset_id": "3304e775-5f5f-435a-b68e-d98c9f5fb72a", "dataset_version": "aaac44e047d375cd8f791b1b6fe2b739f02c83b2", "type": "dataset", + "name": "cortical-surfaces-freesurfer", + "alias": "cortical-surfaces-freesurfer", "children": [], "url": [ "http://psydata.ovgu.de/studyforrest/visualrois/.git", @@ -32,6 +34,14 @@ "source_time": 1652857136.363641, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] } diff --git a/datalad_catalog/catalog/metadata/3a8648b3-7df8-413f-8efb-4d39040ac174/10e23aafa8271f742e9022a3522d9a88d7fe30cf/e3a/40711c6157b40133f72c8598b00a2.json b/datalad_catalog/catalog/metadata/3a8648b3-7df8-413f-8efb-4d39040ac174/10e23aafa8271f742e9022a3522d9a88d7fe30cf/e3a/40711c6157b40133f72c8598b00a2.json index 0f46cbb7..85fee744 100644 --- a/datalad_catalog/catalog/metadata/3a8648b3-7df8-413f-8efb-4d39040ac174/10e23aafa8271f742e9022a3522d9a88d7fe30cf/e3a/40711c6157b40133f72c8598b00a2.json +++ b/datalad_catalog/catalog/metadata/3a8648b3-7df8-413f-8efb-4d39040ac174/10e23aafa8271f742e9022a3522d9a88d7fe30cf/e3a/40711c6157b40133f72c8598b00a2.json @@ -59,10 +59,19 @@ "source_time": 1652857221.792691, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] }, "name": "studyforrest_multires7t", + "alias": "7T_multiresolution_fmri", "license": { "name": "PDDL", "url": "" diff --git a/datalad_catalog/catalog/metadata/45b9ab26-07fc-11e8-8c71-f0d5bf7b5561/29dcce2b9477537b433996ebc342c531139e1d87/84f/2098de82902d61066fa8c5aaa0f79.json b/datalad_catalog/catalog/metadata/45b9ab26-07fc-11e8-8c71-f0d5bf7b5561/29dcce2b9477537b433996ebc342c531139e1d87/84f/2098de82902d61066fa8c5aaa0f79.json index 007a8e58..0c2849ac 100644 --- a/datalad_catalog/catalog/metadata/45b9ab26-07fc-11e8-8c71-f0d5bf7b5561/29dcce2b9477537b433996ebc342c531139e1d87/84f/2098de82902d61066fa8c5aaa0f79.json +++ b/datalad_catalog/catalog/metadata/45b9ab26-07fc-11e8-8c71-f0d5bf7b5561/29dcce2b9477537b433996ebc342c531139e1d87/84f/2098de82902d61066fa8c5aaa0f79.json @@ -2,6 +2,8 @@ "dataset_id": "45b9ab26-07fc-11e8-8c71-f0d5bf7b5561", "dataset_version": "29dcce2b9477537b433996ebc342c531139e1d87", "type": "dataset", + "name": "curated-annotations", + "alias": "curated-annotations", "children": [], "url": [ "https://datapub.fz-juelich.de/studyforrest/studyforrest.ria/45b/9ab26-07fc-11e8-8c71-f0d5bf7b5561" @@ -34,6 +36,14 @@ "source_time": 1652857269.6786208, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] } diff --git a/datalad_catalog/catalog/metadata/5b1081d6-84d7-11e8-b00a-a0369fb55db0/b623351b43eb2715331ac59ad4cf41682e84ff7d/ed9/46e96a98769a46c7cb92b89d071a7.json b/datalad_catalog/catalog/metadata/5b1081d6-84d7-11e8-b00a-a0369fb55db0/b623351b43eb2715331ac59ad4cf41682e84ff7d/ed9/46e96a98769a46c7cb92b89d071a7.json index bdc96558..a6bfcdc3 100644 --- a/datalad_catalog/catalog/metadata/5b1081d6-84d7-11e8-b00a-a0369fb55db0/b623351b43eb2715331ac59ad4cf41682e84ff7d/ed9/46e96a98769a46c7cb92b89d071a7.json +++ b/datalad_catalog/catalog/metadata/5b1081d6-84d7-11e8-b00a-a0369fb55db0/b623351b43eb2715331ac59ad4cf41682e84ff7d/ed9/46e96a98769a46c7cb92b89d071a7.json @@ -51,10 +51,19 @@ "source_time": 1652857174.37293, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] }, "name": "studyforrest_multires3t", + "alias": "studyforrest_multires3t", "license": { "name": "PDDL (http://opendatacommons.org/licenses/pddl/)", "url": "" diff --git a/datalad_catalog/catalog/metadata/5eaff716-54eb-11e8-803d-a0369f7c647e/72f835ada046bd0479009ea0ff933b30a95b0076/d6c/4a0834f9bbceb0fda32d2abb93f95.json b/datalad_catalog/catalog/metadata/5eaff716-54eb-11e8-803d-a0369f7c647e/72f835ada046bd0479009ea0ff933b30a95b0076/d6c/4a0834f9bbceb0fda32d2abb93f95.json index b00ae934..b97f49dd 100644 --- a/datalad_catalog/catalog/metadata/5eaff716-54eb-11e8-803d-a0369f7c647e/72f835ada046bd0479009ea0ff933b30a95b0076/d6c/4a0834f9bbceb0fda32d2abb93f95.json +++ b/datalad_catalog/catalog/metadata/5eaff716-54eb-11e8-803d-a0369f7c647e/72f835ada046bd0479009ea0ff933b30a95b0076/d6c/4a0834f9bbceb0fda32d2abb93f95.json @@ -63,10 +63,19 @@ "source_time": 1652857264.862466, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] }, "name": "studyforrest_phase2", + "alias": "studyforrest_phase2", "license": { "name": "PDDL", "url": "" diff --git a/datalad_catalog/catalog/metadata/7fcd8812-d0fe-11e7-8db2-a0369f7c647e/2ccaa115543c21e6658950d1cb8cc3038f14272f/a31/1d8af93457571bdccbdd53ee77cc5.json b/datalad_catalog/catalog/metadata/7fcd8812-d0fe-11e7-8db2-a0369f7c647e/2ccaa115543c21e6658950d1cb8cc3038f14272f/a31/1d8af93457571bdccbdd53ee77cc5.json index 73a2031d..e2cf0d7d 100644 --- a/datalad_catalog/catalog/metadata/7fcd8812-d0fe-11e7-8db2-a0369f7c647e/2ccaa115543c21e6658950d1cb8cc3038f14272f/a31/1d8af93457571bdccbdd53ee77cc5.json +++ b/datalad_catalog/catalog/metadata/7fcd8812-d0fe-11e7-8db2-a0369f7c647e/2ccaa115543c21e6658950d1cb8cc3038f14272f/a31/1d8af93457571bdccbdd53ee77cc5.json @@ -2,6 +2,8 @@ "dataset_id": "7fcd8812-d0fe-11e7-8db2-a0369f7c647e", "dataset_version": "2ccaa115543c21e6658950d1cb8cc3038f14272f", "type": "dataset", + "name": "aggregate", + "alias": "aggregate", "children": [], "url": [ "http://psydata.ovgu.de/studyforrest/aggregate/.git", @@ -31,6 +33,14 @@ "source_time": 1652857130.159643, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] } diff --git a/datalad_catalog/catalog/metadata/92e65958-4a5a-4c34-a4f4-ee070f7a123b/203aa983534fc2b823ff4777a85f4f80d7a68656/d3e/3a9e40f3f36a138a58e79c33a22de.json b/datalad_catalog/catalog/metadata/92e65958-4a5a-4c34-a4f4-ee070f7a123b/203aa983534fc2b823ff4777a85f4f80d7a68656/d3e/3a9e40f3f36a138a58e79c33a22de.json index 9d175eca..7f18950a 100644 --- a/datalad_catalog/catalog/metadata/92e65958-4a5a-4c34-a4f4-ee070f7a123b/203aa983534fc2b823ff4777a85f4f80d7a68656/d3e/3a9e40f3f36a138a58e79c33a22de.json +++ b/datalad_catalog/catalog/metadata/92e65958-4a5a-4c34-a4f4-ee070f7a123b/203aa983534fc2b823ff4777a85f4f80d7a68656/d3e/3a9e40f3f36a138a58e79c33a22de.json @@ -2,6 +2,8 @@ "dataset_id": "92e65958-4a5a-4c34-a4f4-ee070f7a123b", "dataset_version": "203aa983534fc2b823ff4777a85f4f80d7a68656", "type": "dataset", + "name": "visual-areas", + "alias": "visual-areas", "children": [], "url": [ "http://psydata.ovgu.de/studyforrest/visualrois/.git", @@ -32,6 +34,14 @@ "source_time": 1652857147.619349, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] } diff --git a/datalad_catalog/catalog/metadata/c475969b-2919-57b1-a3e6-71770acaa222/0.1.0/cad/486b905182ab9d7cee7d80ea1173d.json b/datalad_catalog/catalog/metadata/c475969b-2919-57b1-a3e6-71770acaa222/0.1.0/cad/486b905182ab9d7cee7d80ea1173d.json index 9b033e7d..5cc05272 100644 --- a/datalad_catalog/catalog/metadata/c475969b-2919-57b1-a3e6-71770acaa222/0.1.0/cad/486b905182ab9d7cee7d80ea1173d.json +++ b/datalad_catalog/catalog/metadata/c475969b-2919-57b1-a3e6-71770acaa222/0.1.0/cad/486b905182ab9d7cee7d80ea1173d.json @@ -46,10 +46,19 @@ "source_time": 1702323824.737152, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] }, - "name": null, + "name": "Palmer Penguins", + "alias": "palmerpenguins", "license": { "name": "https://creativecommons.org/publicdomain/zero/1.0/", "url": "https://creativecommons.org/publicdomain/zero/1.0/" diff --git a/datalad_catalog/catalog/metadata/c8ec2919-493b-4af5-9271-cbe9ebd08c43/74cd7ec0538448b05fb4d5f91119b279c5e9ab04/b90/35a1c54a01f9ac941818f3f3a73f6.json b/datalad_catalog/catalog/metadata/c8ec2919-493b-4af5-9271-cbe9ebd08c43/74cd7ec0538448b05fb4d5f91119b279c5e9ab04/b90/35a1c54a01f9ac941818f3f3a73f6.json index 2ee6326c..43897daf 100644 --- a/datalad_catalog/catalog/metadata/c8ec2919-493b-4af5-9271-cbe9ebd08c43/74cd7ec0538448b05fb4d5f91119b279c5e9ab04/b90/35a1c54a01f9ac941818f3f3a73f6.json +++ b/datalad_catalog/catalog/metadata/c8ec2919-493b-4af5-9271-cbe9ebd08c43/74cd7ec0538448b05fb4d5f91119b279c5e9ab04/b90/35a1c54a01f9ac941818f3f3a73f6.json @@ -2,6 +2,8 @@ "dataset_id": "c8ec2919-493b-4af5-9271-cbe9ebd08c43", "dataset_version": "74cd7ec0538448b05fb4d5f91119b279c5e9ab04", "type": "dataset", + "name": "Aligned MRI", + "alias": "aligned_mri", "children": [], "url": [ "http://psydata.ovgu.de/studyforrest/aligned/.git", @@ -31,7 +33,16 @@ "source_time": 1652857133.28578, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] } -} \ No newline at end of file +} + diff --git a/datalad_catalog/catalog/metadata/ceb007ac-ef05-4392-98d2-35c02a774a21/688d8d8558fe847f4c1b19aed579745bcd6c7744/261/eb908246b1cc2d056ef050fd8b75a.json b/datalad_catalog/catalog/metadata/ceb007ac-ef05-4392-98d2-35c02a774a21/688d8d8558fe847f4c1b19aed579745bcd6c7744/261/eb908246b1cc2d056ef050fd8b75a.json index b893b059..390730ce 100644 --- a/datalad_catalog/catalog/metadata/ceb007ac-ef05-4392-98d2-35c02a774a21/688d8d8558fe847f4c1b19aed579745bcd6c7744/261/eb908246b1cc2d056ef050fd8b75a.json +++ b/datalad_catalog/catalog/metadata/ceb007ac-ef05-4392-98d2-35c02a774a21/688d8d8558fe847f4c1b19aed579745bcd6c7744/261/eb908246b1cc2d056ef050fd8b75a.json @@ -2,6 +2,8 @@ "dataset_id": "ceb007ac-ef05-4392-98d2-35c02a774a21", "dataset_version": "688d8d8558fe847f4c1b19aed579745bcd6c7744", "type": "dataset", + "name": "template-transforms", + "alias": "template-transforms", "children": [], "url": [ "http://psydata.ovgu.de/studyforrest/templatetransforms/.git", @@ -35,6 +37,14 @@ "source_time": 1652857139.4177752, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] } diff --git a/datalad_catalog/catalog/metadata/deabeb9b-7a37-4062-a1e0-8fcef7909609/6d7fb68264f9b9951ae141fc830712a8744e3293/ddb/8aa081e7afeb3831fe007a3816dce.json b/datalad_catalog/catalog/metadata/deabeb9b-7a37-4062-a1e0-8fcef7909609/6d7fb68264f9b9951ae141fc830712a8744e3293/ddb/8aa081e7afeb3831fe007a3816dce.json index 4cfb4d09..73db3034 100644 --- a/datalad_catalog/catalog/metadata/deabeb9b-7a37-4062-a1e0-8fcef7909609/6d7fb68264f9b9951ae141fc830712a8744e3293/ddb/8aa081e7afeb3831fe007a3816dce.json +++ b/datalad_catalog/catalog/metadata/deabeb9b-7a37-4062-a1e0-8fcef7909609/6d7fb68264f9b9951ae141fc830712a8744e3293/ddb/8aa081e7afeb3831fe007a3816dce.json @@ -246,10 +246,19 @@ "source_time": 1652857119.960284, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" + }, + { + "source_name": "manual_entry", + "source_version": "1", + "source_parameter": {}, + "source_time": 1709548638972.9111, + "agent_name": "Stephan Heunis", + "agent_email": "s.heunis@fz-juelich.de" } ] }, "name": "StudyForrest", + "alias": "studyforrest", "description": [ { "source": "metalad_studyminimeta", From 78cf3375acd1508ecdb283e8ccdde3bd261709d5 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Mon, 4 Mar 2024 14:18:17 +0100 Subject: [PATCH 03/18] Adds functionality to summarize info about dataset ids and versions in a catalog This includes changes to the following core modules: - webcatalog: new methods are added for extracting all IDs in a catalog, and all VERSIONs for respective IDs, including properties like name, alias, and more. This allows users to iterate through a list comprising all catalog datasets (which is necessary for the upcoming 'tree' command) and allows the 'report' functionality which summarizes some stats of a catalog. - node: adds a method for sorting metadata_sources by time, as a proxy for determining a 'last_updated' value for a dataset version, which forms part of the output of the new webcatalog methods. - get: adds the property 'report', allowing a summary report of the catalog to be printed out. - utils: changes supporting above methods. - tests: minor changes to allow test success, new tests are TODO. These commits all contribute to the upcoming changes related to navigating to a dataset-version via concept ID or via alias. --- datalad_catalog/get.py | 62 +++++++++++++---- datalad_catalog/node.py | 34 +++++---- datalad_catalog/tests/test_get.py | 18 ----- datalad_catalog/tests/test_schema_utils.py | 1 + datalad_catalog/utils.py | 10 +++ datalad_catalog/webcatalog.py | 81 ++++++++++++++++++++++ 6 files changed, 159 insertions(+), 47 deletions(-) diff --git a/datalad_catalog/get.py b/datalad_catalog/get.py index 7aec3409..188df51a 100644 --- a/datalad_catalog/get.py +++ b/datalad_catalog/get.py @@ -139,7 +139,7 @@ def __init__(self): super().__init__( param_constraints=dict( catalog=CatalogRequired() & EnsureWebCatalog(), - property=EnsureChoice("home", "config", "metadata", "tree"), + property=EnsureChoice("home", "config", "metadata", "report"), dataset_id=EnsureStr(), dataset_version=EnsureStr(), record_type=EnsureChoice("dataset", "directory", "file"), @@ -158,10 +158,11 @@ def __init__(self): # All extension commands must be derived from Interface class Get(ValidatedInterface): """Utility for getting various properties of a catalog, based on the specified - property ('home', 'config', 'metadata', 'tree') + property ('home', 'config', 'metadata', 'report') Used to get the catalog home page, get config at catalog- or dataset-level, - or get the metadata for a specific dataset/version. + get the metadata for a specific dataset/version, or get a summary report of + the catalog. """ _validator_ = GetParameterValidator() @@ -176,7 +177,7 @@ class Get(ValidatedInterface): property=Parameter( args=("property",), doc="""The property to get in the catalog. - Should be one of 'home', 'config', 'metadata' or 'tree'.""", + Should be one of 'home', 'config', 'metadata' or 'report'.""", ), dataset_id=Parameter( args=("-i", "--dataset_id"), @@ -241,6 +242,14 @@ class Get(ValidatedInterface): "metadata" ), ), + dict( + text=( + "Get a report of the number of datasets, dataset-versions, and " + "metadata files contained in existing catalog" + ), + code_py=("catalog_get(property='report', catalog='/tmp/my-cat')"), + code_cmd=("datalad catalog-get -c /tmp/my-cat report"), + ), ] @staticmethod @@ -248,14 +257,34 @@ def custom_result_renderer(res, **kwargs): """This result renderer dumps the value of the 'output' key in the result record in JSON-line format -- only if status==ok""" ui = ui_switcher.ui - ui.message( - json.dumps( - res.get("output"), - separators=(",", ":"), - indent=None, - cls=jsEncoder, + if res.get("action_property") == "report": + ui.message( + f"Catalog location: {res.get('output').get('catalog_location')}" + ) + ui.message( + f"Homepage dataset: ID={res.get('output').get('homepage_id')}, VERSION={res.get('output').get('homepage_version')}" + ) + ui.message( + f"Homepage metadata file: {res.get('output').get('homepage_path')}" + ) + ui.message( + f"Number of datasets: {res.get('output').get('dataset_count')}" + ) + ui.message( + f"Number of dataset-versions: {res.get('output').get('version_count')}" + ) + ui.message( + f"Number of metadata files: {res.get('output').get('metadata_file_count')}" + ) + else: + ui.message( + json.dumps( + res.get("output"), + separators=(",", ":"), + indent=None, + cls=jsEncoder, + ) ) - ) @staticmethod # generic handling of command results (logging, rendering, filtering, ...) @@ -279,9 +308,7 @@ def __call__( # TODO: add property schema, schema:store, schema:version, schema:catalog, schema:dataset, etc # Yield error for get-operations that haven't been implemented yet - if property in ("tree"): - msg = f"catalog-get for property={property} is not yet implemented" - yield get_status_dict(**res_kwargs, status="error", message=msg) + # none # Get catalog home page if property == "home": try: @@ -371,3 +398,10 @@ def __call__( exception=e, output=None, ) + # Get catalog-level summary + if property == "report": + report = catalog.get_catalog_report() + msg = f"Catalog report retrieved" + yield get_status_dict( + **res_kwargs, status="ok", message=msg, output=report + ) diff --git a/datalad_catalog/node.py b/datalad_catalog/node.py index 48adc683..00f6fb33 100644 --- a/datalad_catalog/node.py +++ b/datalad_catalog/node.py @@ -6,6 +6,7 @@ load_config_file, md5hash, merge_lists, + split_string, ) lgr = logging.getLogger("datalad.catalog.node") @@ -169,7 +170,9 @@ def get_location(self): self.long_name = self.get_long_name() self.md5_hash = md5hash(self.long_name) - hash_path_left, hash_path_right = self.split_dir_name(self.md5_hash) + hash_path_left, hash_path_right = split_string( + self.md5_hash, self._split_dir_length + ) node_fn = ( self.parent_catalog.metadata_path / self.dataset_id @@ -215,20 +218,6 @@ def get_config(self, config_file: str = None): # only load from catalog-level config file return dict(source="catalog", config=self.parent_catalog.config) - def split_dir_name(self, dir_name): - """ - Split a string into two parts - - Args: - dir_name ([type]): [description] - - Returns: - [type]: [description] - """ - path_left = dir_name[: self._split_dir_length] - path_right = dir_name[self._split_dir_length :] - return path_left, path_right - def add_attributes( self, new_attributes: dict, config_file: str = None, overwrite=False ): @@ -474,3 +463,18 @@ def get_source_map_entry(self, key: str): return None # Return none if no key, else key return self.metadata_sources[cnst.KEY_SOURCE_MAP].get(key, None) + + def get_last_updated(self): + """Proxy to a dedicated 'last_updated' field (which does not + exist in the catalog's dataset schema) by looking at the time + of the last metadata source that was added to the node record + """ + + if hasattr(self, "metadata_sources"): + sorted_sources = sorted( + self.metadata_sources[cnst.SOURCES], + key=lambda d: d.get("source_time"), + reverse=True, + ) + return sorted_sources[0].get("source_time") + return None diff --git a/datalad_catalog/tests/test_get.py b/datalad_catalog/tests/test_get.py index 595dcb79..132ccd73 100644 --- a/datalad_catalog/tests/test_get.py +++ b/datalad_catalog/tests/test_get.py @@ -64,24 +64,6 @@ def test_arg_combinations(demo_catalog): ) -def test_get_tree(demo_catalog): - """Tests for property: tree""" - # placeholder test until the tree functionality is implemented - res = catalog_get( - catalog=demo_catalog, - property="tree", - on_failure="ignore", - return_type="list", - ) - assert_in_results( - res, - action="catalog_get", - action_property="tree", - status="error", - path=demo_catalog.location, - ) - - def test_get_home(demo_catalog, test_data): """Tests for property: home""" # test no home spec diff --git a/datalad_catalog/tests/test_schema_utils.py b/datalad_catalog/tests/test_schema_utils.py index 7b88fd44..4a9b5d1b 100644 --- a/datalad_catalog/tests/test_schema_utils.py +++ b/datalad_catalog/tests/test_schema_utils.py @@ -9,6 +9,7 @@ "dataset_id": "", "dataset_version": "", "name": "", + "alias": "", "short_name": "", "description": "", "doi": "", diff --git a/datalad_catalog/utils.py b/datalad_catalog/utils.py index 0e052f0e..2cf36094 100644 --- a/datalad_catalog/utils.py +++ b/datalad_catalog/utils.py @@ -47,6 +47,16 @@ def md5hash(txt): return txt_hash +def split_string(input_string, split_length): + """ + Split a string into two parts using a specified + length for the first part + """ + path_left = input_string[:split_length] + path_right = input_string[split_length:] + return path_left, path_right + + def load_config_file(file: Path): """Helper to load content from JSON or YAML file""" with open(file) as f: diff --git a/datalad_catalog/webcatalog.py b/datalad_catalog/webcatalog.py index 2f6d779e..8f72d23e 100644 --- a/datalad_catalog/webcatalog.py +++ b/datalad_catalog/webcatalog.py @@ -14,7 +14,10 @@ copy_overwrite_path, dir_exists, load_config_file, + md5hash, + md5sum_from_id_version_path, read_json_file, + split_string, ) lgr = logging.getLogger("datalad.catalog.webcatalog") @@ -316,3 +319,81 @@ def do_GET(self): msg="Unable to serve at the desired host and port", exc_info=e ) raise (e) + + def get_dataset_versions(self): + """Function to get all dataset-versions from a catalog, + including several data points from each specific dataset-version + metadata file. This means that each dataset-level metadata file + in the catalog is read, which might take some time. + """ + dataset_versions = [] + + for dv in self.metadata_path.glob("*/*"): + """""" + if not dv.is_dir(): + continue + ds_id_path = dv.parent.relative_to(self.metadata_path) + ds_id = str(ds_id_path) + ds_version_path = dv.relative_to(self.metadata_path) + ds_version = dv.name + n = Node( + catalog=self, + type="dataset", + dataset_id=ds_id, + dataset_version=ds_version, + node_path=None, + ) + name = alias_path = alias = None + if hasattr(n, "name"): + name = n.name + if hasattr(n, "alias"): + alias = n.alias + alias_path = str( + (Path(alias) / md5hash(alias)).with_suffix(".json") + ) + dataset_versions.append( + { + "dataset_name": name, + "dataset_id": ds_id, + "dataset_version": ds_version, + "concept_path": str( + (ds_id_path / md5hash(ds_id)).with_suffix(".json") + ), + "metadata_path": str( + n.get_location().relative_to(self.metadata_path) + ), + "alias": alias, + "alias_path": alias_path, + "updated_at": n.get_last_updated(), + } + ) + return dataset_versions + + def get_catalog_report(self): + """Summarize output from self.get_dataset_versions and + some more additional stats + """ + files = list(self.metadata_path.rglob("*.json")) + ds_versions = self.get_dataset_versions() + ds_ids = list(set([dsv["dataset_id"] for dsv in ds_versions])) + homepage = self.get_main_dataset() + homepage_node = Node( + catalog=self, + type="dataset", + dataset_id=homepage.get("dataset_id"), + dataset_version=homepage.get("dataset_version"), + node_path=None, + ) + return { + "catalog_location": str(self.location.resolve()), + "homepage_id": homepage.get("dataset_id"), + "homepage_version": homepage.get("dataset_version"), + "homepage_path": str( + homepage_node.get_location().relative_to(self.location) + ), + "dataset_count": len(ds_ids), + "version_count": len(ds_versions), + "metadata_file_count": len(files), + "datasets": ds_ids, + "versions": ds_versions, + } From 13355d09ad93c5fcfdc284c19c99b3d9982c52f3 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Mon, 4 Mar 2024 14:19:53 +0100 Subject: [PATCH 04/18] add a script to create concept id and alias metadata files for all datasets in a catalog --- tools/create_alias_concept_metadata.py | 65 ++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 tools/create_alias_concept_metadata.py diff --git a/tools/create_alias_concept_metadata.py b/tools/create_alias_concept_metadata.py new file mode 100644 index 00000000..cdb4b6a6 --- /dev/null +++ b/tools/create_alias_concept_metadata.py @@ -0,0 +1,65 @@ +""" +With this script you can do the following for an existing catalog: +- create aliases for datasets from a tsv file (TODO) +- create alias and concept id metadata files for all datasets +""" +from argparse import ArgumentParser +import json +from datalad_catalog.constraints import EnsureWebCatalog +from datalad_catalog.utils import md5hash + +if __name__ == "__main__": + parser = ArgumentParser() + parser.add_argument( + "--catalog", + type=str, + help="Path to the catalog", + ) + parser.add_argument( + "--aliases", + type=str, + help="Path to tsv file with dataset ids and aliases", + ) + args = parser.parse_args() + # Ensure is a catalog + catalog = EnsureWebCatalog()(args.catalog) + # Get report + report = catalog.get_catalog_report() + + # Write metadata for all datasets + # assumes that datasets have aliases set + for d in report.get("datasets", []): + # Get latest version + current_ds_versions = [ + dsv for dsv in report.get("versions") if dsv["dataset_id"] == d + ] + sorted_versions = sorted( + current_ds_versions, + key=lambda d: d.get("updated_at"), + reverse=True, + ) + + # Dict for metadata + redirect_dict = { + "type": "redirect", + "dataset_id": d, + "dataset_version": sorted_versions[0]["dataset_version"], + } + + # Create id concept metadata + dataset_concept_path = ( + catalog.metadata_path / d / md5hash(d) + ).with_suffix(".json") + dataset_concept_path.parent.mkdir(parents=True, exist_ok=True) + with open(dataset_concept_path, "w") as f: + json.dump(redirect_dict, f) + + # Create alias metadata + dataset_alias_path = ( + catalog.metadata_path + / sorted_versions[0]["alias"] + / md5hash(sorted_versions[0]["alias"]) + ).with_suffix(".json") + dataset_alias_path.parent.mkdir(parents=True, exist_ok=True) + with open(dataset_alias_path, "w") as f: + json.dump(redirect_dict, f) From afc24742163ea461f4f93fe71d2d5db28a97b202 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Mon, 4 Mar 2024 16:15:33 +0100 Subject: [PATCH 05/18] adds redirect files for dataset ID concept and dataset alias as a result of running the script added in 13355d09ad93c5fcfdc284c19c99b3d9982c52f3 --- .../b454b57ee6b61594659ef53a2d0e1d8b.json | 1 + .../8d16d5c5c6d981312c9247ecdfbfa2fc.json | 1 + .../fbbb9ff6740c1924621a49c2a9939130.json | 1 + .../833cd0923c5f6e4ab0d27cc46c21e4a1.json | 1 + .../3T_structural_mri/37460a809f98d57c82043004953a0f8b.json | 1 + .../6d432172d19c0c59883e75b33d435901.json | 1 + .../695cf504599be40464b16c52f4ed6f02.json | 1 + .../de4d5a97f87d6fd5a4e306fd1a3c7461.json | 1 + .../8ca4989589416fc688cf2aef780f55bc.json | 1 + .../9528cf4440e65b7f1a5023843a4beefa.json | 1 + .../abae378ab377b7029525877afb1e41ea.json | 1 + .../b91516ac08f564a1ba4266ebf4a751db.json | 1 + .../metadata/aggregate/39adbeb6bc21a3133e5fdcf1ec05d1a0.json | 1 + .../metadata/aligned_mri/3bc310d582987a884c2c845e4faef1ec.json | 1 + .../2d762d47310e4b398e723584e37bd0bc.json | 1 + .../b23197118340b9403a16e17af8861a42.json | 1 + .../5cdbcb6740de9c334c52f69aea7f957f.json | 1 + .../metadata/conversion-qa/54733551de044407ac7f4e3bc91290d4.json | 1 + .../b38b7c3aaa7aedd007533a5babd08ffa.json | 1 + .../curated-annotations/dbeb41c7b03da69f096365ba5f63232d.json | 1 + .../cc1657d02382ca0a1ca3100843902942.json | 1 + .../palmerpenguins/66d083a5f519d1fdea831534d187ef5b.json | 1 + .../retinotopic-maps/29b0ad994a02deeca923988ad80acf10.json | 1 + .../metadata/studyforrest/c3f4ea5fee4b9504ec4718a605d49cd4.json | 1 + .../e7d094ff09f0602affe30f46cdf19c37.json | 1 + .../studyforrest_phase2/b2405fe766badfea81133768231974d2.json | 1 + .../template-transforms/4b421880d1f6f1155f8a3c9f3fd2d236.json | 1 + .../metadata/visual-areas/4068e6ba9400dd1b95ff8cb302cd3344.json | 1 + 28 files changed, 28 insertions(+) create mode 100644 datalad_catalog/catalog/metadata/0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307/b454b57ee6b61594659ef53a2d0e1d8b.json create mode 100644 datalad_catalog/catalog/metadata/1882e2e6-fbbf-4ade-a65f-3a1615235f51/8d16d5c5c6d981312c9247ecdfbfa2fc.json create mode 100644 datalad_catalog/catalog/metadata/2d05f277-94b0-470b-8e11-4e56691d5b89/fbbb9ff6740c1924621a49c2a9939130.json create mode 100644 datalad_catalog/catalog/metadata/3304e775-5f5f-435a-b68e-d98c9f5fb72a/833cd0923c5f6e4ab0d27cc46c21e4a1.json create mode 100644 datalad_catalog/catalog/metadata/3T_structural_mri/37460a809f98d57c82043004953a0f8b.json create mode 100644 datalad_catalog/catalog/metadata/3a8648b3-7df8-413f-8efb-4d39040ac174/6d432172d19c0c59883e75b33d435901.json create mode 100644 datalad_catalog/catalog/metadata/45b9ab26-07fc-11e8-8c71-f0d5bf7b5561/695cf504599be40464b16c52f4ed6f02.json create mode 100644 datalad_catalog/catalog/metadata/5b1081d6-84d7-11e8-b00a-a0369fb55db0/de4d5a97f87d6fd5a4e306fd1a3c7461.json create mode 100644 datalad_catalog/catalog/metadata/5eaff716-54eb-11e8-803d-a0369f7c647e/8ca4989589416fc688cf2aef780f55bc.json create mode 100644 datalad_catalog/catalog/metadata/7T_multiresolution_fmri/9528cf4440e65b7f1a5023843a4beefa.json create mode 100644 datalad_catalog/catalog/metadata/7fcd8812-d0fe-11e7-8db2-a0369f7c647e/abae378ab377b7029525877afb1e41ea.json create mode 100644 datalad_catalog/catalog/metadata/92e65958-4a5a-4c34-a4f4-ee070f7a123b/b91516ac08f564a1ba4266ebf4a751db.json create mode 100644 datalad_catalog/catalog/metadata/aggregate/39adbeb6bc21a3133e5fdcf1ec05d1a0.json create mode 100644 datalad_catalog/catalog/metadata/aligned_mri/3bc310d582987a884c2c845e4faef1ec.json create mode 100644 datalad_catalog/catalog/metadata/c475969b-2919-57b1-a3e6-71770acaa222/2d762d47310e4b398e723584e37bd0bc.json create mode 100644 datalad_catalog/catalog/metadata/c8ec2919-493b-4af5-9271-cbe9ebd08c43/b23197118340b9403a16e17af8861a42.json create mode 100644 datalad_catalog/catalog/metadata/ceb007ac-ef05-4392-98d2-35c02a774a21/5cdbcb6740de9c334c52f69aea7f957f.json create mode 100644 datalad_catalog/catalog/metadata/conversion-qa/54733551de044407ac7f4e3bc91290d4.json create mode 100644 datalad_catalog/catalog/metadata/cortical-surfaces-freesurfer/b38b7c3aaa7aedd007533a5babd08ffa.json create mode 100644 datalad_catalog/catalog/metadata/curated-annotations/dbeb41c7b03da69f096365ba5f63232d.json create mode 100644 datalad_catalog/catalog/metadata/deabeb9b-7a37-4062-a1e0-8fcef7909609/cc1657d02382ca0a1ca3100843902942.json create mode 100644 datalad_catalog/catalog/metadata/palmerpenguins/66d083a5f519d1fdea831534d187ef5b.json create mode 100644 datalad_catalog/catalog/metadata/retinotopic-maps/29b0ad994a02deeca923988ad80acf10.json create mode 100644 datalad_catalog/catalog/metadata/studyforrest/c3f4ea5fee4b9504ec4718a605d49cd4.json create mode 100644 datalad_catalog/catalog/metadata/studyforrest_multires3t/e7d094ff09f0602affe30f46cdf19c37.json create mode 100644 datalad_catalog/catalog/metadata/studyforrest_phase2/b2405fe766badfea81133768231974d2.json create mode 100644 datalad_catalog/catalog/metadata/template-transforms/4b421880d1f6f1155f8a3c9f3fd2d236.json create mode 100644 datalad_catalog/catalog/metadata/visual-areas/4068e6ba9400dd1b95ff8cb302cd3344.json diff --git a/datalad_catalog/catalog/metadata/0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307/b454b57ee6b61594659ef53a2d0e1d8b.json b/datalad_catalog/catalog/metadata/0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307/b454b57ee6b61594659ef53a2d0e1d8b.json new file mode 100644 index 00000000..3eca9b3e --- /dev/null +++ b/datalad_catalog/catalog/metadata/0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307/b454b57ee6b61594659ef53a2d0e1d8b.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307", "dataset_version": "c74b66cf37c0d4ed8914296c6d7792b2d25696aa"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/1882e2e6-fbbf-4ade-a65f-3a1615235f51/8d16d5c5c6d981312c9247ecdfbfa2fc.json b/datalad_catalog/catalog/metadata/1882e2e6-fbbf-4ade-a65f-3a1615235f51/8d16d5c5c6d981312c9247ecdfbfa2fc.json new file mode 100644 index 00000000..c08bbecc --- /dev/null +++ b/datalad_catalog/catalog/metadata/1882e2e6-fbbf-4ade-a65f-3a1615235f51/8d16d5c5c6d981312c9247ecdfbfa2fc.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "1882e2e6-fbbf-4ade-a65f-3a1615235f51", "dataset_version": "e5d2f8368fc5f6717d8ef131041c6d943298d0c7"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/2d05f277-94b0-470b-8e11-4e56691d5b89/fbbb9ff6740c1924621a49c2a9939130.json b/datalad_catalog/catalog/metadata/2d05f277-94b0-470b-8e11-4e56691d5b89/fbbb9ff6740c1924621a49c2a9939130.json new file mode 100644 index 00000000..90295adf --- /dev/null +++ b/datalad_catalog/catalog/metadata/2d05f277-94b0-470b-8e11-4e56691d5b89/fbbb9ff6740c1924621a49c2a9939130.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "2d05f277-94b0-470b-8e11-4e56691d5b89", "dataset_version": "78e04a00fedbe3e055f86c2f9127aa48e1133d55"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/3304e775-5f5f-435a-b68e-d98c9f5fb72a/833cd0923c5f6e4ab0d27cc46c21e4a1.json b/datalad_catalog/catalog/metadata/3304e775-5f5f-435a-b68e-d98c9f5fb72a/833cd0923c5f6e4ab0d27cc46c21e4a1.json new file mode 100644 index 00000000..5c011cbe --- /dev/null +++ b/datalad_catalog/catalog/metadata/3304e775-5f5f-435a-b68e-d98c9f5fb72a/833cd0923c5f6e4ab0d27cc46c21e4a1.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "3304e775-5f5f-435a-b68e-d98c9f5fb72a", "dataset_version": "aaac44e047d375cd8f791b1b6fe2b739f02c83b2"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/3T_structural_mri/37460a809f98d57c82043004953a0f8b.json b/datalad_catalog/catalog/metadata/3T_structural_mri/37460a809f98d57c82043004953a0f8b.json new file mode 100644 index 00000000..c08bbecc --- /dev/null +++ b/datalad_catalog/catalog/metadata/3T_structural_mri/37460a809f98d57c82043004953a0f8b.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "1882e2e6-fbbf-4ade-a65f-3a1615235f51", "dataset_version": "e5d2f8368fc5f6717d8ef131041c6d943298d0c7"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/3a8648b3-7df8-413f-8efb-4d39040ac174/6d432172d19c0c59883e75b33d435901.json b/datalad_catalog/catalog/metadata/3a8648b3-7df8-413f-8efb-4d39040ac174/6d432172d19c0c59883e75b33d435901.json new file mode 100644 index 00000000..e00121e4 --- /dev/null +++ b/datalad_catalog/catalog/metadata/3a8648b3-7df8-413f-8efb-4d39040ac174/6d432172d19c0c59883e75b33d435901.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "3a8648b3-7df8-413f-8efb-4d39040ac174", "dataset_version": "10e23aafa8271f742e9022a3522d9a88d7fe30cf"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/45b9ab26-07fc-11e8-8c71-f0d5bf7b5561/695cf504599be40464b16c52f4ed6f02.json b/datalad_catalog/catalog/metadata/45b9ab26-07fc-11e8-8c71-f0d5bf7b5561/695cf504599be40464b16c52f4ed6f02.json new file mode 100644 index 00000000..61352271 --- /dev/null +++ b/datalad_catalog/catalog/metadata/45b9ab26-07fc-11e8-8c71-f0d5bf7b5561/695cf504599be40464b16c52f4ed6f02.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "45b9ab26-07fc-11e8-8c71-f0d5bf7b5561", "dataset_version": "29dcce2b9477537b433996ebc342c531139e1d87"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/5b1081d6-84d7-11e8-b00a-a0369fb55db0/de4d5a97f87d6fd5a4e306fd1a3c7461.json b/datalad_catalog/catalog/metadata/5b1081d6-84d7-11e8-b00a-a0369fb55db0/de4d5a97f87d6fd5a4e306fd1a3c7461.json new file mode 100644 index 00000000..ecfa3517 --- /dev/null +++ b/datalad_catalog/catalog/metadata/5b1081d6-84d7-11e8-b00a-a0369fb55db0/de4d5a97f87d6fd5a4e306fd1a3c7461.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "5b1081d6-84d7-11e8-b00a-a0369fb55db0", "dataset_version": "b623351b43eb2715331ac59ad4cf41682e84ff7d"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/5eaff716-54eb-11e8-803d-a0369f7c647e/8ca4989589416fc688cf2aef780f55bc.json b/datalad_catalog/catalog/metadata/5eaff716-54eb-11e8-803d-a0369f7c647e/8ca4989589416fc688cf2aef780f55bc.json new file mode 100644 index 00000000..ef6a6435 --- /dev/null +++ b/datalad_catalog/catalog/metadata/5eaff716-54eb-11e8-803d-a0369f7c647e/8ca4989589416fc688cf2aef780f55bc.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "5eaff716-54eb-11e8-803d-a0369f7c647e", "dataset_version": "72f835ada046bd0479009ea0ff933b30a95b0076"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/7T_multiresolution_fmri/9528cf4440e65b7f1a5023843a4beefa.json b/datalad_catalog/catalog/metadata/7T_multiresolution_fmri/9528cf4440e65b7f1a5023843a4beefa.json new file mode 100644 index 00000000..e00121e4 --- /dev/null +++ b/datalad_catalog/catalog/metadata/7T_multiresolution_fmri/9528cf4440e65b7f1a5023843a4beefa.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "3a8648b3-7df8-413f-8efb-4d39040ac174", "dataset_version": "10e23aafa8271f742e9022a3522d9a88d7fe30cf"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/7fcd8812-d0fe-11e7-8db2-a0369f7c647e/abae378ab377b7029525877afb1e41ea.json b/datalad_catalog/catalog/metadata/7fcd8812-d0fe-11e7-8db2-a0369f7c647e/abae378ab377b7029525877afb1e41ea.json new file mode 100644 index 00000000..6d728636 --- /dev/null +++ b/datalad_catalog/catalog/metadata/7fcd8812-d0fe-11e7-8db2-a0369f7c647e/abae378ab377b7029525877afb1e41ea.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "7fcd8812-d0fe-11e7-8db2-a0369f7c647e", "dataset_version": "2ccaa115543c21e6658950d1cb8cc3038f14272f"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/92e65958-4a5a-4c34-a4f4-ee070f7a123b/b91516ac08f564a1ba4266ebf4a751db.json b/datalad_catalog/catalog/metadata/92e65958-4a5a-4c34-a4f4-ee070f7a123b/b91516ac08f564a1ba4266ebf4a751db.json new file mode 100644 index 00000000..83f4a7a9 --- /dev/null +++ b/datalad_catalog/catalog/metadata/92e65958-4a5a-4c34-a4f4-ee070f7a123b/b91516ac08f564a1ba4266ebf4a751db.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "92e65958-4a5a-4c34-a4f4-ee070f7a123b", "dataset_version": "203aa983534fc2b823ff4777a85f4f80d7a68656"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/aggregate/39adbeb6bc21a3133e5fdcf1ec05d1a0.json b/datalad_catalog/catalog/metadata/aggregate/39adbeb6bc21a3133e5fdcf1ec05d1a0.json new file mode 100644 index 00000000..6d728636 --- /dev/null +++ b/datalad_catalog/catalog/metadata/aggregate/39adbeb6bc21a3133e5fdcf1ec05d1a0.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "7fcd8812-d0fe-11e7-8db2-a0369f7c647e", "dataset_version": "2ccaa115543c21e6658950d1cb8cc3038f14272f"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/aligned_mri/3bc310d582987a884c2c845e4faef1ec.json b/datalad_catalog/catalog/metadata/aligned_mri/3bc310d582987a884c2c845e4faef1ec.json new file mode 100644 index 00000000..67b490dc --- /dev/null +++ b/datalad_catalog/catalog/metadata/aligned_mri/3bc310d582987a884c2c845e4faef1ec.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "c8ec2919-493b-4af5-9271-cbe9ebd08c43", "dataset_version": "74cd7ec0538448b05fb4d5f91119b279c5e9ab04"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/c475969b-2919-57b1-a3e6-71770acaa222/2d762d47310e4b398e723584e37bd0bc.json b/datalad_catalog/catalog/metadata/c475969b-2919-57b1-a3e6-71770acaa222/2d762d47310e4b398e723584e37bd0bc.json new file mode 100644 index 00000000..1d8c6edd --- /dev/null +++ b/datalad_catalog/catalog/metadata/c475969b-2919-57b1-a3e6-71770acaa222/2d762d47310e4b398e723584e37bd0bc.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "c475969b-2919-57b1-a3e6-71770acaa222", "dataset_version": "0.1.0"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/c8ec2919-493b-4af5-9271-cbe9ebd08c43/b23197118340b9403a16e17af8861a42.json b/datalad_catalog/catalog/metadata/c8ec2919-493b-4af5-9271-cbe9ebd08c43/b23197118340b9403a16e17af8861a42.json new file mode 100644 index 00000000..67b490dc --- /dev/null +++ b/datalad_catalog/catalog/metadata/c8ec2919-493b-4af5-9271-cbe9ebd08c43/b23197118340b9403a16e17af8861a42.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "c8ec2919-493b-4af5-9271-cbe9ebd08c43", "dataset_version": "74cd7ec0538448b05fb4d5f91119b279c5e9ab04"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/ceb007ac-ef05-4392-98d2-35c02a774a21/5cdbcb6740de9c334c52f69aea7f957f.json b/datalad_catalog/catalog/metadata/ceb007ac-ef05-4392-98d2-35c02a774a21/5cdbcb6740de9c334c52f69aea7f957f.json new file mode 100644 index 00000000..12050dac --- /dev/null +++ b/datalad_catalog/catalog/metadata/ceb007ac-ef05-4392-98d2-35c02a774a21/5cdbcb6740de9c334c52f69aea7f957f.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "ceb007ac-ef05-4392-98d2-35c02a774a21", "dataset_version": "688d8d8558fe847f4c1b19aed579745bcd6c7744"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/conversion-qa/54733551de044407ac7f4e3bc91290d4.json b/datalad_catalog/catalog/metadata/conversion-qa/54733551de044407ac7f4e3bc91290d4.json new file mode 100644 index 00000000..3eca9b3e --- /dev/null +++ b/datalad_catalog/catalog/metadata/conversion-qa/54733551de044407ac7f4e3bc91290d4.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307", "dataset_version": "c74b66cf37c0d4ed8914296c6d7792b2d25696aa"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/cortical-surfaces-freesurfer/b38b7c3aaa7aedd007533a5babd08ffa.json b/datalad_catalog/catalog/metadata/cortical-surfaces-freesurfer/b38b7c3aaa7aedd007533a5babd08ffa.json new file mode 100644 index 00000000..5c011cbe --- /dev/null +++ b/datalad_catalog/catalog/metadata/cortical-surfaces-freesurfer/b38b7c3aaa7aedd007533a5babd08ffa.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "3304e775-5f5f-435a-b68e-d98c9f5fb72a", "dataset_version": "aaac44e047d375cd8f791b1b6fe2b739f02c83b2"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/curated-annotations/dbeb41c7b03da69f096365ba5f63232d.json b/datalad_catalog/catalog/metadata/curated-annotations/dbeb41c7b03da69f096365ba5f63232d.json new file mode 100644 index 00000000..61352271 --- /dev/null +++ b/datalad_catalog/catalog/metadata/curated-annotations/dbeb41c7b03da69f096365ba5f63232d.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "45b9ab26-07fc-11e8-8c71-f0d5bf7b5561", "dataset_version": "29dcce2b9477537b433996ebc342c531139e1d87"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/deabeb9b-7a37-4062-a1e0-8fcef7909609/cc1657d02382ca0a1ca3100843902942.json b/datalad_catalog/catalog/metadata/deabeb9b-7a37-4062-a1e0-8fcef7909609/cc1657d02382ca0a1ca3100843902942.json new file mode 100644 index 00000000..f77bb39c --- /dev/null +++ b/datalad_catalog/catalog/metadata/deabeb9b-7a37-4062-a1e0-8fcef7909609/cc1657d02382ca0a1ca3100843902942.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "deabeb9b-7a37-4062-a1e0-8fcef7909609", "dataset_version": "6d7fb68264f9b9951ae141fc830712a8744e3293"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/palmerpenguins/66d083a5f519d1fdea831534d187ef5b.json b/datalad_catalog/catalog/metadata/palmerpenguins/66d083a5f519d1fdea831534d187ef5b.json new file mode 100644 index 00000000..1d8c6edd --- /dev/null +++ b/datalad_catalog/catalog/metadata/palmerpenguins/66d083a5f519d1fdea831534d187ef5b.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "c475969b-2919-57b1-a3e6-71770acaa222", "dataset_version": "0.1.0"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/retinotopic-maps/29b0ad994a02deeca923988ad80acf10.json b/datalad_catalog/catalog/metadata/retinotopic-maps/29b0ad994a02deeca923988ad80acf10.json new file mode 100644 index 00000000..90295adf --- /dev/null +++ b/datalad_catalog/catalog/metadata/retinotopic-maps/29b0ad994a02deeca923988ad80acf10.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "2d05f277-94b0-470b-8e11-4e56691d5b89", "dataset_version": "78e04a00fedbe3e055f86c2f9127aa48e1133d55"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/studyforrest/c3f4ea5fee4b9504ec4718a605d49cd4.json b/datalad_catalog/catalog/metadata/studyforrest/c3f4ea5fee4b9504ec4718a605d49cd4.json new file mode 100644 index 00000000..f77bb39c --- /dev/null +++ b/datalad_catalog/catalog/metadata/studyforrest/c3f4ea5fee4b9504ec4718a605d49cd4.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "deabeb9b-7a37-4062-a1e0-8fcef7909609", "dataset_version": "6d7fb68264f9b9951ae141fc830712a8744e3293"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/studyforrest_multires3t/e7d094ff09f0602affe30f46cdf19c37.json b/datalad_catalog/catalog/metadata/studyforrest_multires3t/e7d094ff09f0602affe30f46cdf19c37.json new file mode 100644 index 00000000..ecfa3517 --- /dev/null +++ b/datalad_catalog/catalog/metadata/studyforrest_multires3t/e7d094ff09f0602affe30f46cdf19c37.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "5b1081d6-84d7-11e8-b00a-a0369fb55db0", "dataset_version": "b623351b43eb2715331ac59ad4cf41682e84ff7d"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/studyforrest_phase2/b2405fe766badfea81133768231974d2.json b/datalad_catalog/catalog/metadata/studyforrest_phase2/b2405fe766badfea81133768231974d2.json new file mode 100644 index 00000000..ef6a6435 --- /dev/null +++ b/datalad_catalog/catalog/metadata/studyforrest_phase2/b2405fe766badfea81133768231974d2.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "5eaff716-54eb-11e8-803d-a0369f7c647e", "dataset_version": "72f835ada046bd0479009ea0ff933b30a95b0076"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/template-transforms/4b421880d1f6f1155f8a3c9f3fd2d236.json b/datalad_catalog/catalog/metadata/template-transforms/4b421880d1f6f1155f8a3c9f3fd2d236.json new file mode 100644 index 00000000..12050dac --- /dev/null +++ b/datalad_catalog/catalog/metadata/template-transforms/4b421880d1f6f1155f8a3c9f3fd2d236.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "ceb007ac-ef05-4392-98d2-35c02a774a21", "dataset_version": "688d8d8558fe847f4c1b19aed579745bcd6c7744"} \ No newline at end of file diff --git a/datalad_catalog/catalog/metadata/visual-areas/4068e6ba9400dd1b95ff8cb302cd3344.json b/datalad_catalog/catalog/metadata/visual-areas/4068e6ba9400dd1b95ff8cb302cd3344.json new file mode 100644 index 00000000..83f4a7a9 --- /dev/null +++ b/datalad_catalog/catalog/metadata/visual-areas/4068e6ba9400dd1b95ff8cb302cd3344.json @@ -0,0 +1 @@ +{"type": "redirect", "dataset_id": "92e65958-4a5a-4c34-a4f4-ee070f7a123b", "dataset_version": "203aa983534fc2b823ff4777a85f4f80d7a68656"} \ No newline at end of file From 1006ab5048eb26b9d4af8b6f657a661e740b56da Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Mon, 4 Mar 2024 16:21:17 +0100 Subject: [PATCH 06/18] fix incorrect source time committed in dbe68ec345caedc244c43ce47135eb640797b0a2 --- .../dfb/cb2533c8e474498f9451d63d385c0.json | 2 +- .../cc9/4e43626749e8e368f1526a44a8fcf.json | 2 +- .../db7/6b24cdbea351b8052cf00c1a1d898.json | 2 +- .../58a/fe240bdb862d1a2bab36fd679efb4.json | 2 +- .../e3a/40711c6157b40133f72c8598b00a2.json | 2 +- .../84f/2098de82902d61066fa8c5aaa0f79.json | 2 +- .../ed9/46e96a98769a46c7cb92b89d071a7.json | 2 +- .../d6c/4a0834f9bbceb0fda32d2abb93f95.json | 2 +- .../a31/1d8af93457571bdccbdd53ee77cc5.json | 2 +- .../d3e/3a9e40f3f36a138a58e79c33a22de.json | 2 +- .../0.1.0/cad/486b905182ab9d7cee7d80ea1173d.json | 2 +- .../b90/35a1c54a01f9ac941818f3f3a73f6.json | 2 +- .../261/eb908246b1cc2d056ef050fd8b75a.json | 2 +- .../ddb/8aa081e7afeb3831fe007a3816dce.json | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/datalad_catalog/catalog/metadata/0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307/c74b66cf37c0d4ed8914296c6d7792b2d25696aa/dfb/cb2533c8e474498f9451d63d385c0.json b/datalad_catalog/catalog/metadata/0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307/c74b66cf37c0d4ed8914296c6d7792b2d25696aa/dfb/cb2533c8e474498f9451d63d385c0.json index 5e18497f..f5ec9253 100644 --- a/datalad_catalog/catalog/metadata/0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307/c74b66cf37c0d4ed8914296c6d7792b2d25696aa/dfb/cb2533c8e474498f9451d63d385c0.json +++ b/datalad_catalog/catalog/metadata/0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307/c74b66cf37c0d4ed8914296c6d7792b2d25696aa/dfb/cb2533c8e474498f9451d63d385c0.json @@ -37,7 +37,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } diff --git a/datalad_catalog/catalog/metadata/1882e2e6-fbbf-4ade-a65f-3a1615235f51/e5d2f8368fc5f6717d8ef131041c6d943298d0c7/cc9/4e43626749e8e368f1526a44a8fcf.json b/datalad_catalog/catalog/metadata/1882e2e6-fbbf-4ade-a65f-3a1615235f51/e5d2f8368fc5f6717d8ef131041c6d943298d0c7/cc9/4e43626749e8e368f1526a44a8fcf.json index 4f7be763..f5849d05 100644 --- a/datalad_catalog/catalog/metadata/1882e2e6-fbbf-4ade-a65f-3a1615235f51/e5d2f8368fc5f6717d8ef131041c6d943298d0c7/cc9/4e43626749e8e368f1526a44a8fcf.json +++ b/datalad_catalog/catalog/metadata/1882e2e6-fbbf-4ade-a65f-3a1615235f51/e5d2f8368fc5f6717d8ef131041c6d943298d0c7/cc9/4e43626749e8e368f1526a44a8fcf.json @@ -48,7 +48,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } diff --git a/datalad_catalog/catalog/metadata/2d05f277-94b0-470b-8e11-4e56691d5b89/78e04a00fedbe3e055f86c2f9127aa48e1133d55/db7/6b24cdbea351b8052cf00c1a1d898.json b/datalad_catalog/catalog/metadata/2d05f277-94b0-470b-8e11-4e56691d5b89/78e04a00fedbe3e055f86c2f9127aa48e1133d55/db7/6b24cdbea351b8052cf00c1a1d898.json index 78fc0eae..13635df0 100644 --- a/datalad_catalog/catalog/metadata/2d05f277-94b0-470b-8e11-4e56691d5b89/78e04a00fedbe3e055f86c2f9127aa48e1133d55/db7/6b24cdbea351b8052cf00c1a1d898.json +++ b/datalad_catalog/catalog/metadata/2d05f277-94b0-470b-8e11-4e56691d5b89/78e04a00fedbe3e055f86c2f9127aa48e1133d55/db7/6b24cdbea351b8052cf00c1a1d898.json @@ -46,7 +46,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } diff --git a/datalad_catalog/catalog/metadata/3304e775-5f5f-435a-b68e-d98c9f5fb72a/aaac44e047d375cd8f791b1b6fe2b739f02c83b2/58a/fe240bdb862d1a2bab36fd679efb4.json b/datalad_catalog/catalog/metadata/3304e775-5f5f-435a-b68e-d98c9f5fb72a/aaac44e047d375cd8f791b1b6fe2b739f02c83b2/58a/fe240bdb862d1a2bab36fd679efb4.json index 51ba9568..df51583e 100644 --- a/datalad_catalog/catalog/metadata/3304e775-5f5f-435a-b68e-d98c9f5fb72a/aaac44e047d375cd8f791b1b6fe2b739f02c83b2/58a/fe240bdb862d1a2bab36fd679efb4.json +++ b/datalad_catalog/catalog/metadata/3304e775-5f5f-435a-b68e-d98c9f5fb72a/aaac44e047d375cd8f791b1b6fe2b739f02c83b2/58a/fe240bdb862d1a2bab36fd679efb4.json @@ -39,7 +39,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } diff --git a/datalad_catalog/catalog/metadata/3a8648b3-7df8-413f-8efb-4d39040ac174/10e23aafa8271f742e9022a3522d9a88d7fe30cf/e3a/40711c6157b40133f72c8598b00a2.json b/datalad_catalog/catalog/metadata/3a8648b3-7df8-413f-8efb-4d39040ac174/10e23aafa8271f742e9022a3522d9a88d7fe30cf/e3a/40711c6157b40133f72c8598b00a2.json index 85fee744..b126e06a 100644 --- a/datalad_catalog/catalog/metadata/3a8648b3-7df8-413f-8efb-4d39040ac174/10e23aafa8271f742e9022a3522d9a88d7fe30cf/e3a/40711c6157b40133f72c8598b00a2.json +++ b/datalad_catalog/catalog/metadata/3a8648b3-7df8-413f-8efb-4d39040ac174/10e23aafa8271f742e9022a3522d9a88d7fe30cf/e3a/40711c6157b40133f72c8598b00a2.json @@ -64,7 +64,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } diff --git a/datalad_catalog/catalog/metadata/45b9ab26-07fc-11e8-8c71-f0d5bf7b5561/29dcce2b9477537b433996ebc342c531139e1d87/84f/2098de82902d61066fa8c5aaa0f79.json b/datalad_catalog/catalog/metadata/45b9ab26-07fc-11e8-8c71-f0d5bf7b5561/29dcce2b9477537b433996ebc342c531139e1d87/84f/2098de82902d61066fa8c5aaa0f79.json index 0c2849ac..9f8923ae 100644 --- a/datalad_catalog/catalog/metadata/45b9ab26-07fc-11e8-8c71-f0d5bf7b5561/29dcce2b9477537b433996ebc342c531139e1d87/84f/2098de82902d61066fa8c5aaa0f79.json +++ b/datalad_catalog/catalog/metadata/45b9ab26-07fc-11e8-8c71-f0d5bf7b5561/29dcce2b9477537b433996ebc342c531139e1d87/84f/2098de82902d61066fa8c5aaa0f79.json @@ -41,7 +41,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } diff --git a/datalad_catalog/catalog/metadata/5b1081d6-84d7-11e8-b00a-a0369fb55db0/b623351b43eb2715331ac59ad4cf41682e84ff7d/ed9/46e96a98769a46c7cb92b89d071a7.json b/datalad_catalog/catalog/metadata/5b1081d6-84d7-11e8-b00a-a0369fb55db0/b623351b43eb2715331ac59ad4cf41682e84ff7d/ed9/46e96a98769a46c7cb92b89d071a7.json index a6bfcdc3..443f0827 100644 --- a/datalad_catalog/catalog/metadata/5b1081d6-84d7-11e8-b00a-a0369fb55db0/b623351b43eb2715331ac59ad4cf41682e84ff7d/ed9/46e96a98769a46c7cb92b89d071a7.json +++ b/datalad_catalog/catalog/metadata/5b1081d6-84d7-11e8-b00a-a0369fb55db0/b623351b43eb2715331ac59ad4cf41682e84ff7d/ed9/46e96a98769a46c7cb92b89d071a7.json @@ -56,7 +56,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } diff --git a/datalad_catalog/catalog/metadata/5eaff716-54eb-11e8-803d-a0369f7c647e/72f835ada046bd0479009ea0ff933b30a95b0076/d6c/4a0834f9bbceb0fda32d2abb93f95.json b/datalad_catalog/catalog/metadata/5eaff716-54eb-11e8-803d-a0369f7c647e/72f835ada046bd0479009ea0ff933b30a95b0076/d6c/4a0834f9bbceb0fda32d2abb93f95.json index b97f49dd..72b0953e 100644 --- a/datalad_catalog/catalog/metadata/5eaff716-54eb-11e8-803d-a0369f7c647e/72f835ada046bd0479009ea0ff933b30a95b0076/d6c/4a0834f9bbceb0fda32d2abb93f95.json +++ b/datalad_catalog/catalog/metadata/5eaff716-54eb-11e8-803d-a0369f7c647e/72f835ada046bd0479009ea0ff933b30a95b0076/d6c/4a0834f9bbceb0fda32d2abb93f95.json @@ -68,7 +68,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } diff --git a/datalad_catalog/catalog/metadata/7fcd8812-d0fe-11e7-8db2-a0369f7c647e/2ccaa115543c21e6658950d1cb8cc3038f14272f/a31/1d8af93457571bdccbdd53ee77cc5.json b/datalad_catalog/catalog/metadata/7fcd8812-d0fe-11e7-8db2-a0369f7c647e/2ccaa115543c21e6658950d1cb8cc3038f14272f/a31/1d8af93457571bdccbdd53ee77cc5.json index e2cf0d7d..f917417e 100644 --- a/datalad_catalog/catalog/metadata/7fcd8812-d0fe-11e7-8db2-a0369f7c647e/2ccaa115543c21e6658950d1cb8cc3038f14272f/a31/1d8af93457571bdccbdd53ee77cc5.json +++ b/datalad_catalog/catalog/metadata/7fcd8812-d0fe-11e7-8db2-a0369f7c647e/2ccaa115543c21e6658950d1cb8cc3038f14272f/a31/1d8af93457571bdccbdd53ee77cc5.json @@ -38,7 +38,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } diff --git a/datalad_catalog/catalog/metadata/92e65958-4a5a-4c34-a4f4-ee070f7a123b/203aa983534fc2b823ff4777a85f4f80d7a68656/d3e/3a9e40f3f36a138a58e79c33a22de.json b/datalad_catalog/catalog/metadata/92e65958-4a5a-4c34-a4f4-ee070f7a123b/203aa983534fc2b823ff4777a85f4f80d7a68656/d3e/3a9e40f3f36a138a58e79c33a22de.json index 7f18950a..3ae7f5b9 100644 --- a/datalad_catalog/catalog/metadata/92e65958-4a5a-4c34-a4f4-ee070f7a123b/203aa983534fc2b823ff4777a85f4f80d7a68656/d3e/3a9e40f3f36a138a58e79c33a22de.json +++ b/datalad_catalog/catalog/metadata/92e65958-4a5a-4c34-a4f4-ee070f7a123b/203aa983534fc2b823ff4777a85f4f80d7a68656/d3e/3a9e40f3f36a138a58e79c33a22de.json @@ -39,7 +39,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } diff --git a/datalad_catalog/catalog/metadata/c475969b-2919-57b1-a3e6-71770acaa222/0.1.0/cad/486b905182ab9d7cee7d80ea1173d.json b/datalad_catalog/catalog/metadata/c475969b-2919-57b1-a3e6-71770acaa222/0.1.0/cad/486b905182ab9d7cee7d80ea1173d.json index 5cc05272..3dc4371e 100644 --- a/datalad_catalog/catalog/metadata/c475969b-2919-57b1-a3e6-71770acaa222/0.1.0/cad/486b905182ab9d7cee7d80ea1173d.json +++ b/datalad_catalog/catalog/metadata/c475969b-2919-57b1-a3e6-71770acaa222/0.1.0/cad/486b905182ab9d7cee7d80ea1173d.json @@ -51,7 +51,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } diff --git a/datalad_catalog/catalog/metadata/c8ec2919-493b-4af5-9271-cbe9ebd08c43/74cd7ec0538448b05fb4d5f91119b279c5e9ab04/b90/35a1c54a01f9ac941818f3f3a73f6.json b/datalad_catalog/catalog/metadata/c8ec2919-493b-4af5-9271-cbe9ebd08c43/74cd7ec0538448b05fb4d5f91119b279c5e9ab04/b90/35a1c54a01f9ac941818f3f3a73f6.json index 43897daf..da2166eb 100644 --- a/datalad_catalog/catalog/metadata/c8ec2919-493b-4af5-9271-cbe9ebd08c43/74cd7ec0538448b05fb4d5f91119b279c5e9ab04/b90/35a1c54a01f9ac941818f3f3a73f6.json +++ b/datalad_catalog/catalog/metadata/c8ec2919-493b-4af5-9271-cbe9ebd08c43/74cd7ec0538448b05fb4d5f91119b279c5e9ab04/b90/35a1c54a01f9ac941818f3f3a73f6.json @@ -38,7 +38,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } diff --git a/datalad_catalog/catalog/metadata/ceb007ac-ef05-4392-98d2-35c02a774a21/688d8d8558fe847f4c1b19aed579745bcd6c7744/261/eb908246b1cc2d056ef050fd8b75a.json b/datalad_catalog/catalog/metadata/ceb007ac-ef05-4392-98d2-35c02a774a21/688d8d8558fe847f4c1b19aed579745bcd6c7744/261/eb908246b1cc2d056ef050fd8b75a.json index 390730ce..616f50b2 100644 --- a/datalad_catalog/catalog/metadata/ceb007ac-ef05-4392-98d2-35c02a774a21/688d8d8558fe847f4c1b19aed579745bcd6c7744/261/eb908246b1cc2d056ef050fd8b75a.json +++ b/datalad_catalog/catalog/metadata/ceb007ac-ef05-4392-98d2-35c02a774a21/688d8d8558fe847f4c1b19aed579745bcd6c7744/261/eb908246b1cc2d056ef050fd8b75a.json @@ -42,7 +42,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } diff --git a/datalad_catalog/catalog/metadata/deabeb9b-7a37-4062-a1e0-8fcef7909609/6d7fb68264f9b9951ae141fc830712a8744e3293/ddb/8aa081e7afeb3831fe007a3816dce.json b/datalad_catalog/catalog/metadata/deabeb9b-7a37-4062-a1e0-8fcef7909609/6d7fb68264f9b9951ae141fc830712a8744e3293/ddb/8aa081e7afeb3831fe007a3816dce.json index 73db3034..ae8ca055 100644 --- a/datalad_catalog/catalog/metadata/deabeb9b-7a37-4062-a1e0-8fcef7909609/6d7fb68264f9b9951ae141fc830712a8744e3293/ddb/8aa081e7afeb3831fe007a3816dce.json +++ b/datalad_catalog/catalog/metadata/deabeb9b-7a37-4062-a1e0-8fcef7909609/6d7fb68264f9b9951ae141fc830712a8744e3293/ddb/8aa081e7afeb3831fe007a3816dce.json @@ -251,7 +251,7 @@ "source_name": "manual_entry", "source_version": "1", "source_parameter": {}, - "source_time": 1709548638972.9111, + "source_time": 1709565468.450221, "agent_name": "Stephan Heunis", "agent_email": "s.heunis@fz-juelich.de" } From 7dfbda768d406427aeb95dcbdc51313b158303f2 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Mon, 4 Mar 2024 16:26:48 +0100 Subject: [PATCH 07/18] updates to javascript assets to allow user-friendly navigation These are the web-side changes that accompany the previous commits related to dataset aliases and dataset id concepts. This now allows users to navigate to e.g. http://mycatalog.de/dataset/\ or to e.g. http://mycatalog.de/dataset/\. The javascript will first fetch the concept id file or the alias file, which contains a redirect pointer to the correct dataset id AND version. Internal navigation between datasets are still done based on the dataset-id AND dataset-version URL parameters. The latter now becomes an optional parameter. One aspect that this commit does not account for yet is the second optional URL parameter 'tab' and its use with the sinle required URL parameter. --- .../catalog/assets/app_component_dataset.js | 17 +++++++++++++ datalad_catalog/catalog/assets/app_globals.js | 25 +++++++++++++------ datalad_catalog/catalog/assets/app_router.js | 2 +- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/datalad_catalog/catalog/assets/app_component_dataset.js b/datalad_catalog/catalog/assets/app_component_dataset.js index 5ffe750b..95ce9b4d 100644 --- a/datalad_catalog/catalog/assets/app_component_dataset.js +++ b/datalad_catalog/catalog/assets/app_component_dataset.js @@ -771,6 +771,23 @@ const datasetView = () => return; } text = await response.text(); + response_obj = JSON.parse(text); + // if the object.type is alias (i.e. the url parameter is an alias for the dataset) + // replace the current route with one containing the actual id and version + // TODO: should this be an actual route replace? or should the route with + // alias be kept as is and the correct dataset info just fetched from the file + // associated with the id and version? + if (response_obj["type"] == "redirect") { + const replace_route_info = { + name: "dataset", + params: { + dataset_id: response_obj.dataset_id, + dataset_version: response_obj.dataset_version, + }, + } + router.replace(replace_route_info) + return; + } app.selectedDataset = JSON.parse(text); this.dataset_ready = true; if ( diff --git a/datalad_catalog/catalog/assets/app_globals.js b/datalad_catalog/catalog/assets/app_globals.js index c00f4d7a..648f20a3 100644 --- a/datalad_catalog/catalog/assets/app_globals.js +++ b/datalad_catalog/catalog/assets/app_globals.js @@ -56,15 +56,24 @@ async function grabSubDatasets(app) { function getFilePath(dataset_id, dataset_version, path, ext = ".json") { // Get node file location from dataset id, dataset version, and node path // using a file system structure similar to RIA stores - file = metadata_dir + "/" + dataset_id + "/" + dataset_version; - blob = dataset_id + "-" + dataset_version; - if (path) { - blob = blob + "-" + path; + // - dataset_id is required, all the other parameters are optional + // - dataset_id could either be an actual dataset ID or an alias + file = metadata_dir + "/" + dataset_id + blob = dataset_id + if (dataset_version) { + file = file + "/" + dataset_version; + blob = blob + "-" + dataset_version; + // path to file only makes sense with the context of a dataset id AND version + if (path) { + blob = blob + "-" + path; + } + blob = md5(blob); + blob_parts = [blob.substring(0, SPLIT_INDEX), blob.substring(SPLIT_INDEX)]; + return file + "/" + blob_parts[0] + "/" + blob_parts[1] + ext; + } else { + blob = md5(blob); + return file + "/" + blob + ext; } - blob = md5(blob); - blob_parts = [blob.substring(0, SPLIT_INDEX), blob.substring(SPLIT_INDEX)]; - file = file + "/" + blob_parts[0] + "/" + blob_parts[1] + ext; - return file; } function getRelativeFilePath(dataset_id, dataset_version, path) { diff --git a/datalad_catalog/catalog/assets/app_router.js b/datalad_catalog/catalog/assets/app_router.js index 0a775e05..51a6460c 100644 --- a/datalad_catalog/catalog/assets/app_router.js +++ b/datalad_catalog/catalog/assets/app_router.js @@ -36,7 +36,7 @@ const routes = [ }, }, { - path: "/dataset/:dataset_id/:dataset_version/:tab_name?", + path: "/dataset/:dataset_id/:dataset_version?/:tab_name?", component: datasetView, name: "dataset", }, From ab2fbeabb51696a534daeb0f43c2e969d8e1a1b7 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Mon, 4 Mar 2024 23:50:28 +0100 Subject: [PATCH 08/18] update script to allow adding dataset aliases to metadata from tsv file --- tools/create_alias_concept_metadata.py | 75 +++++++++++++++++++------- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/tools/create_alias_concept_metadata.py b/tools/create_alias_concept_metadata.py index cdb4b6a6..57ed3ec2 100644 --- a/tools/create_alias_concept_metadata.py +++ b/tools/create_alias_concept_metadata.py @@ -1,33 +1,46 @@ """ With this script you can do the following for an existing catalog: -- create aliases for datasets from a tsv file (TODO) +- create aliases for datasets from a tsv file - create alias and concept id metadata files for all datasets """ from argparse import ArgumentParser +import csv import json +from pathlib import Path +from datalad.api import ( + catalog_add, +) from datalad_catalog.constraints import EnsureWebCatalog from datalad_catalog.utils import md5hash +from datalad_catalog.schema_utils import get_metadata_item -if __name__ == "__main__": - parser = ArgumentParser() - parser.add_argument( - "--catalog", - type=str, - help="Path to the catalog", - ) - parser.add_argument( - "--aliases", - type=str, - help="Path to tsv file with dataset ids and aliases", - ) - args = parser.parse_args() - # Ensure is a catalog - catalog = EnsureWebCatalog()(args.catalog) + +def add_aliases(alias_path, catalog): + + alias_path = Path(alias_path) + with alias_path.open(newline='') as tsvfile: + reader = csv.DictReader(tsvfile, delimiter='\t') + for i, row in enumerate(reader): + meta_item = get_metadata_item( + item_type="dataset", + dataset_id=row["dataset_id"], + dataset_version=row["dataset_version"], + source_name="automated_alias_entry", + source_version="0.1.0", + required_only=True, + exclude_keys=[], + ) + meta_item["alias"] = row["alias"] + catalog_add( + catalog=catalog, + metadata=json.dumps(meta_item), + ) + +def create_metadata_files(catalog): # Get report report = catalog.get_catalog_report() - # Write metadata for all datasets - # assumes that datasets have aliases set + # - assumes that datasets have aliases set for d in report.get("datasets", []): # Get latest version current_ds_versions = [ @@ -38,14 +51,12 @@ key=lambda d: d.get("updated_at"), reverse=True, ) - # Dict for metadata redirect_dict = { "type": "redirect", "dataset_id": d, "dataset_version": sorted_versions[0]["dataset_version"], } - # Create id concept metadata dataset_concept_path = ( catalog.metadata_path / d / md5hash(d) @@ -63,3 +74,27 @@ dataset_alias_path.parent.mkdir(parents=True, exist_ok=True) with open(dataset_alias_path, "w") as f: json.dump(redirect_dict, f) + + + +if __name__ == "__main__": + parser = ArgumentParser() + parser.add_argument( + "--catalog", + type=str, + help="Path to the catalog", + ) + parser.add_argument( + "--aliases", + type=str, + help="Path to tsv file with dataset ids and aliases", + ) + args = parser.parse_args() + # Ensure is a catalog + catalog = EnsureWebCatalog()(args.catalog) + + # If aliases are provided, first set them in metadata + if (args.aliases): + add_aliases(args.aliases, catalog) + + create_metadata_files(catalog) \ No newline at end of file From b7af8b48f13b487534bf34219e1465d8b64634d2 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Wed, 10 Apr 2024 23:44:25 +0200 Subject: [PATCH 09/18] linting for alias script --- tools/create_alias_concept_metadata.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/create_alias_concept_metadata.py b/tools/create_alias_concept_metadata.py index 57ed3ec2..59edd452 100644 --- a/tools/create_alias_concept_metadata.py +++ b/tools/create_alias_concept_metadata.py @@ -7,7 +7,7 @@ import csv import json from pathlib import Path -from datalad.api import ( +from datalad.api import ( catalog_add, ) from datalad_catalog.constraints import EnsureWebCatalog @@ -16,10 +16,9 @@ def add_aliases(alias_path, catalog): - alias_path = Path(alias_path) - with alias_path.open(newline='') as tsvfile: - reader = csv.DictReader(tsvfile, delimiter='\t') + with alias_path.open(newline="") as tsvfile: + reader = csv.DictReader(tsvfile, delimiter="\t") for i, row in enumerate(reader): meta_item = get_metadata_item( item_type="dataset", @@ -36,6 +35,7 @@ def add_aliases(alias_path, catalog): metadata=json.dumps(meta_item), ) + def create_metadata_files(catalog): # Get report report = catalog.get_catalog_report() @@ -76,7 +76,6 @@ def create_metadata_files(catalog): json.dump(redirect_dict, f) - if __name__ == "__main__": parser = ArgumentParser() parser.add_argument( @@ -94,7 +93,7 @@ def create_metadata_files(catalog): catalog = EnsureWebCatalog()(args.catalog) # If aliases are provided, first set them in metadata - if (args.aliases): + if args.aliases: add_aliases(args.aliases, catalog) - create_metadata_files(catalog) \ No newline at end of file + create_metadata_files(catalog) From c40242e2451251f74098b7412ea82c9f2397c9c2 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Fri, 12 Apr 2024 00:22:25 +0200 Subject: [PATCH 10/18] wip: work on instating tabs and keywords as route query parameters This falls into the same context as the work on aliasing and concept id navigation. The point is that any number of combinations between using an alias or concept id or dataset_id+version, and query tabs and keywords as query parameters should be possible. An important change is the use of history.replaceState to update the query string in the URL without updating the route or reloading it (i.e. without using pushState). This seems to work fine, but the process of keeping the query string and the selected keywords and tabs in sync is still not ironed out completely, and hence some navigations are still a bit buggy (e.g. after navigation to a subdataset, a keyword query param might still remain, unexpectedly). Note that vue-router's router.push is not aware of the history.replaceState call. This is not a problem per se, but needs to be kept track of. --- .../catalog/assets/app_component_dataset.js | 78 +++++++++++++++---- datalad_catalog/catalog/assets/app_router.js | 3 +- 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/datalad_catalog/catalog/assets/app_component_dataset.js b/datalad_catalog/catalog/assets/app_component_dataset.js index 95ce9b4d..1e9749ac 100644 --- a/datalad_catalog/catalog/assets/app_component_dataset.js +++ b/datalad_catalog/catalog/assets/app_component_dataset.js @@ -57,11 +57,30 @@ const datasetView = () => ); } }); - } + } this.tag_options = tags; this.tag_options_filtered = this.tag_options; this.tag_options_available = this.tag_options; this.tags_ready = true; + + // if keyword(s) included in query parameters + if (this.$route.query.hasOwnProperty("keyword")) { + query_keywords = this.$route.query.keyword + // if included keywords(s) not null or empty string/array/object + if (query_keywords) { + // if included keywords(s) = array + if ((query_keywords instanceof Array || Array.isArray(query_keywords)) + && query_keywords.length > 0) { + // add all search tags + for (const el of query_keywords) { + console.log(`adding to search tags: ${el}`) + this.addSearchTag(el) + } + } else { + this.addSearchTag(query_keywords) + } + } + } } }, dataset_ready: function (newVal, oldVal) { @@ -300,6 +319,28 @@ const datasetView = () => if (tabs[newTabIndex] == 'content') { this.getFiles() } + // Update URL query string whenever a new tab is selected + this.updateURLQueryString(this.$route, newTabIndex) + }, + updateURLQueryString(current_route, tab_index) { + if (tab_index) { + query_tab = this.selectedDataset.available_tabs[tab_index]; + } else { + const query = Object.assign({}, current_route.query); + default_tab = this.$root.selectedDataset.config?.dataset_options?.default_tab + query_tab = query.tab ? query.tab : (default_tab ? default_tab : "content") + } + query_string = '?tab=' + query_tab + if (this.search_tags.length > 0) { + for (const element of this.search_tags) { + query_string = query_string + '&keyword=' + element + } + } + history.replaceState( + {}, + null, + current_route.path + query_string + ) }, copyCloneCommand(index) { // https://stackoverflow.com/questions/60581285/execcommand-is-now-obsolete-whats-the-alternative @@ -354,15 +395,23 @@ const datasetView = () => dataset_id: objId, dataset_version: objVersion, }, + query: {}, } // before navigation, clear filtering options this.clearFilters() // now navigate if (newBrowserTab) { const routeData = router.resolve(route_info); + console.log(routeData) window.open(routeData.href, '_blank'); } else { + this.search_tags = [] + history.replaceState( + {}, + null, + this.$route.path + ) router.push(route_info); } } else { @@ -416,20 +465,14 @@ const datasetView = () => }, } if (!this.catalogHasHome()) { - if (this.$route.params.tab_name) { - router.push(current_route_info) - } else { this.clearFilters(); this.tabIndex = this.getDefaultTabIdx(); - } + this.updateURLQueryString(this.$route, this.tabIndex) } else { if (this.currentIsHome()) { - if (this.$route.params.tab_name) { - router.push(current_route_info) - } else { - this.clearFilters(); - this.tabIndex = this.getDefaultTabIdx(); - } + this.clearFilters(); + this.tabIndex = this.getDefaultTabIdx(); + this.updateURLQueryString(this.$route, this.tabIndex) } else { router.push({ name: "home" }); } @@ -501,6 +544,7 @@ const datasetView = () => this.search_tags.push(option); this.clearSearchTagText(); this.filterTags(); + this.updateURLQueryString(this.$route) }, removeSearchTag(tag) { idx = this.search_tags.indexOf(tag); @@ -508,6 +552,7 @@ const datasetView = () => this.search_tags.splice(idx, 1); } this.filterTags(); + this.updateURLQueryString(this.$route) }, clearSearchTagText() { this.tag_text = ""; @@ -582,7 +627,8 @@ const datasetView = () => // If a tab parameter is supplied via the router, navigate to that tab if // part of available tabs, otherwise default tab else { - selectTab = tabs.indexOf(tab_param.toLowerCase()) + tab_param = Array.isArray(tab_param) ? tab_param[0] : tab_param + selectTab = available_tabs.indexOf(tab_param.toLowerCase()) if (selectTab >= 0) { this.tabIndex = selectTab; } else { @@ -736,8 +782,9 @@ const datasetView = () => this.$root.selectedDataset.config = config; } // Set the correct tab to be rendered + correct_tab = to.query.hasOwnProperty("tab") ? to.query.tab : null this.setCorrectTab( - to.params.tab_name, + correct_tab, available_tabs_lower, this.$root.selectedDataset.config?.dataset_options?.default_tab ) @@ -784,6 +831,7 @@ const datasetView = () => dataset_id: response_obj.dataset_id, dataset_version: response_obj.dataset_version, }, + query: this.$route.query, } router.replace(replace_route_info) return; @@ -883,9 +931,9 @@ const datasetView = () => config = JSON.parse(configtext); this.$root.selectedDataset.config = config; } - // Set the correct tab to be rendered + correct_tab = this.$route.query.hasOwnProperty("tab") ? this.$route.query.tab : null this.setCorrectTab( - this.$route.params.tab_name, + correct_tab, available_tabs_lower, this.$root.selectedDataset.config?.dataset_options?.default_tab ) diff --git a/datalad_catalog/catalog/assets/app_router.js b/datalad_catalog/catalog/assets/app_router.js index 51a6460c..c0b34173 100644 --- a/datalad_catalog/catalog/assets/app_router.js +++ b/datalad_catalog/catalog/assets/app_router.js @@ -22,6 +22,7 @@ const routes = [ dataset_id: superds["dataset_id"], dataset_version: superds["dataset_version"], }, + query: to.query, }); next(); } else if (rawFile.status === 404) { @@ -36,7 +37,7 @@ const routes = [ }, }, { - path: "/dataset/:dataset_id/:dataset_version?/:tab_name?", + path: "/dataset/:dataset_id/:dataset_version?", component: datasetView, name: "dataset", }, From e26fc1df314d5f75fe5acf932d8f4d626eda1f63 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Mon, 15 Apr 2024 23:04:32 +0200 Subject: [PATCH 11/18] add ability for alias to point to ID only That is, an alias file can redirect to a dataset ID without specifying a dataset version. Importantly, the concept ID metadata file should always specify a dataset version. This lays the groundwork for allowing an alias to identify either a dataset OR a dataset-version. --- .../catalog/assets/app_component_dataset.js | 39 ++++++++++++++----- .../54733551de044407ac7f4e3bc91290d4.json | 2 +- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/datalad_catalog/catalog/assets/app_component_dataset.js b/datalad_catalog/catalog/assets/app_component_dataset.js index 1e9749ac..61a00169 100644 --- a/datalad_catalog/catalog/assets/app_component_dataset.js +++ b/datalad_catalog/catalog/assets/app_component_dataset.js @@ -646,10 +646,28 @@ const datasetView = () => async beforeRouteUpdate(to, from, next) { this.subdatasets_ready = false; this.dataset_ready = false; - file = getFilePath(to.params.dataset_id, to.params.dataset_version, null); response = await fetch(file); text = await response.text(); + response_obj = JSON.parse(text); + // if the object.type is redirect (i.e. the url parameter is an alias for or ID + // of the dataset) replace the current route with one containing the actual id + // and optionally version + if (response_obj["type"] == "redirect") { + route_params = { + dataset_id: response_obj.dataset_id, + } + if (response_obj.dataset_version) { + route_params.dataset_version = response_obj.dataset_version + } + const replace_route_info = { + name: "dataset", + params: route_params, + query: to.query, + } + router.replace(replace_route_info) + return; + } this.$root.selectedDataset = JSON.parse(text); this.$root.selectedDataset.name = this.$root.selectedDataset.name ? this.$root.selectedDataset.name @@ -819,18 +837,19 @@ const datasetView = () => } text = await response.text(); response_obj = JSON.parse(text); - // if the object.type is alias (i.e. the url parameter is an alias for the dataset) - // replace the current route with one containing the actual id and version - // TODO: should this be an actual route replace? or should the route with - // alias be kept as is and the correct dataset info just fetched from the file - // associated with the id and version? + // if the object.type is redirect (i.e. the url parameter is an alias for or ID + // of the dataset) replace the current route with one containing the actual id + // and optionally version if (response_obj["type"] == "redirect") { + route_params = { + dataset_id: response_obj.dataset_id, + } + if (response_obj.dataset_version) { + route_params.dataset_version = response_obj.dataset_version + } const replace_route_info = { name: "dataset", - params: { - dataset_id: response_obj.dataset_id, - dataset_version: response_obj.dataset_version, - }, + params: route_params, query: this.$route.query, } router.replace(replace_route_info) diff --git a/datalad_catalog/catalog/metadata/conversion-qa/54733551de044407ac7f4e3bc91290d4.json b/datalad_catalog/catalog/metadata/conversion-qa/54733551de044407ac7f4e3bc91290d4.json index 3eca9b3e..77e611e7 100644 --- a/datalad_catalog/catalog/metadata/conversion-qa/54733551de044407ac7f4e3bc91290d4.json +++ b/datalad_catalog/catalog/metadata/conversion-qa/54733551de044407ac7f4e3bc91290d4.json @@ -1 +1 @@ -{"type": "redirect", "dataset_id": "0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307", "dataset_version": "c74b66cf37c0d4ed8914296c6d7792b2d25696aa"} \ No newline at end of file +{"type": "redirect", "dataset_id": "0f66b1ba-e9a9-46fd-b9d9-2e64fe94d307"} \ No newline at end of file From 5ffe81bb78c44ead0310acd64a27a51e5d0d0c28 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Mon, 15 Apr 2024 23:35:13 +0200 Subject: [PATCH 12/18] fix outdated demo site link in docs, outdated tutorial link in readme, and outdated command syntax in readme --- README.md | 38 +++++++++++++++++++++++--------------- docs/source/index.rst | 4 ++-- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index a3224b97..1ff85569 100644 --- a/README.md +++ b/README.md @@ -112,34 +112,42 @@ The overall catalog generation process actually starts several steps before the The first four steps in this list can follow any arbitrarily specified procedures and can use any arbitrarily specified tools to get the job done. If these steps are completed, correctly formatted data can be input, together with some configuration details, to `datalad-catalog`. This tool then provides several basic commands for catalog generation and customization. *For example:* ```bash +# CREATE a new catalog from scratch: +datalad catalog-create -c /tmp/my-cat -datalad catalog validate -m -# Validate input data located at according to the catalog's schema. +#ADD metadata to an existing catalog: +datalad catalog-add -c /tmp/my-cat -m path/to/metadata.jsonl -datalad catalog create -c -m -# Create a catalog at location , using input data located at . +# SET a property of an existing catalog, such as the home page of an existing catalog - i.e. the first dataset displayed when navigating to the root URL of the catalog: +datalad catalog-set -c /tmp/my-cat -i abcd -v 1234 home -datalad catalog add -c -m -# Add metadata to an existing catalog at location , using input data located at . +# SERVE the content of the catalog via a local HTTP server at http://localhost:8001: +datalad catalog-serve -c /tmp/my-cat -p 8001 -datalad catalog set-super -c -i -v -# Set the superdataset of an existing catalog at location , where the superdataset id and version are provided as arguments. The superdataset will be the first dataset displayed when navigating to the root URL of a catalog. +# VALIDATE metadata against a catalog schema without adding it to the catalog:: +datalad catalog-validate -c /tmp/my-cat/-m path/to/metadata.jsonl -datalad catalog serve -c -# Serve the content of the catalog at location via a local HTTP server. +# GET a property of an existing catalog, such as the catalog configuration: +datalad catalog-get -c /tmp/my-cat/ config -datalad catalog workflow-new -c -d -# Run a workflow for recursive metadata extraction (using datalad-metalad), translating metadata to the catalog schema (using JQ bindings), and adding the translated metadata to a new catalog. +# REMOVE a specific metadata record from an existing catalog: +datalad catalog-remove -c /tmp/my-cat -i efgh -v 5678 -datalad catalog workflow-update -c -d -s -# Run a workflow for updating a catalog after registering a subdataset to the superdataset which the catalog represents. This workflow includes extraction (using datalad-metalad), translating metadata to the catalog schema (using JQ bindings), and adding the translated metadata to the existing catalog. +# TRANSLATE a metalad-extracted metadata item from a particular source structure into the catalog schema. A dedicated translator should be provided and exposed as an entry point (e.g. via a DataLad extension) as part of the 'datalad.metadata.translators' group: +datalad catalog-translate -c /tmp/my-cat -m path/to/metadata.jsonl + +# RUN A WORKFLOW for recursive metadata extraction (using datalad-metalad), translating metadata to the catalog schema, and adding the translated metadata to a new catalog: +datalad catalog-workflow -t new -c /tmp/my-cat -d path/to/superdataset -e metalad_core + +# RUN A WORKFLOW for updating a catalog after registering a subdataset to the superdataset which the catalog represents. This workflow includes extraction (using datalad-metalad), translating metadata to the catalog schema, and adding the translated metadata to the existing catalog: +datalad catalog-workflow -t new -c /tmp/my-cat -d path/to/superdataset -s path/to/subdataset -e metalad_core ```
## 5. Tutorial -To explore the basic functionality of `datalad-catalog`, please refer to [these tutorials](https://github.com/datalad/tutorials/tree/master/notebooks/catalog_tutorials#readme). +To explore the basic functionality of `datalad-catalog`, please refer to [the tutorial in the DataLad Handbook](https://handbook.datalad.org/en/latest/beyond_basics/101-182-catalog.html). ## 6. An example workflow diff --git a/docs/source/index.rst b/docs/source/index.rst index a7d7ea91..68bf099f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -29,7 +29,7 @@ Foundation) under grant SFB 1451 (`431549029`_, INF project). Demo ==== -See our `demo catalog`_, hosted via GitHub Pages. This catalog was generated +See our `demo catalog`_, hosted via Netlify. This catalog was generated from the `studyforrest dataset`_. .. image:: /_static/datalad_catalog_demo.svg @@ -67,6 +67,6 @@ Indices and tables .. |---| unicode:: U+02014 .. em dash -.. _demo catalog: https://datalad.github.io/datalad-catalog/ +.. _demo catalog: https://datalad-catalog.netlify.app/ .. _studyforrest dataset: https://www.studyforrest.org/ From 70df623424238156b11771f335820ab01b20bc3d Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Tue, 16 Apr 2024 00:12:25 +0200 Subject: [PATCH 13/18] fix url query error related to first available tab --- datalad_catalog/catalog/assets/app_component_dataset.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/datalad_catalog/catalog/assets/app_component_dataset.js b/datalad_catalog/catalog/assets/app_component_dataset.js index 61a00169..20bb1dbf 100644 --- a/datalad_catalog/catalog/assets/app_component_dataset.js +++ b/datalad_catalog/catalog/assets/app_component_dataset.js @@ -323,7 +323,7 @@ const datasetView = () => this.updateURLQueryString(this.$route, newTabIndex) }, updateURLQueryString(current_route, tab_index) { - if (tab_index) { + if (tab_index >= 0) { query_tab = this.selectedDataset.available_tabs[tab_index]; } else { const query = Object.assign({}, current_route.query); @@ -688,8 +688,6 @@ const datasetView = () => this.$root.selectedDataset.keywords = this.$root.selectedDataset.keywords ? this.$root.selectedDataset.keywords : []; - this.dataset_ready = true; - if ( this.$root.selectedDataset.hasOwnProperty("subdatasets") && this.$root.selectedDataset.subdatasets instanceof Array && @@ -806,9 +804,12 @@ const datasetView = () => available_tabs_lower, this.$root.selectedDataset.config?.dataset_options?.default_tab ) + this.dataset_ready = true; next(); }, async created() { + this.dataset_ready = false; + this.subdatasets_ready = false; // fetch superfile in order to set id and version on $root homefile = metadata_dir + "/super.json"; homeresponse = await fetch(homefile); @@ -856,7 +857,6 @@ const datasetView = () => return; } app.selectedDataset = JSON.parse(text); - this.dataset_ready = true; if ( this.$root.selectedDataset.hasOwnProperty("subdatasets") && this.$root.selectedDataset.subdatasets instanceof Array && @@ -956,6 +956,7 @@ const datasetView = () => available_tabs_lower, this.$root.selectedDataset.config?.dataset_options?.default_tab ) + this.dataset_ready = true; }, mounted() { this.tag_options_filtered = this.tag_options; From 5fed8d21792df7a68300735cbce25766feb068a1 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Wed, 17 Apr 2024 10:19:29 +0200 Subject: [PATCH 14/18] wip: minor commit while debugging query string issues --- .../catalog/assets/app_component_dataset.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/datalad_catalog/catalog/assets/app_component_dataset.js b/datalad_catalog/catalog/assets/app_component_dataset.js index 20bb1dbf..dc24d984 100644 --- a/datalad_catalog/catalog/assets/app_component_dataset.js +++ b/datalad_catalog/catalog/assets/app_component_dataset.js @@ -323,6 +323,8 @@ const datasetView = () => this.updateURLQueryString(this.$route, newTabIndex) }, updateURLQueryString(current_route, tab_index) { + console.log("updateURLQueryString - current route:") + console.log(current_route) if (tab_index >= 0) { query_tab = this.selectedDataset.available_tabs[tab_index]; } else { @@ -407,11 +409,16 @@ const datasetView = () => } else { this.search_tags = [] - history.replaceState( - {}, - null, - this.$route.path - ) + // The following commented out code is an attempt to fix remaining + // bugs with query strings that remain in the url when navigating to + // a subdataset. This code tries to set the query string to null first, + // by replacing the state, before pushing the next route via vue router. + // It didn't seem to solve the issue, but should be investigated more. + // history.replaceState( + // {}, + // null, + // this.$route.path + // ) router.push(route_info); } } else { From 858475626faf484bbffe03db2dd429dcc7e30ca4 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Wed, 17 Apr 2024 22:16:49 +0200 Subject: [PATCH 15/18] More functionality to consolidate router.push and history.replaceState behaviour This commit fixes bugs in the recently added functionality to update the URL query string based on user selections. The problems included that a test for '>= 0' incorrectly validated null or NaN, resulting in the incorrect part of an if statement being executed and creating the '?tab=undefined' issue in the query string; and also that the code for adding/removing search tags based on the 'keyword' parameter in the query string had to move to the 'dataset_ready' watcher rather than the 'subdatasets_ready' watcher to allow more time for asynchronous code to complete. To support debugging during this and future steps, several 'console.debug' statements were added all over the code base. Lastly, references in the html rendering to 'Subdatasets' were replaced with 'Datasets' to conform to recent similar changes in other catalog instances. --- datalad_catalog/catalog/assets/app.js | 18 +-- .../catalog/assets/app_component_dataset.js | 131 +++++++++++++----- datalad_catalog/catalog/assets/app_router.js | 1 + .../catalog/templates/dataset-template.html | 4 +- 4 files changed, 98 insertions(+), 56 deletions(-) diff --git a/datalad_catalog/catalog/assets/app.js b/datalad_catalog/catalog/assets/app.js index b56ea9a1..a3be4528 100644 --- a/datalad_catalog/catalog/assets/app.js +++ b/datalad_catalog/catalog/assets/app.js @@ -22,25 +22,9 @@ var datacat = new Vue({ gotoExternal(dest) { window.open(dest); }, - async load() { - // Load templates - await Promise.all( - Object.keys(template_paths).map(async (key, index) => { - url = template_dir + "/" + template_paths[key] - fetch(url). - then(response => { - return response.text(); - }). - then(text => { - console.log('template loaded: '+key) - console.log(text) - document.getElementById(key).innerHTML = text; - }); - }) - ) - } }, beforeCreate() { + console.debug("Executing lifecycle hook: beforeCreate") fetch(config_file) .then((response) => { if (response.ok) { diff --git a/datalad_catalog/catalog/assets/app_component_dataset.js b/datalad_catalog/catalog/assets/app_component_dataset.js index e6b1946f..8328c471 100644 --- a/datalad_catalog/catalog/assets/app_component_dataset.js +++ b/datalad_catalog/catalog/assets/app_component_dataset.js @@ -60,29 +60,15 @@ const datasetView = () => this.tag_options_filtered = this.tag_options; this.tag_options_available = this.tag_options; this.tags_ready = true; - - // if keyword(s) included in query parameters - if (this.$route.query.hasOwnProperty("keyword")) { - query_keywords = this.$route.query.keyword - // if included keywords(s) not null or empty string/array/object - if (query_keywords) { - // if included keywords(s) = array - if ((query_keywords instanceof Array || Array.isArray(query_keywords)) - && query_keywords.length > 0) { - // add all search tags - for (const el of query_keywords) { - console.log(`adding to search tags: ${el}`) - this.addSearchTag(el) - } - } else { - this.addSearchTag(query_keywords) - } - } - } + } }, dataset_ready: function (newVal, oldVal) { - // TODO: some of these methods/steps should be moved to the generatpr tool. e.g. shortname + // The code in this function is executed once the properties, + // children, variables, and everything related to the currently + // selected dataset is deemed "ready". This means subdatasets + // have been fetched and some subdataset properties have been + // collected to assist dataset-level UX (including search tags) if (newVal) { console.debug("Watched property: dataset_ready = true") console.debug("Active dataset:"); @@ -239,9 +225,27 @@ const datasetView = () => if ( disp_dataset.url || dataset.hasOwnProperty("notebooks") && current_dataset.notebooks.length > 0 ) { disp_dataset.show_binder_button = true } - // Write main derived variable and set to ready - this.displayData = disp_dataset; - this.display_ready = true; + + // Set correct URL query string to mirrorif keyword(s) included in query parameters + if (this.$route.query.hasOwnProperty("keyword")) { + query_keywords = this.$route.query.keyword + // if included keywords(s) not null or empty string/array/object + if (query_keywords) { + console.debug("Keywords in query parameter taken from vue route:") + console.debug(query_keywords) + // if included keywords(s) = array + if ((query_keywords instanceof Array || Array.isArray(query_keywords)) + && query_keywords.length > 0) { + // add all search tags + for (const el of query_keywords) { + console.log(`adding to search tags: ${el}`) + this.addSearchTag(el) + } + } else { + this.addSearchTag(query_keywords) + } + } + } // Add json-ld data to head var scripttag = document.getElementById("structured-data") @@ -258,6 +262,12 @@ const datasetView = () => "description": this.selectedDataset.description ? this.selectedDataset.description : "" } scripttag.textContent = JSON.stringify(obj); + + // Write main derived variable and set to ready + this.displayData = disp_dataset; + this.display_ready = true; + + console.debug("Watched property function completed: dataset_ready = true") } }, }, @@ -336,21 +346,33 @@ const datasetView = () => methods: { newTabActivated(newTabIndex, prevTabIndex, bvEvent) { var tabs = this.selectedDataset.available_tabs + console.debug( + "%c> USER INPUT: new tab selected (%s)", + "color: white; font-style: italic; background-color: blue", + tabs[newTabIndex] + ); if (tabs[newTabIndex] == 'content') { this.getFiles() } // Update URL query string whenever a new tab is selected this.updateURLQueryString(this.$route, newTabIndex) }, - updateURLQueryString(current_route, tab_index) { - console.log("updateURLQueryString - current route:") - console.log(current_route) - if (tab_index >= 0) { + updateURLQueryString(current_route, tab_index = null) { + // This function is called from: + // - addSearchTag(): when adding a search tag (a.k.a. keyword) - WITHOUT tab_index param + // - removeSearchTag(): when removing a search tag (a.k.a. keyword) - WITHOUT tab_index param + // - newTabActivated(): when a new tab is selected or programmatically activated - WITH tab_index param + console.debug("---\nUpdating URL query string\n---") + console.debug("- Argument tab_index: %i", tab_index) + console.debug("- Before: Vue Route query params: %s", JSON.stringify(Object.assign({}, current_route.query))) + let url_qp = new URL(document.location.toString()).searchParams + console.debug("- Before: URL query string: %s", url_qp.toString()) + var query_tab + if (Number.isInteger(tab_index)) { query_tab = this.selectedDataset.available_tabs[tab_index]; } else { - const query = Object.assign({}, current_route.query); default_tab = this.$root.selectedDataset.config?.dataset_options?.default_tab - query_tab = query.tab ? query.tab : (default_tab ? default_tab : "content") + query_tab = url_qp.get("tab") ? url_qp.get("tab") : (default_tab ? default_tab : "content") } query_string = '?tab=' + query_tab if (this.search_tags.length > 0) { @@ -363,6 +385,9 @@ const datasetView = () => null, current_route.path + query_string ) + console.debug("- After: Vue Route query params: %s", JSON.stringify(Object.assign({}, this.$route.query))) + let url_qp2 = new URL(document.location.toString()).searchParams + console.debug("- After: URL query string: %s", url_qp2.toString()) }, copyCloneCommand(index) { // https://stackoverflow.com/questions/60581285/execcommand-is-now-obsolete-whats-the-alternative @@ -401,6 +426,10 @@ const datasetView = () => }, 1000); }, async selectDataset(event, obj, objId, objVersion, objPath) { + console.debug( + "%c> USER INPUT: dataset selected", + "color: white; font-style: italic; background-color: blue", + ); console.debug("Inside selectDataset") console.debug(event) event.preventDefault() @@ -454,6 +483,10 @@ const datasetView = () => this.clearSearchTagText() }, gotoHome() { + console.debug( + "%c> USER INPUT: home selected", + "color: white; font-style: italic; background-color: blue", + ); // if there is NO home page set: // - if there is a tab name in the URL, navigate to current // - else: don't navigate, only "reset" @@ -473,12 +506,16 @@ const datasetView = () => if (!this.catalogHasHome()) { this.clearFilters(); this.tabIndex = this.getDefaultTabIdx(); - this.updateURLQueryString(this.$route, this.tabIndex) + // Note: no need to call updateURLQueryString() here because a change to + // this.tabIndex will automatically call newTabActivated() (because of + // v-model="tabIndex"), which in turn calls updateURLQueryString(). } else { if (this.currentIsHome()) { this.clearFilters(); this.tabIndex = this.getDefaultTabIdx(); - this.updateURLQueryString(this.$route, this.tabIndex) + // Note: no need to call updateURLQueryString() here because a change to + // this.tabIndex will automatically call newTabActivated() (because of + // v-model="tabIndex"), which in turn calls updateURLQueryString(). } else { router.push({ name: "home" }); } @@ -656,6 +693,13 @@ const datasetView = () => var idx = this.selectedDataset.available_tabs.indexOf(default_tab.toLowerCase()) return idx >= 0 ? idx : 0 }, + clickBackButton() { + console.debug( + "%c> USER INPUT: backbutton clicked", + "color: white; font-style: italic; background-color: blue", + ); + history.back() + }, }, async beforeRouteUpdate(to, from, next) { console.debug("Executing navigation guard: beforeRouteUpdate") @@ -680,7 +724,7 @@ const datasetView = () => params: route_params, query: to.query, } - router.replace(replace_route_info) + await router.replace(replace_route_info) return; } this.$root.selectedDataset = JSON.parse(text); @@ -783,9 +827,9 @@ const datasetView = () => this.$root.selectedDataset.has_files = false; } // Now list all tabs and set the correct one - // order in DOM: content, subdatasets, publications, funding, provenance, + // order in DOM: content, datasets, publications, funding, provenance, sDs = this.$root.selectedDataset - available_tabs = ['content', 'subdatasets'] + available_tabs = ['content', 'datasets'] standard_tabs = ['publications', 'funding', 'provenance'] // add available standard tabs for (var t=0; t this.$root.selectedDataset.config?.dataset_options?.default_tab ) this.dataset_ready = true; + console.debug("Finished navigation guard: beforeRouteUpdate") next(); }, async created() { @@ -869,7 +914,7 @@ const datasetView = () => params: route_params, query: this.$route.query, } - router.replace(replace_route_info) + await router.replace(replace_route_info) return; } app.selectedDataset = JSON.parse(text); @@ -937,9 +982,9 @@ const datasetView = () => this.$root.selectedDataset.has_files = false; } // Now list all tabs and set the correct one - // order in DOM: content, subdatasets, publications, funding, provenance, + // order in DOM: content, datasets, publications, funding, provenance, sDs = this.$root.selectedDataset - available_tabs = ['content', 'subdatasets'] + available_tabs = ['content', 'datasets'] standard_tabs = ['publications', 'funding', 'provenance'] // add available standard tabs for (var t=0; t config = JSON.parse(configtext); this.$root.selectedDataset.config = config; } + // --- + // Note for future: Handle route query parameters (tab and keyword) here? + // --- + // This point in the code is reached from an explicit URL navigation to a dataset + // (via home and/or via alias and/or via dataset-id, or directly to a dataset-version. + // This means that explicit query parameters will be in the $route object. + // (Note: when the same point is reached in the beforeRouteUpdate function, + // it means that navigation happened from within the catalog (i.e. not explicitly / externally) + // This means a new dataset page will be opened from the content tab or from the datasets tab of + // the dataset that is being navigated away from. This means we do not want keyword or tab parameters to pass through. correct_tab = this.$route.query.hasOwnProperty("tab") ? this.$route.query.tab : null this.setCorrectTab( correct_tab, @@ -973,11 +1028,13 @@ const datasetView = () => this.$root.selectedDataset.config?.dataset_options?.default_tab ) this.dataset_ready = true; + console.debug("Finished lifecycle hook: created") }, mounted() { console.debug("Executing lifecycle hook: mounted") this.tag_options_filtered = this.tag_options; this.tag_options_available = this.tag_options; + console.debug("Finished lifecycle hook: mounted") } } }) \ No newline at end of file diff --git a/datalad_catalog/catalog/assets/app_router.js b/datalad_catalog/catalog/assets/app_router.js index c0b34173..e1aa65e9 100644 --- a/datalad_catalog/catalog/assets/app_router.js +++ b/datalad_catalog/catalog/assets/app_router.js @@ -8,6 +8,7 @@ const routes = [ path: "/", name: "home", beforeEnter: (to, from, next) => { + console.debug("Executing navigation guard: beforeEnter - route '/')") const superfile = metadata_dir + "/super.json"; // https://www.dummies.com/programming/php/using-xmlhttprequest-class-properties/ var rawFile = new XMLHttpRequest(); diff --git a/datalad_catalog/catalog/templates/dataset-template.html b/datalad_catalog/catalog/templates/dataset-template.html index ac3c4223..8eeee524 100644 --- a/datalad_catalog/catalog/templates/dataset-template.html +++ b/datalad_catalog/catalog/templates/dataset-template.html @@ -9,7 +9,7 @@ - +
@@ -191,7 +191,7 @@

Dataset not found

- + From 17b89554ad70d8c046ec8f0aaca4caee6b874773 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Thu, 18 Apr 2024 08:37:24 +0200 Subject: [PATCH 16/18] remove dataset version from alias redirect dictionary --- tools/create_alias_concept_metadata.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/create_alias_concept_metadata.py b/tools/create_alias_concept_metadata.py index 59edd452..e8b3e09a 100644 --- a/tools/create_alias_concept_metadata.py +++ b/tools/create_alias_concept_metadata.py @@ -51,7 +51,7 @@ def create_metadata_files(catalog): key=lambda d: d.get("updated_at"), reverse=True, ) - # Dict for metadata + # Dict for id concept metadata redirect_dict = { "type": "redirect", "dataset_id": d, @@ -64,7 +64,11 @@ def create_metadata_files(catalog): dataset_concept_path.parent.mkdir(parents=True, exist_ok=True) with open(dataset_concept_path, "w") as f: json.dump(redirect_dict, f) - + # Dict for alias metadata + redirect_dict = { + "type": "redirect", + "dataset_id": d, + } # Create alias metadata dataset_alias_path = ( catalog.metadata_path From bcb6d7dc087f130bfe8fa1d7e126116dd2f98f7a Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Fri, 26 Apr 2024 10:38:06 +0200 Subject: [PATCH 17/18] Add share button that allows copying all viable dataset urls --- .../catalog/assets/app_component_dataset.js | 32 ++++++++++ .../catalog/templates/dataset-template.html | 63 ++++++++++++++++++- 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/datalad_catalog/catalog/assets/app_component_dataset.js b/datalad_catalog/catalog/assets/app_component_dataset.js index 8328c471..17cc78ba 100644 --- a/datalad_catalog/catalog/assets/app_component_dataset.js +++ b/datalad_catalog/catalog/assets/app_component_dataset.js @@ -14,6 +14,9 @@ const datasetView = () => dataPath: [], showCopyTooltip: false, showCopyCiteTooltip: false, + showCopyDatasetAliasTooltip: false, + showCopyDatasetIdTooltip: false, + showCopyDatasetFullTooltip: false, tabIndex: 0, sort_name: true, sort_modified: true, @@ -408,6 +411,35 @@ const datasetView = () => this.showCopyTooltip = false; }, 1000); }, + copyDatasetURL(url_type) { + // https://stackoverflow.com/questions/60581285/execcommand-is-now-obsolete-whats-the-alternative + // https://www.sitepoint.com/clipboard-api/ + urlmap = { + 'alias': "showCopyDatasetAliasTooltip", + 'id': "showCopyDatasetIdTooltip", + 'full': "showCopyDatasetFullTooltip", + } + selectText = document.getElementById(url_type + "_url").textContent; + selectText = '\n ' + selectText + ' \n\n ' + selectText = selectText.replace(/^\s+|\s+$/g, ''); + navigator.clipboard + .writeText(selectText) + .then(() => {}) + .catch((error) => { + alert(`Copy failed! ${error}`); + }); + this[urlmap[url_type]] = true; + }, + hideURLTooltipLater(url_type) { + setTimeout(() => { + urlmap = { + 'alias': "showCopyDatasetAliasTooltip", + 'id': "showCopyDatasetIdTooltip", + 'full': "showCopyDatasetFullTooltip", + } + this[urlmap[url_type]] = false; + }, 1000); + }, copyCitationText(index) { // https://stackoverflow.com/questions/60581285/execcommand-is-now-obsolete-whats-the-alternative // https://www.sitepoint.com/clipboard-api/ diff --git a/datalad_catalog/catalog/templates/dataset-template.html b/datalad_catalog/catalog/templates/dataset-template.html index 8eeee524..42c1dddd 100644 --- a/datalad_catalog/catalog/templates/dataset-template.html +++ b/datalad_catalog/catalog/templates/dataset-template.html @@ -40,9 +40,10 @@ View on GitHub  View on GIN  Cite  - Export metadata  + Export metadata  binder_logoExplore with Binder + alt="binder_logo" height="14em" class="mb-1">Explore with Binder  + Share  Request access  Request access @@ -123,6 +124,64 @@

Cite dataset

Invalid DOI
+ + + +
Alias URL
+
+ + + + + {{window.location.origin + '/dataset/' + selectedDataset.alias}} + + + + + + + + +
+
+
ID URL
+
+ + + + {{window.location.origin + '/dataset/' + selectedDataset.dataset_id}} + + + + + + + + +
+
Full URL
+
+ + + + {{window.location.origin + 'dataset/' + selectedDataset.dataset_id + '/' + selectedDataset.dataset_version}} + + + + + + + + +
+

From 3f3963d07415209457f53c4342deb620adf5dbd2 Mon Sep 17 00:00:00 2001 From: Stephan Heunis Date: Sat, 27 Apr 2024 18:46:46 +0200 Subject: [PATCH 18/18] Hide the 'ID URL' from share modal if the id path does not exist --- .../catalog/assets/app_component_dataset.js | 13 +++++++- .../catalog/templates/dataset-template.html | 32 ++++++++++--------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/datalad_catalog/catalog/assets/app_component_dataset.js b/datalad_catalog/catalog/assets/app_component_dataset.js index 17cc78ba..a198f7b2 100644 --- a/datalad_catalog/catalog/assets/app_component_dataset.js +++ b/datalad_catalog/catalog/assets/app_component_dataset.js @@ -266,10 +266,21 @@ const datasetView = () => } scripttag.textContent = JSON.stringify(obj); + dataset_id_path = getFilePath(this.selectedDataset.dataset_id) + fetch(dataset_id_path) + .then((response) => { + if(response.status == 404) { + this.selectedDataset.has_id_path = false + } else { + this.selectedDataset.has_id_path = true + } + }) + .catch(error => { + // do nothing + }) // Write main derived variable and set to ready this.displayData = disp_dataset; this.display_ready = true; - console.debug("Watched property function completed: dataset_ready = true") } }, diff --git a/datalad_catalog/catalog/templates/dataset-template.html b/datalad_catalog/catalog/templates/dataset-template.html index 42c1dddd..d9f53c63 100644 --- a/datalad_catalog/catalog/templates/dataset-template.html +++ b/datalad_catalog/catalog/templates/dataset-template.html @@ -151,21 +151,23 @@
Alias URL
-
ID URL
-
- - - - {{window.location.origin + '/dataset/' + selectedDataset.dataset_id}} - - - - - - - - -
+ +
ID URL
+
+ + + + {{window.location.origin + '/dataset/' + selectedDataset.dataset_id}} + + + + + + + + +
+
Full URL