diff --git a/catalog/assets/app.js b/catalog/assets/app.js index a3be452..e4a0d05 100644 --- a/catalog/assets/app.js +++ b/catalog/assets/app.js @@ -11,6 +11,7 @@ var datacat = new Vue({ links: {}, dataset_options: {}, config_ready: false, + catalog_config: {}, }, methods: { gotoHome() { @@ -25,7 +26,7 @@ var datacat = new Vue({ }, beforeCreate() { console.debug("Executing lifecycle hook: beforeCreate") - fetch(config_file) + fetch(config_file, {cache: "no-cache"}) .then((response) => { if (response.ok) { return response.json(); @@ -45,6 +46,7 @@ var datacat = new Vue({ obj[key] = value; } } + this.catalog_config = obj // set social links this.social_links = obj.social_links // set dataset options diff --git a/catalog/assets/app_component_dataset.js b/catalog/assets/app_component_dataset.js index a198f7b..38a16f5 100644 --- a/catalog/assets/app_component_dataset.js +++ b/catalog/assets/app_component_dataset.js @@ -225,7 +225,7 @@ const datasetView = () => } // Show / hide binder button: if disp_dataset.url exists OR if dataset has a notebook specified in metadata disp_dataset.show_binder_button = false - if ( disp_dataset.url || dataset.hasOwnProperty("notebooks") && current_dataset.notebooks.length > 0 ) { + if ( disp_dataset.url || disp_dataset.hasOwnProperty("notebooks") && disp_dataset.notebooks.length > 0 ) { disp_dataset.show_binder_button = true } @@ -258,16 +258,42 @@ const datasetView = () => scripttag.setAttribute("id", "structured-data"); document.head.appendChild(scripttag); } + keys_to_populate = [ + "name", // Text + "description", // Text + "alternateName", // Text + "creator", // Person or Organization + "citation", // Text or CreativeWork + "funder", // Person or Organization + "hasPart", // URL or Dataset + // "isPartOf", // URL or Dataset + "identifier", // URL, Text, or PropertyValue + // "isAccessibleForFree", // Boolean + "keywords", // Text + "license", // URL or CreativeWork + // "measurementTechnique", // Text or URL + "sameAs", // URL + // "spatialCoverage", // Text or Place + // "temporalCoverage", // Text + // "variableMeasured", // Text or PropertyValue + "version", // Text or Number + // "url", // URL + "includedInDataCatalog", // DataCatalog + // "distribution", // DataDownload + ] obj = { "@context": "https://schema.org/", "@type": "Dataset", - "name": this.displayData.display_name ? this.displayData.display_name : "", - "description": this.selectedDataset.description ? this.selectedDataset.description : "" } - scripttag.textContent = JSON.stringify(obj); + for (var k=0; k { if(response.status == 404) { this.selectedDataset.has_id_path = false @@ -403,6 +429,140 @@ const datasetView = () => let url_qp2 = new URL(document.location.toString()).searchParams console.debug("- After: URL query string: %s", url_qp2.toString()) }, + getRichData(key, selectedDS, displayDS) { + switch (key) { + case "name": + return displayDS.display_name ? displayDS.display_name : "" + case "description": + return selectedDS.description ? selectedDS.description : "" + case "alternateName": + // use alias if present + return [selectedDS.alias ? selectedDS.alias : ""] + case "creator": + // authors + return selectedDS.authors?.map( (auth) => { + return { + "@type": "Person", + "givenName": auth.givenName ? auth.givenName : null, + "familyName": auth.familyName ? auth.familyName : null, + "name": auth.name ? auth.name : null, + "sameAs": this.getAuthorORCID(auth), + } + }) + case "citation": + // from publications + return selectedDS.publications?.map( (pub) => { + return pub.doi + }) + case "funder": + // from funding + return selectedDS.funding?.map( (fund) => { + var fund_obj = { + "@type": "Organization", + "name": fund.funder ? fund.funder : (fund.name ? fund.name : (fund.description ? fund.description : null)), + } + var sameas = this.getFunderSameAs(fund) + if (sameas) { + fund_obj["sameAs"] = sameas + } + return fund_obj + }) + case "hasPart": + // from subdatasets + var parts = selectedDS.subdatasets?.map( (ds) => { + return { + "@type": "Dataset", + "name": ds.dirs_from_path[ds.dirs_from_path.length - 1] + } + }) + return parts.length ? parts : null + // case "isPartOf": + case "identifier": + // use DOI + return selectedDS.doi ? selectedDS.doi : null + // "isAccessibleForFree", // Boolean + case "keywords": + return selectedDS.keywords?.length ? selectedDS.keywords : null + case "license": + return selectedDS.license?.url ? selectedDS.license.url : null + // "measurementTechnique", // Text or URL + case "sameAs": + // homepage + if (selectedDS.additional_display && selectedDS.additional_display.length) { + for (var t=0; t 0) { + orcid_element = author.identifiers.filter( + (x) => x.name === "ORCID" + ); + if (orcid_element.length > 0) { + orcid_code = orcid_element[0].identifier + const prefix = "https://orcid.org/" + return orcid_code.indexOf(prefix) >= 0 ? orcid_code : prefix + orcid_code + } else { + return null + } + } else { + return null + } + }, + getFunderSameAs(fund) { + const common_funders = [ + { + "name": "Deutsche Forschungsgemeinschaft", + "alternate_name": "DFG", + "ror": "https://ror.org/018mejw64" + }, + { + "name": "National Science Foundation", + "alternate_name": "NSF", + "ror": "https://ror.org/021nxhr62" + } + ] + for (var i=0; i= 0 || + fund.name?.indexOf(cf.name) >= 0 || + fund.description?.indexOf(cf.name) >= 0 || + fund.funder?.indexOf(cf.alternate_name) >= 0 || + fund.name?.indexOf(cf.alternate_name) >= 0 || + fund.description?.indexOf(cf.alternate_name) >= 0 ) { + return cf.ror + } + } + return null + }, copyCloneCommand(index) { // https://stackoverflow.com/questions/60581285/execcommand-is-now-obsolete-whats-the-alternative // https://www.sitepoint.com/clipboard-api/ @@ -596,9 +756,9 @@ const datasetView = () => openWithBinder(dataset_url, current_dataset) { const environment_url = "https://mybinder.org/v2/gh/datalad/datalad-binder/main"; - const content_url = "https://github.com/jsheunis/datalad-notebooks"; - const content_repo_name = "datalad-notebooks"; - const notebook_name = "download_data_with_datalad_python.ipynb"; + var content_url = "https://github.com/jsheunis/datalad-notebooks"; + var content_repo_name = "datalad-notebooks"; + var notebook_name = "download_data_with_datalad_python.ipynb"; if (current_dataset.hasOwnProperty("notebooks") && current_dataset.notebooks.length > 0) { // until including the functionality to select from multiple notebooks in a dropdown, just select the first one notebook = current_dataset.notebooks[0] @@ -679,7 +839,7 @@ const datasetView = () => this.files_ready = false; file_hash = this.selectedDataset.children; file = metadata_dir + "/" + file_hash + ".json"; - response = await fetch(file); + response = await fetch(file, {cache: "no-cache"}); text = await response.text(); obj = JSON.parse(text); this.$root.selectedDataset.tree = obj["children"]; @@ -749,7 +909,7 @@ const datasetView = () => this.subdatasets_ready = false; this.dataset_ready = false; file = getFilePath(to.params.dataset_id, to.params.dataset_version, null); - response = await fetch(file); + response = await fetch(file, {cache: "no-cache"}); 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 @@ -891,7 +1051,7 @@ const datasetView = () => this.$root.selectedDataset.available_tabs = available_tabs_lower // Now get dataset config if it exists dataset_config_path = metadata_dir + "/" + sDs.dataset_id + "/" + sDs.dataset_version + "/config.json"; - configresponse = await fetch(dataset_config_path); + configresponse = await fetch(dataset_config_path, {cache: "no-cache"}); if (configresponse.status == 404) { this.$root.selectedDataset.config = {}; } else { @@ -916,7 +1076,7 @@ const datasetView = () => console.debug("Executing lifecycle hook: created") // fetch superfile in order to set id and version on $root homefile = metadata_dir + "/super.json"; - homeresponse = await fetch(homefile); + homeresponse = await fetch(homefile, {cache: "no-cache"}); if (homeresponse.status == 404) { this.$root.home_dataset_id = null; this.$root.home_dataset_version = null; @@ -932,7 +1092,7 @@ const datasetView = () => null ); var app = this.$root; - response = await fetch(file); + response = await fetch(file, {cache: "no-cache"}); // Reroute to 404 if the dataset file is not found if (response.status == 404) { router.push({ @@ -1046,7 +1206,7 @@ const datasetView = () => this.$root.selectedDataset.available_tabs = available_tabs_lower // Now get dataset config if it exists dataset_config_path = metadata_dir + "/" + sDs.dataset_id + "/" + sDs.dataset_version + "/config.json"; - configresponse = await fetch(dataset_config_path); + configresponse = await fetch(dataset_config_path, {cache: "no-cache"}); if (configresponse.status == 404) { this.$root.selectedDataset.config = {}; } else { @@ -1080,4 +1240,4 @@ const datasetView = () => console.debug("Finished lifecycle hook: mounted") } } - }) \ No newline at end of file + }) diff --git a/catalog/assets/app_component_item.js b/catalog/assets/app_component_item.js index dea66b5..57002f1 100644 --- a/catalog/assets/app_component_item.js +++ b/catalog/assets/app_component_item.js @@ -119,7 +119,7 @@ Vue.component('tree-item', function (resolve, reject) { obj.dataset_version = this.$root.selectedDataset.dataset_version; file = getFilePath(obj.dataset_id, obj.dataset_version, obj.path); try { - response = await fetch(file); + response = await fetch(file, {cache: "no-cache"}); text = await response.text(); } catch (error) { console.error(error); diff --git a/catalog/assets/app_globals.js b/catalog/assets/app_globals.js index 648f20a..228df91 100644 --- a/catalog/assets/app_globals.js +++ b/catalog/assets/app_globals.js @@ -9,7 +9,8 @@ const superdatasets_file = metadata_dir + "/super.json"; const SPLIT_INDEX = 3; const SHORT_NAME_LENGTH = 0; // number of characters in name to display, zero if all const default_config = { - catalog_name: "DataCat", + catalog_name: "DataCat Demo", + catalog_url: "https://datalad-catalog.netlify.app/", link_color: "#fba304", link_hover_color: "#af7714", logo_path: "/artwork/catalog_logo.svg", @@ -36,7 +37,7 @@ async function grabSubDatasets(app) { id_and_version = subds.dataset_id + "-" + subds.dataset_version; subds_file = getFilePath(subds.dataset_id, subds.dataset_version, null); try { - subds_response = await fetch(subds_file); + subds_response = await fetch(subds_file, {cache: "no-cache"}); subds_text = await subds_response.text(); } catch (e) { console.error(e); @@ -101,4 +102,27 @@ async function checkFileExists(url) { } catch (error) { return false; } -} \ No newline at end of file +} + +function pruneObject(obj) { + const newObj = {}; + Object.entries(obj).forEach(([k, v]) => { + if (typeof v === 'object' && !Array.isArray(v) && v !== null) { + newObj[k] = pruneObject(v); + } else if ((v instanceof Array || Array.isArray(v)) && v.length > 0) { + newArr = [] + for (const el of v) { + if (typeof el === 'object' && !Array.isArray(el) && el !== null) { + newArr.push(pruneObject(el)) + } else if (el != null) { + newArr.push(el) + } + } + newObj[k] = newArr; + } else if (v != null) { + newObj[k] = obj[k]; + } + }); + return newObj; +} + diff --git a/catalog/assets/app_router.js b/catalog/assets/app_router.js index e1aa65e..0271110 100644 --- a/catalog/assets/app_router.js +++ b/catalog/assets/app_router.js @@ -10,31 +10,28 @@ const routes = [ 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(); - rawFile.onreadystatechange = function () { - if (rawFile.readyState === 4) { - if (rawFile.status === 200 || rawFile.status == 0) { - var allText = rawFile.responseText; - superds = JSON.parse(allText); - router.push({ - name: "dataset", - params: { - dataset_id: superds["dataset_id"], - dataset_version: superds["dataset_version"], - }, - query: to.query, - }); - next(); - } else if (rawFile.status === 404) { - router.push({ name: "404" }); - } else { - // TODO: figure out what to do here - } + fetch(superfile, {cache: "no-cache"}) + .then((response) => { + if(response.status == 404) { + router.push({ name: "404" }); + next(); } - }; - rawFile.open("GET", superfile, false); - rawFile.send(); + return response.text() + }).then((text) => { + superds = JSON.parse(text); + router.push({ + name: "dataset", + params: { + dataset_id: superds["dataset_id"], + dataset_version: superds["dataset_version"], + }, + query: to.query, + }); + next(); + }) + .catch(error => { + console.error(error) + }) }, }, { diff --git a/catalog/index.html b/catalog/index.html index 2c05c7f..989b00e 100644 --- a/catalog/index.html +++ b/catalog/index.html @@ -5,6 +5,10 @@ + + + + diff --git a/catalog/templates/dataset-template.html b/catalog/templates/dataset-template.html index d9f53c6..8928340 100644 --- a/catalog/templates/dataset-template.html +++ b/catalog/templates/dataset-template.html @@ -461,7 +461,7 @@
{{fund.name}}(fund name not s - +