Skip to content

Commit

Permalink
Add methods to auto add dataset dist'n url [WIP]
Browse files Browse the repository at this point in the history
- Add `autoAddDistributionURL` option to app model (default: false)
- add method to optionally add dataset distribution url during EML211 save event
- Add methods for finding, removing, adding, and updating distributions in EML211
- These changes need testing
- distribution URL is not yet updated during publish with DOI event

Relates to #1380
  • Loading branch information
robyngit committed Aug 1, 2023
1 parent f8ab572 commit b80f8e0
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 2 deletions.
13 changes: 13 additions & 0 deletions src/js/models/AppModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,19 @@ define(['jquery', 'underscore', 'backbone'],
*/
quickAddTaxa: [],

/**
* Whether or not documents saved in the Editor should automatically have
* the online URL of the dataset landing page added to the EML within a
* <distribution> element. The URL will be the view service for whatever
* member node is being used, or if the dataset has DOI, it should use
* doi.org. Setting this to true will also update the <distribution> url
* when the dataset is updated, or when it is published with a DOI.
* @since x.x.x
* @type {boolean}
* @default false
*/
autoAddDistributionURL: false,

/**
* The base URL for the repository. This only needs to be changed if the repository
* is hosted at a different origin than the MetacatUI origin. This URL is used to contruct all
Expand Down
87 changes: 87 additions & 0 deletions src/js/models/metadata/eml211/EML211.js
Original file line number Diff line number Diff line change
Expand Up @@ -1287,6 +1287,12 @@ define(['jquery', 'underscore', 'backbone', 'uuid',
formData.append("newPid", this.get("id"));
formData.append("pid", this.get("oldPid"));
}

// Add the distribution URL to the EML (if the repository is configured
// to do so). Only do this once the pid has been updated.
if (MetacatUI.appModel.get("autoAddDistributionURL")) {
this.addDatasetDistributionURL();
}

//Serialize the EML XML
var xml = this.serialize();
Expand Down Expand Up @@ -1430,6 +1436,87 @@ define(['jquery', 'underscore', 'backbone', 'uuid',

return Backbone.Model.prototype.save.call(this, attributes, saveOptions);
},

/**
* Adds a new EMLDistribution model to the distribution array
* @param {object} attributes - The attributes to set on the new
* EMLDistribution model
* @param {object} options - Options to pass to the new EMLDistribution
* model
*/
addDistribution: function (attributes, options) {
try {
const distributions = this.get('distribution') || [];
const newDistribution = new EMLDistribution(attributes, options);
distributions.push(newDistribution);
this.set('distribution', distributions);
} catch (e) {
console.log("Couldn't add a distribution to the EML model", e);
}
},

/**
* Find the distribution that has all of the matching attributes. This will
* return true if the distribution has all of the attributes, even if it
* has more attributes than the ones passed in.
* @param {object} attributes - The attributes to match
* @param {boolean} partialMatch - If true, then the attributes only need
* to partially match. If false, then the attributes must match exactly.
*/
findDistribution: function (attributes, partialMatch = false) {
const distributions = this.get('distribution') || [];
return distributions.find(d => {
return Object.keys(attributes).every(key => {
const val = d.get(key);
if (partialMatch) {
return val.includes(attributes[key]);
}
return val === attributes[key];
});
});
},

/**
* Make sure that the EML dataset element has a distribution node with the
* location where the data package can be viewed. This will be either the
* view URL for the member node being used or the DOI.org URL if the dataset
* has one. This method will look for the old distribution URL and update it
* if it exists, or add a new distribution node if it doesn't.
*/
addDatasetDistributionURL: function () {
const model = this;
const oldPid = this.get('oldPid');
const newPid = this.get('id');
const seriesId = this.get('seriesId');
const IDs = [oldPid, newPid, seriesId]

// Remove any distribution models with the old PID, seriesId, or current
// PID in the URL (only if the URL function is "information")
const distributions = this.get('distribution') || [];
IDs.forEach(id => {
const distributions = model.get('distribution');
if(!distributions || !distributions.length) return;
const dist = this.findDistribution(
{ url: id, urlFunction: 'information' }, true);
if (dist) {
// Remove the distribution model from the array
distributions.splice(distributions.indexOf(dist), 1);
}
});


// Add a new distribution node with the view URL
const viewURL = this.getCanonicalDOIIRI() || this.createViewURL();
if (viewURL) {
this.addDistribution({
url: viewURL,
urlFunction: 'information'
});
} else {
console.log('Could not add a distribution node with the view URL');
}

},


/*
Expand Down
45 changes: 43 additions & 2 deletions src/js/models/metadata/eml211/EMLDistribution.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,48 @@ define(["jquery", "underscore", "backbone", "models/DataONEObject"], function (
});
},

/**
* Adds a URL for an online distribution to the model. If the model already
* has offline distribution info, this method will remove all of the offline
* nodes and replace them with a <url> node when overwrite is true.
* @param {string} url - The URL to add to the model
* @param {string} urlFunction - Optional, the purpose of the URL. May be
* either "information" or "download".
* @param {boolean} overwrite - Optional, if true, will overwrite any
* existing URL or offline distribution.
*/
addURL: function (url, urlFunction = null, overwrite = false) {
if (this.hasValuesForDistributionLocation("offline") && !overwrite) {
console.log(
"Cannot add a URL to a distribution that already has an offline " +
"distribution. Create a new distribution instead, or set overwrite " +
"to true."
);
return;
}

if (!url) {
console.log("Cannot add a URL to a distribution without a URL value");
return;
}

if (this.get("url") && !overwrite) {
console.log(
"Cannot add a URL to a distribution that already has a URL. " +
"Set overwrite to true to overwrite the existing URL."
);
return;
}

this.set("url", url);
if (urlFunction) this.set("urlFunction", urlFunction);

// Remove all of the offline node values
this.offlineNodes.forEach((nodeName) => {
this.set(nodeName, null);
});
},

/*
* Makes a copy of the original XML DOM and updates it with the new values
* from the model.
Expand Down Expand Up @@ -249,7 +291,7 @@ define(["jquery", "underscore", "backbone", "models/DataONEObject"], function (

// Add the urlFunction attribute if one is set in the model. Remove it if
// it's not set.
const url = $objectDOM.find("url")
const url = $objectDOM.find("url");
if (url) {
const urlFunction = this.get("urlFunction");
if (urlFunction) {
Expand All @@ -258,7 +300,6 @@ define(["jquery", "underscore", "backbone", "models/DataONEObject"], function (
url.removeAttr("function");
}
}


return objectDOM;
},
Expand Down

0 comments on commit b80f8e0

Please sign in to comment.