diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/master-data/data-model.xls b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/master-data/data-model.xls index 3ee993ae6e5fcd4df2a656c6551274769709d661..dc41839238990f7688c5a4b4f956986f3414f318 100644 Binary files a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/master-data/data-model.xls and b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/master-data/data-model.xls differ diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/master-data/data-model.xls b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/master-data/data-model.xls index 4f80487f892ef4976e6b18b21e387ed772b85e39..21bc5da6b913898b698b337c5eaa1dd604c75b92 100644 Binary files a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/master-data/data-model.xls and b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/master-data/data-model.xls differ diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/config/Profile.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/config/Profile.js index b713b303923d04fa508d679c6db1851f4d2ce138..6027757010cb5d97163a8d04c21d03cdcbc93eae 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/config/Profile.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/config/Profile.js @@ -61,7 +61,8 @@ $.extend(DefaultProfile.prototype, { showVocabularyViewer : true, showUserManager : true, showUserProfile : true, - showResearchCollectionExportBuilder : false, + // Not fully implemented yet. + // showResearchCollectionExportBuilder : false, showZenodoExportBuilder : false, } diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/controllers/MainController.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/controllers/MainController.js index 8c6bfbcf1f2791f064a86b0aff88d215f6bd5568..4a42b1c0c13a61c3ff253c9f5535a822f8707862 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/controllers/MainController.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/controllers/MainController.js @@ -83,13 +83,35 @@ function MainController(profile) { //Functionality to keep state this.backStack = []; + + this.zenodoApiTokenKey = "personal-zenodo-api-token"; // // Validates and enters the app // - + this.enterApp = function(data, username, password) { + var _this = this; + if(data && !username && !password) { + this.openbisV1.listDataStores(function(result) { + if(result && result.error && result.error.message) { + var callback = function() {Util.unblockUI();}; + Util.showUserError(result.error.message, callback); + } else { + _this.initApp(data, username, password); + } + }); + } else { + this.initApp(data, username, password); + } + } + + this.initApp = function(data, username, password) { var localReference = this; + // + // Check + // + // // Check Credentials // diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js index 5fc84d5f807768cfcaf096ac497f5a33875fd4d8..cf273afe3bfe7883c1fbe5f6e7775c43a7243742 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/server/ServerFacade.js @@ -417,7 +417,7 @@ function ServerFacade(openbisServer) { }); }; - this.exportZenodo = function(entities, includeRoot, metadataOnly, userInformation, title, callbackFunction) { + this.exportZenodo = function(entities, includeRoot, metadataOnly, userInformation, title, accessToken, callbackFunction) { this.asyncExportZenodo({ "method": "exportAll", "includeRoot": includeRoot, @@ -427,6 +427,7 @@ function ServerFacade(openbisServer) { "originUrl": window.location.origin, "sessionToken": this.openbisServer.getSession(), "submissionTitle": title, + "accessToken": accessToken }, callbackFunction, "zenodo-exports-api"); }; @@ -451,6 +452,7 @@ function ServerFacade(openbisServer) { options.withParameter("submissionUrl", parameters["submissionUrl"]); options.withParameter("entities", parameters["entities"]); options.withParameter("submissionTitle", parameters["submissionTitle"]); + options.withParameter("accessToken", parameters["accessToken"]); options.withParameter("userId", parameters["userInformation"]["id"]); options.withParameter("userEmail", parameters["userInformation"]["email"]); options.withParameter("userFirstName", parameters["userInformation"]["firstName"]); diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SideMenu/SideMenuWidgetView.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SideMenu/SideMenuWidgetView.js index ecd57517a2c01f717c852ea89b205c396594b486..8cbb61294a164f081712b1385f5ad793adc4eb3d 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SideMenu/SideMenuWidgetView.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/SideMenu/SideMenuWidgetView.js @@ -240,7 +240,8 @@ function SideMenuWidgetView(sideMenuWidgetController, sideMenuWidgetModel) {     treeModelUtils.push({ title : jupyterNotebook, entityType: "NEW_JUPYTER_NOTEBOOK", key : "NEW_JUPYTER_NOTEBOOK", folder : false, lazy : false, view : "showNewJupyterNotebookCreator" }); } - if(profile.mainMenu.showUserProfile && profile.isFileAuthenticationService && profile.isFileAuthenticationUser) { + if(profile.mainMenu.showUserProfile) { + // && profile.isFileAuthenticationService && profile.isFileAuthenticationUser     var userProfileLink = _this.getLinkForNode("User Profile", "USER_PROFILE", "showUserProfilePage", null);     treeModelUtils.push({ title : userProfileLink, entityType: "USER_PROFILE", key : "USER_PROFILE", folder : false, lazy : false, view : "showUserProfilePage", icon : "glyphicon glyphicon-user" }); } @@ -276,15 +277,16 @@ function SideMenuWidgetView(sideMenuWidgetController, sideMenuWidgetModel) { }); } - if (profile.mainMenu.showResearchCollectionExportBuilder) { - var researchCollectionExportBuilderLink = _this.getLinkForNode("Export to Research Collection", - "EXPORT_TO_RESEARCH_COLLECTION", "showResearchCollectionExportPage", null); - treeModelExports.push({ - displayName: "Export to Research Collection", title: researchCollectionExportBuilderLink, - entityType: "EXPORT_TO_RESEARCH_COLLECTION", key: "EXPORT_TO_RESEARCH_COLLECTION", folder: false, lazy: false, - view: "showResearchCollectionExportPage", icon: "./img/research-collection-icon.png" - }); - } + // Not fully implemented yet. + // if (profile.mainMenu.showResearchCollectionExportBuilder) { + // var researchCollectionExportBuilderLink = _this.getLinkForNode("Export to Research Collection", + // "EXPORT_TO_RESEARCH_COLLECTION", "showResearchCollectionExportPage", null); + // treeModelExports.push({ + // displayName: "Export to Research Collection", title: researchCollectionExportBuilderLink, + // entityType: "EXPORT_TO_RESEARCH_COLLECTION", key: "EXPORT_TO_RESEARCH_COLLECTION", folder: false, lazy: false, + // view: "showResearchCollectionExportPage", icon: "./img/research-collection-icon.png" + // }); + // } if (profile.mainMenu.showZenodoExportBuilder) { var zenodoExportBuilderLink = _this.getLinkForNode("Export to Zenodo", "EXPORT_TO_ZENODO", "showZenodoExportPage", null); diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/UserProfile/UserProfileController.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/UserProfile/UserProfileController.js index 74c870c9621ff3375bbb3817d4d63ead3cee369c..93d3c3fc9e2ebfd73e007cdd00da66bee76928ac 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/UserProfile/UserProfileController.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/UserProfile/UserProfileController.js @@ -18,6 +18,7 @@ function UserProfileController(mainController, mode) { this._mainController = mainController; this._userProfileModel = new UserProfileModel(mode); this._userProfileView = new UserProfileView(this, this._userProfileModel); + this._zenodoApiTokenKey = this._mainController.zenodoApiTokenKey; this.init = function(views) { this._userProfileView.repaint(views); @@ -49,6 +50,8 @@ function UserProfileController(mainController, mode) { return; } var userId = this._mainController.serverFacade.getUserId(); + + this.setSettingValue(this._zenodoApiTokenKey, userInformation.zenodoToken); this._mainController.serverFacade.updateUserInformation(userId, userInformation, (function(ok) { if (ok) { Util.showInfo("Profile saved. You will be logged out automatically in order to reload the profile data upon login.", (function() { @@ -69,4 +72,17 @@ function UserProfileController(mainController, mode) { return errors; } + this.isFileAuthentication = function() { + return this._mainController.profile.isFileAuthenticationService && + this._mainController.profile.isFileAuthenticationUser; + } + + this.getSettingValue = function (key, callback) { + this._mainController.serverFacade.getSetting(key, callback); + }; + + this.setSettingValue = function (key, value) { + this._mainController.serverFacade.setSetting(key, value); + }; + } \ No newline at end of file diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/UserProfile/UserProfileView.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/UserProfile/UserProfileView.js index 22e972b17ff4a1c0ed7cd41180acf7d7211b6d91..65d80e7574d388b5922b96ea0459bc8b35175128 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/UserProfile/UserProfileView.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/UserProfile/UserProfileView.js @@ -21,6 +21,7 @@ function UserProfileView(userProfileController, userProfileModel) { this._$firstNameInput = null; this._$lastNameInput = null; this._$emailInput = null; + this._$zenodoToken = null; this.repaint = function(views) { @@ -71,14 +72,28 @@ function UserProfileView(userProfileController, userProfileModel) { this._$emailInput = $("<input>", { type : "text", class : "form-control" }); this._$emailInput.val(getUserInformation.email); $formColumn.append(this._getFormGroup(this._$emailInput, "Email:")); + // personal Zenodo API token + this._$zenodoToken = $("<input>", { type : "text", class : "form-control" }); + + this._userProfileController.getSettingValue(this._userProfileController._zenodoApiTokenKey, (function (settingsValue) { + if (settingsValue) { + this._$zenodoToken.val(settingsValue.trim()); + } + }).bind(this)); + $formColumn.append(this._getFormGroup(this._$zenodoToken, "Zenodo API Token:")); + // disable in view mode - if (this._userProfileModel.mode === FormMode.VIEW) { + if (this._userProfileModel.mode === FormMode.VIEW || + !this._userProfileController.isFileAuthentication()) { this._$firstNameInput.prop("disabled", true); this._$lastNameInput.prop("disabled", true); this._$emailInput.prop("disabled", true); } - }).bind(this)); + if (this._userProfileModel.mode === FormMode.VIEW) { + this._$zenodoToken.prop("disabled", true); + } + }).bind(this)); } this._getOptionsMenu = function() { @@ -96,6 +111,7 @@ function UserProfileView(userProfileController, userProfileModel) { firstName : this._$firstNameInput.val(), lastName : this._$lastNameInput.val(), email : this._$emailInput.val(), + zenodoToken : this._$zenodoToken.val() }; } diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ZenodoExport/ZenodoExportController.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ZenodoExport/ZenodoExportController.js index 22d8015cdae2798ad66dbae025a5c121076a69fe..fb99fc614e7ea5cb2e89a2a84a54680df5e6d190 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ZenodoExport/ZenodoExportController.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ZenodoExport/ZenodoExportController.js @@ -15,17 +15,26 @@ */ function ZenodoExportController(parentController) { - var exportModel = new ZenodoExportModel(); - var exportView = new ZenodoExportView(this, exportModel); + this.exportModel = null; + this.exportView = null; + this.zenodoApiTokenKey = parentController.zenodoApiTokenKey; this.init = function(views) { - exportView.repaint(views); + this.getSettingValue(this.zenodoApiTokenKey, (function (accessToken) { + if (accessToken && accessToken !== '') { + this.exportModel = new ZenodoExportModel(accessToken); + this.exportView = new ZenodoExportView(this, this.exportModel); + this.exportView.repaint(views); + } else { + Util.showError('Personal Zenodo API Token missing, please set it on your user profile.'); + } + }).bind(this)); }; this.exportSelected = function() { var _this = this; - var selectedNodes = $(exportModel.tree).fancytree('getTree').getSelectedNodes(); - var title = exportView.$titleTextBox.val().trim(); + var selectedNodes = $(this.exportModel.tree).fancytree('getTree').getSelectedNodes(); + var title = this.exportView.$titleTextBox.val().trim(); var toExport = []; for (var eIdx = 0; eIdx < selectedNodes.length; eIdx++) { @@ -41,8 +50,8 @@ function ZenodoExportController(parentController) { Util.showInfo('Not only spaces and the root should be selected. It will result in an empty export file.'); } else { Util.blockUI(); - this.getUserInformation(function(userInformation) { - mainController.serverFacade.exportZenodo(toExport, true, false, userInformation, title, + this.getUserInformation((function(userInformation) { + mainController.serverFacade.exportZenodo(toExport, true, false, userInformation, title, this.exportModel.accessToken, function(operationExecutionPermId) { _this.waitForOpExecutionResponse(operationExecutionPermId, function(error, result) { Util.unblockUI(); @@ -59,7 +68,7 @@ function ZenodoExportController(parentController) { } }); }); - }); + }).bind(this)); } }; @@ -112,4 +121,8 @@ function ZenodoExportController(parentController) { callback(userInformation); }); }; + + this.getSettingValue = function (key, callback) { + parentController.serverFacade.getSetting(key, callback); + }; } \ No newline at end of file diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ZenodoExport/ZenodoExportModel.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ZenodoExport/ZenodoExportModel.js index f555844b57e82e8c640965767f2077b1b66f213e..dc4f73489ca42ef5f9dc9cd1abe15ef67a0a8c35 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ZenodoExport/ZenodoExportModel.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ZenodoExport/ZenodoExportModel.js @@ -14,5 +14,6 @@ * limitations under the License. */ -function ZenodoExportModel() { +function ZenodoExportModel(accessToken) { + this.accessToken = accessToken; } \ No newline at end of file diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ZenodoExport/ZenodoExportView.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ZenodoExport/ZenodoExportView.js index 833660f9406412a911d2006d59f9747ee194fca1..a2ae6996d23f4730a24de4e2ff05f4b6df87fae4 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ZenodoExport/ZenodoExportView.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/ZenodoExport/ZenodoExportView.js @@ -21,7 +21,7 @@ function ZenodoExportView(exportController, exportModel) { var $form = $("<div>"); var $formColumn = $("<form>", { - 'name': 'rcExportForm', + 'name': 'zenodoExportForm', 'role': 'form', 'action': 'javascript:void(0);', 'onsubmit': 'mainController.currentView.exportSelected();' @@ -56,7 +56,7 @@ function ZenodoExportView(exportController, exportModel) { this.paintTitleTextBox($container); var $exportButton = $('<input>', { 'type': 'submit', 'class': 'btn btn-primary', 'value': 'Export Selected', - 'onClick': '$("form[name=\'rcExportForm\']").submit()'}); + 'onClick': '$("form[name=\'zenodoExportForm\']").submit()'}); $header.append($exportButton); }; diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/zenodo-exports-api/plugin.properties b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/zenodo-exports-api/plugin.properties index cc77ea6f8cfc5d2c91b4292696d89990276b2b7b..1e4e8fa3aa70869ce9c174f3bdcf7d2c5941224b 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/zenodo-exports-api/plugin.properties +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/zenodo-exports-api/plugin.properties @@ -2,5 +2,4 @@ label = Zenodo Exports API class = ch.systemsx.cisd.openbis.dss.generic.server.plugins.jython.JythonIngestionService script-path = zenodoExports.py limit-data-size-megabytes=${zenodo-exports-api-limit-data-size-megabytes:4000} -zenodoUrl=${zenodo-exports-api-zenodoUrl:https://localhost} -accessToken=${zenodo-exports-api-accessToken} \ No newline at end of file +zenodoUrl=${zenodo-exports-api-zenodoUrl:https://localhost} \ No newline at end of file diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/zenodo-exports-api/zenodoExports.py b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/zenodo-exports-api/zenodoExports.py index be1dd798a3369d52923b64d6be25380fc00e7337..5922f0f8827de532880931ddc8150ef0501f88fc 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/zenodo-exports-api/zenodoExports.py +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/zenodo-exports-api/zenodoExports.py @@ -93,7 +93,7 @@ def export(entities, tr, params): def sendToZenodo(tr, params, tempZipFilePath, entities): depositRootUrl = str(getConfigurationProperty(tr, 'zenodoUrl')) + '/api/deposit/depositions' - accessToken = str(getConfigurationProperty(tr, 'accessToken')) + accessToken = params.get('accessToken') operationLog.info('accessToken: %s' % accessToken) httpClient = None @@ -225,7 +225,7 @@ class ZenodoCallable(object): actionCompleted = True elif publicationJson.get('submitted'): operationLog.info('Publication #%d submitted. Registering metadata.' % publicationJson.get('id')) - self.registerPublicationInOpenbis(publicationJson.get('metadata')) + self.registerPublicationInOpenbis(publicationJson.get('metadata'), publicationJson.get('links')) actionCompleted = True else: operationLog.info('Publication #%d not submitted yet.' % publicationJson.get('id')) @@ -244,13 +244,13 @@ class ZenodoCallable(object): return actionCompleted - def registerPublicationInOpenbis(self, publicationMetadataJson): + def registerPublicationInOpenbis(self, publicationMetadataJson, publicationLinksJson): sessionToken = self.params.get('sessionToken') v3 = ServiceProvider.getV3ApplicationService() id = CustomASServiceCode('publication-api') options = CustomASServiceExecutionOptions() \ .withParameter('method', 'insertPublication') \ - .withParameter('publicationURL', self.selfUrl) \ + .withParameter('publicationURL', publicationLinksJson.get('doi')) \ .withParameter('openBISRelatedIdentifiers', self.permIdsStr) \ .withParameter('name', publicationMetadataJson.get('title')) \ .withParameter('publicationDescription', publicationMetadataJson.get('description')) \ diff --git a/pybis/src/python/CHANGELOG.md b/pybis/src/python/CHANGELOG.md index 1c68708da418d638fa3158a6d438d9e08b63e341..2f0abd9b62c0f900166306e048abc5978f6c8f06 100644 --- a/pybis/src/python/CHANGELOG.md +++ b/pybis/src/python/CHANGELOG.md @@ -1,3 +1,16 @@ +## Changes with pybis-1.9.3 + +* fixed documentation: add_members (not add_persons) +* bugfix role assignments of groups + +## Changes with pybis-1.9.2 + +* searches for datasets and samples are highly improved +* search parameters can accept a code, an identifier or an openbis entity +* searching for all datasets in a project now works +* bugfixes + + ## Changes with pybis-1.9.1 * bugfix: controlled vocabulary diff --git a/pybis/src/python/README.md b/pybis/src/python/README.md index 5a525c397433f583f80bd80189d97610a8ab7500..ef065b428f2ec16b9d9b00028f908a1a20cddc0e 100644 --- a/pybis/src/python/README.md +++ b/pybis/src/python/README.md @@ -126,9 +126,9 @@ group.assign_role(role='ADMIN', space='DEFAULT') group.get_roles() group.revoke_role(role='ADMIN', space='DEFAULT') -group.add_persons(['admin']) -group.get_persons() -group.del_persons(['admin']) +group.add_members(['admin']) +group.get_members() +group.del_members(['admin']) group.delete() o.get_persons() diff --git a/pybis/src/python/pybis/__init__.py b/pybis/src/python/pybis/__init__.py index 4aa2b995675dc04f0874952732c359ada99bdd0f..c09faa979fdad428ea5009396b3390cdd526bfbe 100644 --- a/pybis/src/python/pybis/__init__.py +++ b/pybis/src/python/pybis/__init__.py @@ -1,7 +1,7 @@ name = 'pybis' __author__ = 'Swen Vermeul' __email__ = 'swen@ethz.ch' -__version__ = '1.9.1' +__version__ = '1.9.3' from . import pybis from .pybis import Openbis diff --git a/pybis/src/python/pybis/definitions.py b/pybis/src/python/pybis/definitions.py index 681c47d4526a66a7faadfac3d081a8c8eec9cba2..ca0a43e785563549577e91d6a07968c7ea574d20 100644 --- a/pybis/src/python/pybis/definitions.py +++ b/pybis/src/python/pybis/definitions.py @@ -461,12 +461,12 @@ def get_fetchoption_for_entity(entity): except KeyError as e: return {} -def get_type_for_entity(entity, action): +def get_type_for_entity(entity, action, parents_or_children=''): if action not in "create update delete search".split(): raise ValueError('unknown action: {}'.format(action)) definition = openbis_definitions(entity) - if action in definition: + if action in definition and not parents_or_children: return definition[action] else: # try to guess type, according to the naming scheme @@ -478,10 +478,16 @@ def get_type_for_entity(entity, action): "search": "SearchCriteria", } - return { - "@type": "as.dto.{}.{}.{}{}" - .format(entity.lower(), action, cap_entity, noun[action]) - } + if parents_or_children: + return { + "@type": "as.dto.{}.{}.{}{}{}" + .format(entity.lower(), action, cap_entity, parents_or_children, noun[action]) + } + else: + return { + "@type": "as.dto.{}.{}.{}{}" + .format(entity.lower(), action, cap_entity, noun[action]) + } def get_method_for_entity(entity, action): diff --git a/pybis/src/python/pybis/pybis.py b/pybis/src/python/pybis/pybis.py index 398cf56cda8b98dd3afb248a5240373966886f75..d44a332a0219219e1c65b2ece10331a6a23e5e4c 100644 --- a/pybis/src/python/pybis/pybis.py +++ b/pybis/src/python/pybis/pybis.py @@ -381,9 +381,9 @@ def _subcriteria_for_tags(tags): if not isinstance(tags, list): tags = [tags] - criterias = [] + criteria = [] for tag in tags: - criterias.append({ + criteria.append({ "fieldName": "code", "fieldType": "ATTRIBUTE", "fieldValue": { @@ -396,7 +396,7 @@ def _subcriteria_for_tags(tags): return { "@type": "as.dto.tag.search.TagSearchCriteria", "operator": "AND", - "criteria": criterias + "criteria": criteria } @@ -423,14 +423,99 @@ def _subcriteria_for_properties(prop, val): } } +def _subcriteria_for(thing, entity, parents_or_children='', operator='AND'): + """Returns the sub-search criteria for «thing», which can be either: + - a python object (sample, dataSet, experiment) + - a permId + - an identifier + - a code + """ + + if isinstance(thing, str): + if is_permid(thing): + return _subcriteria_for_permid( + thing, + entity=entity, + parents_or_children=parents_or_children, + operator=operator + ) + elif is_identifier(thing): + return _subcriteria_for_identifier( + thing, + entity=entity, + parents_or_children=parents_or_children, + operator=operator + ) + else: + # look for code + return _subcriteria_for_code_new( + thing, + entity=entity, + parents_or_children=parents_or_children, + operator=operator + ) + + elif isinstance(thing, list): + criteria = [] + for element in thing: + crit = _subcriteria_for(element, entity, parents_or_children, operator) + criteria += crit["criteria"] + + return { + "criteria": criteria, + "@type": crit["@type"], + "operator": "OR" + } + elif thing is None: + # we just need the type + search_type = get_type_for_entity(entity, 'search', parents_or_children) + return { + "criteria": [], + **search_type, + "operator": operator + } + else: + # we passed an object + return _subcriteria_for_permid( + thing.permId, + entity=entity, + parents_or_children=parents_or_children, + operator=operator + ) + + +def _subcriteria_for_identifier(ids, entity, parents_or_children='', operator='AND'): + if not isinstance(ids, list): + ids = [ids] + + criteria = [] + for id in ids: + criteria.append({ + "@type": "as.dto.common.search.IdentifierSearchCriteria", + "fieldValue": { + "value": id, + "@type": "as.dto.common.search.StringEqualToValue" + }, + "fieldType": "ATTRIBUTE", + "fieldName": "identifier" + }) + + search_type = get_type_for_entity(entity, 'search', parents_or_children) + return { + "criteria": criteria, + **search_type, + "operator": operator + } + return criteria + def _subcriteria_for_permid(permids, entity, parents_or_children='', operator='AND'): if not isinstance(permids, list): permids = [permids] - criterias = [] + criteria = [] for permid in permids: - criterias.append({ + criteria.append({ "@type": "as.dto.common.search.PermIdSearchCriteria", "fieldValue": { "value": permid, @@ -440,14 +525,36 @@ def _subcriteria_for_permid(permids, entity, parents_or_children='', operator='A "fieldName": "code" }) - criteria = { - "criteria": criterias, - "@type": "as.dto.{}.search.{}{}SearchCriteria".format( - entity.lower(), entity, parents_or_children - ), + search_type = get_type_for_entity(entity, 'search', parents_or_children) + return { + "criteria": criteria, + **search_type, + "operator": operator + } + + +def _subcriteria_for_code_new(codes, entity, parents_or_children='', operator='AND'): + if not isinstance(codes, list): + codes = [codes] + + criteria = [] + for code in codes: + criteria.append({ + "@type": "as.dto.common.search.CodeSearchCriteria", + "fieldValue": { + "value": code, + "@type": "as.dto.common.search.StringEqualToValue" + }, + "fieldType": "ATTRIBUTE", + "fieldName": "code" + }) + + search_type = get_type_for_entity(entity, 'search', parents_or_children) + return { + "criteria": criteria, + **search_type, "operator": operator } - return criteria def _subcriteria_for_code(code, entity): @@ -1028,7 +1135,7 @@ class Openbis: else: groupId = search_args[attr].code sub_crit.append( - _subcriteria_for_permid(groupId, 'AuthorizationGroup') + _subcriteria_for_permid(groupId, 'authorizationGroup') ) elif attr == 'role': # TODO @@ -1403,37 +1510,34 @@ class Openbis: def get_samples( self, identifier=None, code=None, permId=None, - space=None, project=None, experiment=None, type=None, + space=None, project=None, experiment=None, collection=None, type=None, start_with=None, count=None, withParents=None, withChildren=None, tags=None, props=None, **properties ): """ Get a list of all samples for a given space/project/experiment (or any combination) """ + if collection is not None: + experiment = collection + sub_criteria = [] - # v3 API does not offer a search for identifiers. We need to do a combined search instead: - # space && code or - # space && project && code if identifier: - identifier = identifier.lstrip('/') - elements = identifier.split('/') - if len(elements) == 2: - space = elements[0] - code = elements[1] - elif len(elements) == 3: - space = elements[0] - code = elements[2] - else: - raise ValueError("{} is not a valid sample identifier.".format(identifier)) + crit = _subcriteria_for(identifier, 'sample') + sub_criteria += crit['criteria'] if space: - sub_criteria.append(_subcriteria_for_code(space, 'space')) + sub_criteria.append(_subcriteria_for(space, 'space')) if project: - proj_crit = _subcriteria_for_code(project, 'project') - sub_criteria.append(proj_crit) + sub_criteria.append(_subcriteria_for(project, 'project')) if experiment: - sub_criteria.append(_subcriteria_for_code(experiment, 'experiment')) + sub_criteria.append(_subcriteria_for(experiment, 'experiment')) + + if withParents: + sub_criteria.append(_subcriteria_for(withParents, 'sample', 'Parents')) + if withChildren: + sub_criteria.append(_subcriteria_for(withChildren, 'sample', 'Children')) + if properties is not None: for prop in properties: sub_criteria.append(_subcriteria_for_properties(prop, properties[prop])) @@ -1445,26 +1549,6 @@ class Openbis: sub_criteria.append(_criteria_for_code(code)) if permId: sub_criteria.append(_common_search("as.dto.common.search.PermIdSearchCriteria", permId)) - if withParents: - if not isinstance(withParents, list): - withParents = [withParents] - for parent in withParents: - sub_criteria.append( - _gen_search_criteria({ - "sample": "SampleParents", - "identifier": parent - }) - ) - if withChildren: - if not isinstance(withChildren, list): - withChildren = [withChildren] - for child in withChildren: - sub_criteria.append( - _gen_search_criteria({ - "sample": "SampleChildren", - "identifier": child - }) - ) criteria = { "criteria": sub_criteria, @@ -1596,29 +1680,35 @@ class Openbis: def get_datasets( self, code=None, type=None, withParents=None, withChildren=None, start_with=None, count=None, kind=None, - status=None, sample=None, experiment=None, project=None, + status=None, sample=None, experiment=None, collection=None, project=None, tags=None, props=None, **properties ): + if 'object' in properties: + sample = properties['object'] + if collection is not None: + experiment = collection + sub_criteria = [] if code: sub_criteria.append(_criteria_for_code(code)) if type: - sub_criteria.append(_subcriteria_for_type(type, 'DataSet')) + sub_criteria.append(_subcriteria_for_type(type, 'dataSet')) + if withParents: - sub_criteria.append(_subcriteria_for_permid(withParents, 'DataSet', 'Parents')) + sub_criteria.append(_subcriteria_for(withParents, 'dataSet', 'Parents')) if withChildren: - sub_criteria.append(_subcriteria_for_permid(withChildren, 'DataSet', 'Children')) + sub_criteria.append(_subcriteria_for(withChildren, 'dataSet', 'Children')) if sample: - sub_criteria.append(_subcriteria_for_code(sample, 'Sample')) + sub_criteria.append(_subcriteria_for(sample, 'sample')) if experiment: - sub_criteria.append(_subcriteria_for_code(experiment, 'Experiment')) + sub_criteria.append(_subcriteria_for(experiment, 'experiment')) + if project: - exp_crit = _subcriteria_for_code(experiment, 'Experiment') - proj_crit = _subcriteria_for_code(project, 'Project') - exp_crit['criteria'] = [] + exp_crit = _subcriteria_for(experiment, 'experiment') + proj_crit = _subcriteria_for(project, 'project') exp_crit['criteria'].append(proj_crit) sub_criteria.append(exp_crit) if tags: diff --git a/pybis/src/python/setup.py b/pybis/src/python/setup.py index 723fcda825c708e6a385739579d327aa8d44c80e..d98d25fa4d55669e55272c2d728a0b6a57241c5c 100644 --- a/pybis/src/python/setup.py +++ b/pybis/src/python/setup.py @@ -11,7 +11,7 @@ with open("README.md", "r", encoding="utf-8") as fh: setup( name='PyBIS', - version= '1.9.1', + version= '1.9.3', author='Swen Vermeul • ID SIS • ETH Zürich', author_email='swen@ethz.ch', description='openBIS connection and interaction, optimized for using with Jupyter', diff --git a/pybis/src/python/tests/conftest.py b/pybis/src/python/tests/conftest.py index 677de709a3f316e1eb0806ec0ed2cf7e95f4388c..1568409e701a0c6e37da8fcab45941ae1cf6d83a 100644 --- a/pybis/src/python/tests/conftest.py +++ b/pybis/src/python/tests/conftest.py @@ -3,9 +3,12 @@ import time from pybis import Openbis -openbis_url = 'https://localhost:8443' -admin_username = 'admin' -admin_password = 'changeit' +#openbis_url = 'https://localhost:8443' +#admin_username = 'admin' +#admin_password = 'changeit' +openbis_url = 'http://localhost:20000' +admin_username = 'openbis_test_js' +admin_password = 'password' @pytest.yield_fixture(scope="module") def openbis_instance(): diff --git a/pybis/src/python/tests/test_group.py b/pybis/src/python/tests/test_group.py index 9e3268332131fe216aa8479ba01bd9125e8807d1..cb3e8dad9fd2cb8b55de3e054437e8e837d6dfeb 100644 --- a/pybis/src/python/tests/test_group.py +++ b/pybis/src/python/tests/test_group.py @@ -27,12 +27,12 @@ def test_crud_group(openbis_instance, group): changed_description = 'changed description of group ' + group.code group.description = changed_description group.save() - group_changed = openbis_instance.get_group(code=group.code) + group_changed = openbis_instance.get_group(group.code) assert group_changed.description == changed_description group.delete('test') with pytest.raises(ValueError): - group_not_exists = openbis_instance.get_group(code=group.code) + group_not_exists = openbis_instance.get_group(group.code) assert group_not_exists is None