From edb4c46e88ae6d198f24cdb360b9daef5bffa795 Mon Sep 17 00:00:00 2001 From: Cezary Czernecki <ccezary@ethz.ch> Date: Tue, 18 Sep 2018 09:10:11 +0200 Subject: [PATCH] SSDM-7202 refactor --- .../1/as/initialize-master-data.py | 7 +- .../1/as/life-sciences-types/types2.xls | Bin 45568 -> 0 bytes .../creation_parsers.py | 199 ++++++++---------- .../poi_to_definition/definition_parsers.py | 1 + .../1/as/processors/__init__.py | 1 + .../openbis_duplicates_processor.py} | 3 +- .../scripts/dynamic/dynamic.py | 0 .../scripts/valid.py | 0 .../types.xls | Bin 47616 -> 47616 bytes .../1/as/utils/__init__.py | 2 + .../1/as/{ => utils}/file_handling.py | 0 .../1/as/utils/openbis_utils.py | 9 + 12 files changed, 107 insertions(+), 115 deletions(-) delete mode 100644 openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/life-sciences-types/types2.xls create mode 100644 openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/processors/__init__.py rename openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/{openbis_logic.py => processors/openbis_duplicates_processor.py} (97%) rename openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/{life-sciences-types => test_files}/scripts/dynamic/dynamic.py (100%) rename openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/{life-sciences-types => test_files}/scripts/valid.py (100%) rename openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/{life-sciences-types => test_files}/types.xls (95%) create mode 100644 openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/utils/__init__.py rename openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/{ => utils}/file_handling.py (100%) create mode 100644 openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/utils/openbis_utils.py diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/initialize-master-data.py b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/initialize-master-data.py index ead04e46d97..f5e98d86cee 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/initialize-master-data.py +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/initialize-master-data.py @@ -20,10 +20,10 @@ import sys from ch.ethz.sis.openbis.generic.asapi.v3.dto.operation import SynchronousOperationExecutionOptions from ch.ethz.sis.openbis.generic.server.asapi.v3 import ApplicationServerApi from ch.systemsx.cisd.openbis.generic.server import CommonServiceProvider -from file_handling import list_xls_files -from openbis_logic import OpenbisLogicHandler from parsers import ExcelToPoiParser, PoiToDefinitionParser, DefinitionToCreationParser, DuplicatesHandler, CreationToOperationParser +from processors import OpenbisDuplicatesHandler from search_engines import SearchEngine +from utils.file_handling import list_xls_files api = CommonServiceProvider.getApplicationContext().getBean(ApplicationServerApi.INTERNAL_SERVICE_NAME) @@ -38,11 +38,10 @@ for excel_file_path in list_xls_files(): else: creations[creation_type].extend(partial_creation) distinct_creations = DuplicatesHandler.get_distinct_creations(creations) - sessionToken = api.loginAsSystem() search_engine = SearchEngine(api, sessionToken) existing_elements = search_engine.find_all_existing_elements(distinct_creations) -server_duplicates_handler = OpenbisLogicHandler(distinct_creations, existing_elements) +server_duplicates_handler = OpenbisDuplicatesHandler(distinct_creations, existing_elements) creations = server_duplicates_handler.remove_existing_elements_from_creations() creations = server_duplicates_handler.rewrite_parentchild_creationid_to_permid() # creations = server_duplicates_handler.rewrite_vocabulary_labels() diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/life-sciences-types/types2.xls b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/life-sciences-types/types2.xls deleted file mode 100644 index 52bd9cc8dd6c1020b5d9b9624b4a53c092557beb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45568 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 diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/parsers/definition_to_creation/creation_parsers.py b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/parsers/definition_to_creation/creation_parsers.py index 86e26673774..6b98d4de380 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/parsers/definition_to_creation/creation_parsers.py +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/parsers/definition_to_creation/creation_parsers.py @@ -14,8 +14,9 @@ from ch.ethz.sis.openbis.generic.asapi.v3.dto.space.create import SpaceCreation from ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create import VocabularyCreation from ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.create import VocabularyTermCreation from ch.ethz.sis.openbis.generic.asapi.v3.dto.vocabulary.id import VocabularyPermId -from file_handling import get_script, get_filename_from_path from java.lang import UnsupportedOperationException +from utils.file_handling import get_script +from utils.openbis_utils import is_internal_namespace, get_script_name_for def get_boolean_from_string(text): @@ -27,113 +28,109 @@ class DefinitionToCreationParserFactory(object): @staticmethod def getParsers(definition): if definition.type == u'VOCABULARY_TYPE': - return [VocabularyDefinitionToCreationParser] + return [VocabularyDefinitionToCreationParser()] elif definition.type == u'SAMPLE_TYPE': - return [SampleTypeDefinitionToCreationParser, PropertyTypeDefinitionToCreationParser, ScriptDefinitionToCreationParser] + return [SampleTypeDefinitionToCreationParser(), PropertyTypeDefinitionToCreationParser(), ScriptDefinitionToCreationParser()] elif definition.type == u'EXPERIMENT_TYPE': - return [ExperimentTypeDefinitionToCreationParser, PropertyTypeDefinitionToCreationParser, ScriptDefinitionToCreationParser] + return [ExperimentTypeDefinitionToCreationParser(), PropertyTypeDefinitionToCreationParser(), ScriptDefinitionToCreationParser()] elif definition.type == u'DATASET_TYPE': - return [DatasetTypeDefinitionToCreationParser, PropertyTypeDefinitionToCreationParser, ScriptDefinitionToCreationParser] + return [DatasetTypeDefinitionToCreationParser(), PropertyTypeDefinitionToCreationParser(), ScriptDefinitionToCreationParser()] elif definition.type == u'SPACE': - return [SpaceDefinitionToCreationParser] + return [SpaceDefinitionToCreationParser()] elif definition.type == u'PROJECT': - return [ProjectDefinitionToCreationParser] + return [ProjectDefinitionToCreationParser()] elif definition.type == u'EXPERIMENT': - return [ExperimentDefinitionToCreationParser] + return [ExperimentDefinitionToCreationParser()] elif definition.type == u'SAMPLE': - return [SampleDefinitionToCreationParser] + return [SampleDefinitionToCreationParser()] elif definition.type == u'PROPERTY_TYPE': - return [PropertyTypeDefinitionToCreationParser] + return [PropertyTypeDefinitionToCreationParser()] else: raise UnsupportedOperationException("Definition of " + str(definition.type) + " is not supported (probably yet).") -class PropertyTypeDefinitionToCreationParser(object): +class DefinitionToCreationParser(object): + pass + + +class PropertyTypeDefinitionToCreationParser(DefinitionToCreationParser): type = "PropertyTypeCreation" - @staticmethod - def parse(definition): + def parse(self, definition): property_creations = [] - for property in definition.properties: + + for prop in definition.properties: property_type_creation = PropertyTypeCreation() - property_type_creation.code = property[u'code'] - if property[u'code'].startswith(u'$'): - property_type_creation.internalNameSpace = True - property_type_creation.label = property[u'property label'] - property_type_creation.dataType = DataType.valueOf(property[u'property type']) - property_type_creation.vocabularyId = VocabularyPermId(property[u'vocabulary code']) if property[u'vocabulary code'] is not None else None - property_type_creation.description = property[u'description'] + property_type_creation.code = prop[u'code'] + property_type_creation.label = prop[u'property label'] + property_type_creation.description = prop[u'description'] + property_type_creation.dataType = DataType.valueOf(prop[u'property type']) + property_type_creation.internalNameSpace = is_internal_namespace(prop[u'code']) + property_type_creation.vocabularyId = VocabularyPermId(prop[u'vocabulary code']) if prop[u'vocabulary code'] is not None else None property_creations.append(property_type_creation) return property_creations - @staticmethod - def get_type(): + def get_type(self): return PropertyTypeDefinitionToCreationParser.type -class VocabularyDefinitionToCreationParser(object): +class VocabularyDefinitionToCreationParser(DefinitionToCreationParser): type = "VocabularyCreation" - @staticmethod - def parse(definition): + def parse(self, definition): code = definition.attributes[u'code'] vocabulary_creation = VocabularyCreation() vocabulary_creation.code = code - if code.startswith(u'$'): - vocabulary_creation.internalNameSpace = True + vocabulary_creation.internalNameSpace = is_internal_namespace(code) vocabulary_creation.description = definition.attributes[u'description'] vocabulary_creations_terms = [] - for property in definition.properties: + for prop in definition.properties: vocabulary_creation_term = VocabularyTermCreation() - vocabulary_creation_term.code = property[u'code'] - vocabulary_creation_term.label = property[u'label'] - vocabulary_creation_term.description = property[u'description'] + vocabulary_creation_term.code = prop[u'code'] + vocabulary_creation_term.label = prop[u'label'] + vocabulary_creation_term.description = prop[u'description'] vocabulary_creations_terms.append(vocabulary_creation_term) vocabulary_creation.terms = vocabulary_creations_terms return vocabulary_creation - @staticmethod - def get_type(): + def get_type(self): return VocabularyDefinitionToCreationParser.type -class PropertyAssignmentDefinitionToCreationParser(object): +class PropertyAssignmentDefinitionToCreationParser(DefinitionToCreationParser): type = "PropertyAssignmentCreation" - @staticmethod - def parse(property): - code = property[u'code'] + def parse(self, prop): + code = prop[u'code'] property_assingment_creation = PropertyAssignmentCreation() - is_mandatory = get_boolean_from_string(property[u'mandatory']) + is_mandatory = get_boolean_from_string(prop[u'mandatory']) property_assingment_creation.mandatory = is_mandatory - should_show_in_edit_view = get_boolean_from_string(property[u'show in edit views']) + should_show_in_edit_view = get_boolean_from_string(prop[u'show in edit views']) property_assingment_creation.showInEditView = should_show_in_edit_view - property_assingment_creation.section = property[u'section'] + property_assingment_creation.section = prop[u'section'] property_assingment_creation.propertyTypeId = PropertyTypePermId(code) - if u'dynamic script' in property and property[u'dynamic script'] is not None: - dynamic_script_path = property[u'dynamic script'] - property_assingment_creation.pluginId = PluginPermId(ScriptDefinitionToCreationParser.get_name_for(code, dynamic_script_path)) + if u'dynamic script' in prop and prop[u'dynamic script'] is not None: + dynamic_script_path = prop[u'dynamic script'] + property_assingment_creation.pluginId = PluginPermId(get_script_name_for(code, dynamic_script_path)) return property_assingment_creation - @staticmethod - def get_type(): + def get_type(self): return PropertyAssignmentDefinitionToCreationParser.type -class SampleTypeDefinitionToCreationParser(object): +class SampleTypeDefinitionToCreationParser(DefinitionToCreationParser): type = "SampleTypeCreation" - @staticmethod - def parse(definition): + def parse(self, definition): code = definition.attributes[u'code'] sample_creation = SampleTypeCreation() sample_creation.code = code @@ -141,71 +138,68 @@ class SampleTypeDefinitionToCreationParser(object): sample_creation.autoGeneratedCode = should_auto_generate_codes if u'validation script' in definition.attributes and definition.attributes[u'validation script'] is not None: validation_script_path = definition.attributes[u'validation script'] - sample_creation.validationPluginId = PluginPermId(ScriptDefinitionToCreationParser.get_name_for(code, validation_script_path)) + sample_creation.validationPluginId = PluginPermId(get_script_name_for(code, validation_script_path)) property_assingment_creations = [] - for property in definition.properties: - property_assingment_creation = PropertyAssignmentDefinitionToCreationParser.parse(property) + property_assignment_parser = PropertyAssignmentDefinitionToCreationParser() + for prop in definition.properties: + property_assingment_creation = property_assignment_parser.parse(prop) property_assingment_creations.append(property_assingment_creation) sample_creation.propertyAssignments = property_assingment_creations return sample_creation - @staticmethod - def get_type(): + def get_type(self): return SampleTypeDefinitionToCreationParser.type -class ExperimentTypeDefinitionToCreationParser(object): +class ExperimentTypeDefinitionToCreationParser(DefinitionToCreationParser): type = "ExperimentTypeCreation" - @staticmethod - def parse(definition): + def parse(self, definition): experiment_type_creation = ExperimentTypeCreation() experiment_type_creation.code = definition.attributes[u'code'] property_assingment_creations = [] - for property in definition.properties: - property_assingment_creation = PropertyAssignmentDefinitionToCreationParser.parse(property) + property_assignment_parser = PropertyAssignmentDefinitionToCreationParser() + for prop in definition.properties: + property_assingment_creation = property_assignment_parser.parse(prop) property_assingment_creations.append(property_assingment_creation) experiment_type_creation.propertyAssignments = property_assingment_creations return experiment_type_creation - @staticmethod - def get_type(): + def get_type(self): return ExperimentTypeDefinitionToCreationParser.type -class DatasetTypeDefinitionToCreationParser(object): +class DatasetTypeDefinitionToCreationParser(DefinitionToCreationParser): type = "DatasetTypeCreation" - @staticmethod - def parse(definition): + def parse(self, definition): dataset_type_creation = DataSetTypeCreation() dataset_type_creation.code = definition.attributes[u'code'] property_assingment_creations = [] - for property in definition.properties: - property_assingment_creation = PropertyAssignmentDefinitionToCreationParser.parse(property) + property_assignment_parser = PropertyAssignmentDefinitionToCreationParser() + for prop in definition.properties: + property_assingment_creation = property_assignment_parser.parse(prop) property_assingment_creations.append(property_assingment_creation) dataset_type_creation.propertyAssignments = property_assingment_creations return dataset_type_creation - @staticmethod - def get_type(): + def get_type(self): return DatasetTypeDefinitionToCreationParser.type -class SpaceDefinitionToCreationParser(object): +class SpaceDefinitionToCreationParser(DefinitionToCreationParser): type = "SpaceCreation" - @staticmethod - def parse(definition): + def parse(self, definition): space_creation = SpaceCreation() space_creation.code = definition.attributes[u'code'] space_creation.description = definition.attributes[u'description'] @@ -213,17 +207,15 @@ class SpaceDefinitionToCreationParser(object): space_creation.creationId = CreationId(creation_id) return space_creation - @staticmethod - def get_type(): + def get_type(self): return SpaceDefinitionToCreationParser.type -class ProjectDefinitionToCreationParser(object): +class ProjectDefinitionToCreationParser(DefinitionToCreationParser): type = "ProjectCreation" - @staticmethod - def parse(definition): + def parse(self, definition): project_creation = ProjectCreation() project_creation.code = definition.attributes[u'code'] project_creation.description = definition.attributes[u'description'] @@ -232,17 +224,15 @@ class ProjectDefinitionToCreationParser(object): project_creation.creationId = CreationId(creation_id) return project_creation - @staticmethod - def get_type(): + def get_type(self): return ProjectDefinitionToCreationParser.type -class ExperimentDefinitionToCreationParser(object): +class ExperimentDefinitionToCreationParser(DefinitionToCreationParser): type = "ExperimentCreation" - @staticmethod - def parse(definition): + def parse(self, definition): experiments = [] mandatory_attributes = [u'code', u'project'] for experiment_properties in definition.properties: @@ -252,23 +242,21 @@ class ExperimentDefinitionToCreationParser(object): experiment_creation.projectId = CreationId(experiment_properties[u'project']) creation_id = experiment_properties[u'code'] experiment_creation.creationId = CreationId(creation_id) - for property, value in experiment_properties.items(): - if property not in mandatory_attributes: - experiment_creation.setProperty(property, value) + for prop, value in experiment_properties.items(): + if prop not in mandatory_attributes: + experiment_creation.setProperty(prop, value) experiments.append(experiment_creation) return experiments - @staticmethod - def get_type(): + def get_type(self): return ExperimentDefinitionToCreationParser.type -class SampleDefinitionToCreationParser(object): +class SampleDefinitionToCreationParser(DefinitionToCreationParser): type = "SampleCreation" - @staticmethod - def parse(definition): + def parse(self, definition): samples = [] mandatory_attributes = [u'$', u'code', u'space', u'project', u'experiment', u'auto generate code', u'parents', u'children'] for sample_properties in definition.properties: @@ -302,23 +290,21 @@ class SampleDefinitionToCreationParser(object): child_creationids.append(CreationId(child)) sample_creation.childIds = child_creationids - for property, value in sample_properties.items(): - if property not in mandatory_attributes: - sample_creation.setProperty(property, value) + for prop, value in sample_properties.items(): + if prop not in mandatory_attributes: + sample_creation.setProperty(prop, value) samples.append(sample_creation) return samples - @staticmethod - def get_type(): + def get_type(self): return SampleDefinitionToCreationParser.type -class ScriptDefinitionToCreationParser(object): +class ScriptDefinitionToCreationParser(DefinitionToCreationParser): type = "ScriptCreation" - @staticmethod - def parse(definition): + def parse(self, definition): scripts = [] if u'validation script' in definition.attributes: validation_script_path = definition.attributes[u'validation script'] @@ -328,31 +314,26 @@ class ScriptDefinitionToCreationParser(object): script_file = open(get_script(validation_script_path)) script = script_file.read() script_file.close() - validation_script_creation.name = ScriptDefinitionToCreationParser.get_name_for(code, validation_script_path) + validation_script_creation.name = get_script_name_for(code, validation_script_path) validation_script_creation.script = script validation_script_creation.pluginType = PluginType.ENTITY_VALIDATION scripts.append(validation_script_creation) - for property in definition.properties: - if u'dynamic script' in property: - dynamic_prop_script_path = property[u'dynamic script'] - code = property[u'code'] + for prop in definition.properties: + if u'dynamic script' in prop: + dynamic_prop_script_path = prop[u'dynamic script'] + code = prop[u'code'] if dynamic_prop_script_path is not None: validation_script_creation = PluginCreation() script_file = open(get_script(dynamic_prop_script_path)) script = script_file.read() script_file.close() - validation_script_creation.name = ScriptDefinitionToCreationParser.get_name_for(code, dynamic_prop_script_path) + validation_script_creation.name = get_script_name_for(code, dynamic_prop_script_path) validation_script_creation.script = script validation_script_creation.pluginType = PluginType.DYNAMIC_PROPERTY scripts.append(validation_script_creation) return scripts - @staticmethod - def get_name_for(owner_code, script_path): - return owner_code + '.' + get_filename_from_path(script_path) - - @staticmethod - def get_type(): + def get_type(self): return ScriptDefinitionToCreationParser.type diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/parsers/poi_to_definition/definition_parsers.py b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/parsers/poi_to_definition/definition_parsers.py index 2990cc1345d..3162d6fa808 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/parsers/poi_to_definition/definition_parsers.py +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/parsers/poi_to_definition/definition_parsers.py @@ -1,3 +1,4 @@ +from java.lang import UnsupportedOperationException from .definition import Definition from .poi_cleaner import PoiCleaner diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/processors/__init__.py b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/processors/__init__.py new file mode 100644 index 00000000000..870975eb874 --- /dev/null +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/processors/__init__.py @@ -0,0 +1 @@ +from .openbis_duplicates_processor import OpenbisDuplicatesHandler \ No newline at end of file diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/openbis_logic.py b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/processors/openbis_duplicates_processor.py similarity index 97% rename from openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/openbis_logic.py rename to openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/processors/openbis_duplicates_processor.py index 2e6c63b0bdd..8b0c3077a0c 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/openbis_logic.py +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/processors/openbis_duplicates_processor.py @@ -7,7 +7,7 @@ from parsers import VocabularyDefinitionToCreationParser, PropertyTypeDefinition ProjectDefinitionToCreationParser, ExperimentDefinitionToCreationParser, ScriptDefinitionToCreationParser, SampleDefinitionToCreationParser -class OpenbisLogicHandler(object): +class OpenbisDuplicatesHandler(object): def __init__(self, creations, existing_elements): self.creations = creations @@ -101,7 +101,6 @@ class OpenbisLogicHandler(object): def _create_sample_identifier_string(self, creation): spaceId = creation.spaceId.creationId if creation.spaceId is not None else None projectId = creation.projectId.creationId if creation.projectId is not None else None -# experimentId = creation.experimentId.creationId if creation.experimentId is not None else None code = creation.code sample_identifier = SampleIdentifier(spaceId, projectId, None, code) return sample_identifier.identifier diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/life-sciences-types/scripts/dynamic/dynamic.py b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/test_files/scripts/dynamic/dynamic.py similarity index 100% rename from openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/life-sciences-types/scripts/dynamic/dynamic.py rename to openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/test_files/scripts/dynamic/dynamic.py diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/life-sciences-types/scripts/valid.py b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/test_files/scripts/valid.py similarity index 100% rename from openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/life-sciences-types/scripts/valid.py rename to openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/test_files/scripts/valid.py diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/life-sciences-types/types.xls b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/test_files/types.xls similarity index 95% rename from openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/life-sciences-types/types.xls rename to openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/test_files/types.xls index 473cc33398b77fb5980ba414df0437cd2cc91825..c2d224eb2ae234f8e00d673d04f887f8cc7922ea 100644 GIT binary patch delta 386 zcmZqp!qo7EX+sVRn}XdRQF;H#MJ#QM7dQW8S<k}8P;C5I&VTbdPBTWn3lF=1>?@1{ zDzkv}<WF2ha3O}jGeOFVxQm$4#Xj*Bp=;e-B=FEo=)DI65U?_YL<YD9w=(cCe4d=@ z?$6K1zyuNp14ahM&3oO`*&^?lGBEG}g`&+E7`lP9r#S;dB_jjFY9M_ZNQ+u9Ft`Hs z$y+io_%kywECte6fwZI*P%R4s!!{uO3`lcXGcZ`OGBDHu>2*N*#^zeT2|Q}<UJMKq z!x$K3V;C6H;~5xMCNnVHO=n=x%wb?STEM_yUdq6bT|Qa7YtH8L(T8*y875Ea)ZkWU z0NM=1>I@o_k9PX7a#k`hm~Iy9ie=keJK+E$qsU~tN!pC_CTC5u;}ZsY6r@%d2w7Pt TpX-$0d=)4;*?@&*(G)cRiF<2y delta 382 zcmZ9`KS;ws6bA6`(j*vLqHPBe)I}(Q2s#*T1wl%w7PW$Zps0vQ?NUJkV!H)Ip>-)e z2N6M01VO05+ZA<mDPmM`auFO{N*6a@9dkGQ?!J5PcvfAq>XMz6)&A(abv4CJd5<~b zSH6~2>u7@#QPB*h+o!j5eqmLm+Ni2Eo32QhUen{wYP#ue6=v(F5%?YlEd_I_nb_<u zbo}siJgGH-HF7{a#xrW_brA5;ZQcO($><P}r-}>mgKQZFViM3E29h4&gmlPY1elNk zoBSf>5g?)fIkG}Ni=F9`FEo~*Zx?{JC17<0I9~(aGC+40xZ4B<wt)0D?<^h*XYrwr zN&K+T<Msc~$l!;cKNThwPaX)1j^eVaF-b*`=1huQ>7KDJ9x3;-OTJzn)dSGzfgwO! M)5J|V!Ojjsf4i7$wg3PC diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/utils/__init__.py b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/utils/__init__.py new file mode 100644 index 00000000000..2ca4ab4e79e --- /dev/null +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/utils/__init__.py @@ -0,0 +1,2 @@ +import file_handling +import openbis_utils \ No newline at end of file diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/file_handling.py b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/utils/file_handling.py similarity index 100% rename from openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/file_handling.py rename to openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/utils/file_handling.py diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/utils/openbis_utils.py b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/utils/openbis_utils.py new file mode 100644 index 00000000000..994918600bd --- /dev/null +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims-life-sciences/1/as/utils/openbis_utils.py @@ -0,0 +1,9 @@ +from utils.file_handling import get_filename_from_path + + +def is_internal_namespace(property_value): + return property_value.startswith(u'$') + + +def get_script_name_for(owner_code, script_path): + return owner_code + '.' + get_filename_from_path(script_path) -- GitLab