Skip to content

Commit

Permalink
apply catalog updates from upstream main
Browse files Browse the repository at this point in the history
  • Loading branch information
jsheunis committed May 28, 2024
1 parent eb426b8 commit a3402a1
Show file tree
Hide file tree
Showing 7 changed files with 240 additions and 52 deletions.
4 changes: 3 additions & 1 deletion catalog/assets/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var datacat = new Vue({
links: {},
dataset_options: {},
config_ready: false,
catalog_config: {},
},
methods: {
gotoHome() {
Expand All @@ -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();
Expand All @@ -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
Expand Down
190 changes: 175 additions & 15 deletions catalog/assets/app_component_dataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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<keys_to_populate.length; k++) {
key = keys_to_populate[k]
obj[key] = this.getRichData(key, dataset, disp_dataset)
}

scripttag.textContent = JSON.stringify(pruneObject(obj));

dataset_id_path = getFilePath(this.selectedDataset.dataset_id)
fetch(dataset_id_path)
fetch(dataset_id_path, {cache: "no-cache"})
.then((response) => {
if(response.status == 404) {
this.selectedDataset.has_id_path = false
Expand Down Expand Up @@ -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<selectedDS.additional_display.length; t++) {
var current_display = selectedDS.additional_display[t]
var homepage = current_display.content?.homepage?.["@value"]
if (homepage) {
return homepage
}
}
} else {
return null
}
// "spatialCoverage", // Text or Place
// "temporalCoverage", // Text
// "variableMeasured", // Text or PropertyValue
case "version":
return selectedDS.dataset_version
// "url", // URL
case "includedInDataCatalog":
var obj = {
"@type":"DataCatalog",
"name": this.$root.catalog_config?.catalog_name ? this.$root.catalog_config.catalog_name : null,
"url": this.$root.catalog_config?.catalog_url ? this.$root.catalog_config.catalog_url : null,
}
if (obj.name == null && obj.url == null) {
return null
} else {
return obj
}
// "distribution", // DataDownload
default:
return null
}
},
getAuthorORCID(author) {
if (author.hasOwnProperty("identifiers") && author.identifiers.length > 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<common_funders.length; i++) {
var cf = common_funders[i]
if (fund.funder?.indexOf(cf.name) >= 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/
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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"];
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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;
Expand All @@ -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({
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -1080,4 +1240,4 @@ const datasetView = () =>
console.debug("Finished lifecycle hook: mounted")
}
}
})
})
2 changes: 1 addition & 1 deletion catalog/assets/app_component_item.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
30 changes: 27 additions & 3 deletions catalog/assets/app_globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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);
Expand Down Expand Up @@ -101,4 +102,27 @@ async function checkFileExists(url) {
} catch (error) {
return false;
}
}
}

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;
}

Loading

0 comments on commit a3402a1

Please sign in to comment.