diff --git a/api/src/Authentication/Type/OIDC.php b/api/src/Authentication/Type/OIDC.php index ecda25e9c..ff538d58d 100644 --- a/api/src/Authentication/Type/OIDC.php +++ b/api/src/Authentication/Type/OIDC.php @@ -44,9 +44,9 @@ private function getUser($token) global $sso_user_key; $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $this->getProviderConfig()->userinfo_endpoint); - curl_setopt($ch, CURLOPT_HEADER, 0); - curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $token)); + curl_setopt($ch, CURLOPT_URL, $this->getProviderConfig()->introspection_endpoint); + curl_setopt($ch, CURLOPT_POSTFIELDS, array('token' => $token)); + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Basic ' . $this->getProviderConfig()->b64ClientCreds)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $response = curl_exec($ch); curl_close($ch); diff --git a/api/src/Page/Process.php b/api/src/Page/Process.php index c44c1c18a..ebead1c4d 100644 --- a/api/src/Page/Process.php +++ b/api/src/Page/Process.php @@ -12,7 +12,7 @@ class Process extends Page 'PROCESSINGJOBID' => '\d+', 'DATACOLLECTIONID' => '\d+', 'SCALINGID' => '\d+', - 'DISPLAYNAME' => '([\w\s\-])+', + 'DISPLAYNAME' => '[\w\s\-.\(\)\=]+', 'COMMENTS' => '.*', 'PROCESSINGJOBIMAGESWEEPID' => '\d+', diff --git a/client/src/js/modules/dc/views/autointegration.js b/client/src/js/modules/dc/views/autointegration.js index 36e63df8f..dfcca1729 100644 --- a/client/src/js/modules/dc/views/autointegration.js +++ b/client/src/js/modules/dc/views/autointegration.js @@ -9,6 +9,7 @@ define(['marionette', 'modules/dc/views/autoprocattachments', 'modules/dc/views/apmessages', 'modules/dc/views/downstreamreprocess', + 'modules/dc/views/multiplexreprocess.js', 'views/log', 'views/table', @@ -17,7 +18,7 @@ define(['marionette', 'templates/dc/dc_autoproc.html'], function(Marionette, Backbone, Backgrid, TabView, AutoProcAttachments, AutoIntegrations, RDPlotView, AIPlotsView, AutoProcAttachmentsView, APMessagesView, - DownstreamView, + DownstreamView, MultiplexView, LogView, TableView, table, utils, template) { @@ -34,6 +35,11 @@ define(['marionette', 'click a.apattach': 'showAttachments', 'click a.downstream': 'downstream', 'click .dll': utils.signHandler, + 'click @ui.multiplex': 'multiplexReprocessing', + }, + + ui: { + multiplex: '.multiplex', }, regions: { @@ -42,6 +48,15 @@ define(['marionette', onRender: function() { this.messages.show(new APMessagesView({ messages: new Backbone.Collection(this.model.get('MESSAGES')), embed: true })) + if (this.model.get('TYPE').toLowerCase().includes('cluster') || !this.model.get('TYPE').toLowerCase().includes('multiplex')) { + this.ui.multiplex.hide() + } + }, + + multiplexReprocessing: function(e) { + if (e) e.preventDefault() + app.dialog.show(new MultiplexView({ model: this.getOption('templateHelpers').PARENT, scalingid: this.model.get('SCALINGID'), type: this.model.get('TYPE')})) + }, showAttachments: function(e) { diff --git a/client/src/js/modules/dc/views/multiplexreprocess.js b/client/src/js/modules/dc/views/multiplexreprocess.js new file mode 100644 index 000000000..f697bca42 --- /dev/null +++ b/client/src/js/modules/dc/views/multiplexreprocess.js @@ -0,0 +1,213 @@ +define(['backbone', 'marionette', 'views/dialog', + 'collections/spacegroups', + 'models/reprocessing', + 'models/reprocessingparameter', + 'collections/reprocessingparameters', + 'utils/kvcollection', + 'templates/dc/multiplex.html' +], function(Backbone, Marionette, DialogView, + Spacegroups, + Reprocessing, + ReprocessingParameter, + ReprocessingParameters, + KVCollection, + template + ) { + + const FilteringMethods = Backbone.Collection.extend(_.extend({ + keyAttribute: 'NAME', + valueAttribute: 'VALUE', + }, KVCollection)) + + return ReprocessView = DialogView.extend({ + template: template, + dialog: true, + className: 'rp content', + dOptions: { + width: '1000px', + }, + + ui: { + fields: 'input, select', + sg: 'select[name=sg]', + res: 'input[name=res]', + opts: 'div.options', + filteringMethod: 'select[name=method]', + sdcutoff: 'input[name=sdcutoff]', + cchalf: 'input[name=cchalf]', + groupsize: 'input[name=groupsize]', + }, + + buttons: { + Submit: 'submit', + Close: 'closeDialog', + }, + + events: { + 'input @ui.fields': 'onFieldChanged', + 'change @ui.fields': 'onFieldChanged', + 'click a.opt': 'toggleOpts', + 'change @ui.cchalf': 'updateCCHalf', + 'change @ui.filteringMethod': 'updateFilteringMethod', + }, + + templateHelpers: function() { + return { + TYPE: this.getOption('type') + } + }, + + toggleOpts: function(e) { + e.preventDefault() + this.ui.opts.slideToggle() + }, + + updateCCHalf: function() { + const enabled = this.ui.cchalf.is(':checked') + if (enabled) { + this.ui.filteringMethod.prop('disabled', false).val('image_group') + this.ui.sdcutoff.prop('disabled', false) + this.ui.groupsize.prop('disabled', false) + } else { + this.ui.sdcutoff.prop('disabled', true).val('') + this.ui.filteringMethod.prop('disabled', true).val('') + this.ui.groupsize.prop('disabled', true).val('') + } + }, + + updateFilteringMethod: function() { + const val = this.ui.filteringMethod.val() + if (val === 'dataset') { + this.ui.groupsize.prop('disabled', true).val('') + } else { + this.ui.groupsize.prop('disabled', false) + } + }, + + submit: async function(e) { + e.preventDefault() + this._disableSubmitButton() + const reprocessing = new Reprocessing({ + DATACOLLECTIONID: this.model.get('ID'), + RECIPE: 'trigger-multiplex', + DISPLAYNAME: this.type, + }) + + try { + await reprocessing.save() + const jobId = reprocessing.get('PROCESSINGJOBID') + const reprocessingparams = new ReprocessingParameters() + + reprocessingparams.add(new ReprocessingParameter({ + PROCESSINGJOBID: jobId, + PARAMETERKEY: 'scaling_id', + PARAMETERVALUE: this.scalingid + })); + + const res = this.ui.res.val() + if (res) reprocessingparams.add(new ReprocessingParameter({ + PROCESSINGJOBID: jobId, + PARAMETERKEY: 'd_min', + PARAMETERVALUE: res + })) + + const sg = this.ui.sg.val().replace(/\s/g, '') + if (sg) reprocessingparams.add(new ReprocessingParameter({ + PROCESSINGJOBID: jobId, + PARAMETERKEY: 'spacegroup', + PARAMETERVALUE: sg + })) + + const cchalf = this.ui.cchalf.prop('checked') + if (cchalf) reprocessingparams.add(new ReprocessingParameter({ + PROCESSINGJOBID: jobId, + PARAMETERKEY: 'apply_cchalf_filtering', + PARAMETERVALUE: 1 + })) + + const method = this.ui.filteringMethod.val() + if (method) reprocessingparams.add(new ReprocessingParameter({ + PROCESSINGJOBID: jobId, + PARAMETERKEY: 'cchalf_filtering_method', + PARAMETERVALUE: method + })) + + const sdcutoff = this.ui.sdcutoff.val() + if (sdcutoff) reprocessingparams.add(new ReprocessingParameter({ + PROCESSINGJOBID: jobId, + PARAMETERKEY: 'sd_cutoff', + PARAMETERVALUE: sdcutoff + })) + + const groupsize = this.ui.groupsize.val() + if (groupsize) reprocessingparams.add(new ReprocessingParameter({ + PROCESSINGJOBID: jobId, + PARAMETERKEY: 'image_group_size', + PARAMETERVALUE: groupsize + })) + + await reprocessingparams.save() + this._enqueue({ PROCESSINGJOBID: reprocessing.get('PROCESSINGJOBID') }) + app.message({ message: 'Multiplex reprocessing job successfully submitted'}) + + } catch { + app.alert({ message: 'Something went wrong starting that reprocessing run' }) + } + + }, + + onFieldChanged: function() { + this._enableSubmitButton(); + }, + + _disableSubmitButton: function() { + var btn = $('.ui-dialog-buttonpane button:contains("Submit")') + btn.addClass('submitted').button('disable').button('option', 'label', 'Submitted!') + this.resetTimeout = setTimeout(() => { + this._enableSubmitButton() + }, 5000) + }, + + _enableSubmitButton: function() { + var btn = $('.ui-dialog-buttonpane button.submitted') + btn.removeClass('submitted').button('enable').button('option', 'label', 'Submit') + clearTimeout(this.resetTimeout); + }, + + _enqueue: function(options) { + Backbone.ajax({ + url: app.apiurl+'/process/enqueue', + method: 'POST', + data: { + PROCESSINGJOBID: options.PROCESSINGJOBID, + }, + }) + }, + + initialize: function(options) { + this.scalingid = options.scalingid + this.type = options.type + this.title = 'Rerun multiplex processing - ' + this.type + this.filteringMethods = new FilteringMethods([ + { NAME: 'image_group', VALUE: 'image_group' }, + { NAME: 'dataset', VALUE: 'dataset' }, + ]) + this.spacegroups = new Spacegroups(null, { state: { pageSize: 9999 } }) + this.listenTo(this.spacegroups, 'sync', this.populateSpacegroups) + this.spacegroups.fetch() + }, + + onRender: function() { + this.ui.opts.hide() + this.ui.filteringMethod.html(this.filteringMethods.opts()) + this.ui.filteringMethod.prop('disabled', true).val('') + this.ui.sdcutoff.prop('disabled', true) + this.ui.groupsize.prop('disabled', true) + }, + + populateSpacegroups: function() { + this.ui.sg.html(''+this.spacegroups.opts()) + } + + }) +}) diff --git a/client/src/js/templates/dc/dc_autoproc.html b/client/src/js/templates/dc/dc_autoproc.html index 493f3781d..c9677ba62 100644 --- a/client/src/js/templates/dc/dc_autoproc.html +++ b/client/src/js/templates/dc/dc_autoproc.html @@ -13,6 +13,7 @@ <% } else { %>

+ Multiplex Reprocessing <% if (IMAGESWEEPCOUNT > 1) { %> <%=IMAGESWEEPCOUNT%> image sweeps <% } %> diff --git a/client/src/js/templates/dc/multiplex.html b/client/src/js/templates/dc/multiplex.html new file mode 100644 index 000000000..abb37cc8b --- /dev/null +++ b/client/src/js/templates/dc/multiplex.html @@ -0,0 +1,18 @@ +

+ + + High Res : Å + + Filtering Options +
+
+ +
+ +

+ + + +
+ +