diff --git a/CHANGELOG.md b/CHANGELOG.md index cb8662e15e3b962fc8ac8f974302205809aa4b19..7c458aed9609b71662800d4d69b73755ed263718 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 output - New class for collecting information for exporting tables, e.g., to metadata repositories +- new name parsing +- new test for software folder structure +- new assure_name_is function ### Changed ### diff --git a/integrationtests/crawl.py b/integrationtests/crawl.py index e439510fd7308888e9071476905f486c82769dc5..2bec8b0acc98fdc7dd54c10cb360aac209e30978 100755 --- a/integrationtests/crawl.py +++ b/integrationtests/crawl.py @@ -33,7 +33,7 @@ from caosadvancedtools.cfood import fileguide from caosadvancedtools.crawler import FileCrawler from caosadvancedtools.guard import INSERT, UPDATE from scifolder import (AnalysisCFood, ExperimentCFood, ProjectCFood, - PublicationCFood, SimulationCFood) + PublicationCFood, SimulationCFood, SoftwareCFood) try: from sss_helper import get_argument_parser, print_success @@ -87,7 +87,7 @@ if __name__ == "__main__": c = FileCrawler(files=files, use_cache=True, interactive=False, hideKnown=False, cfood_types=[ProjectCFood, - ExperimentCFood, AnalysisCFood, + ExperimentCFood, AnalysisCFood, SoftwareCFood, PublicationCFood, SimulationCFood, ]) diff --git a/integrationtests/extroot/DataAnalysis/2010_TestProject/2019-02-03_something/README.md b/integrationtests/extroot/DataAnalysis/2010_TestProject/2019-02-03_something/README.md deleted file mode 100644 index 4470e62b71fe60e0c5dddd3c0a9a88790396b16e..0000000000000000000000000000000000000000 --- a/integrationtests/extroot/DataAnalysis/2010_TestProject/2019-02-03_something/README.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -responsible: -- First Person -description: A description of an example analysis. - -results: -- file: "images/*.png" - description: an example reference to a results file - -sources: -- file: /ExperimentalData/2010_TestProject/2019-02-03_something/ - description: an example reference to an experiment - -revisionOf: -- ../2019-02-03 - -scripts: -- analyse.py - -tags: -- collagen -- time sweep -- frequency sweep -... diff --git a/integrationtests/extroot/DataAnalysis/2010_TestProject/2019-02-03_something/README.xlsx b/integrationtests/extroot/DataAnalysis/2010_TestProject/2019-02-03_something/README.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..94afaa4f0af396997ec5582bc377245524817e00 Binary files /dev/null and b/integrationtests/extroot/DataAnalysis/2010_TestProject/2019-02-03_something/README.xlsx differ diff --git a/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_V1.0-rc1/README.xlsx b/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_V1.0-rc1/README.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..37024543a36f17e717d472a63576c017a138a1de Binary files /dev/null and b/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_V1.0-rc1/README.xlsx differ diff --git a/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_V1.0-rc1/analyse.py b/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_V1.0-rc1/analyse.py new file mode 100644 index 0000000000000000000000000000000000000000..02e78c5b0b1ee1896eb16b2fcbd2e9178d091212 --- /dev/null +++ b/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_V1.0-rc1/analyse.py @@ -0,0 +1 @@ +sdkflj2435j4'4rg diff --git a/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_V1.0-rc1/calc.py b/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_V1.0-rc1/calc.py new file mode 100644 index 0000000000000000000000000000000000000000..ec7f06eb8eb435d3ce821792411e781390ae5b82 --- /dev/null +++ b/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_V1.0-rc1/calc.py @@ -0,0 +1 @@ +sldfkjsldfjk diff --git a/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_v0.1/README.md b/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_v0.1/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d844a2ddf0d87d303c69b9107a366f2e34b6d03c --- /dev/null +++ b/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_v0.1/README.md @@ -0,0 +1,15 @@ +--- +responsible: Responsible, Only +description: A description of this example analysis. + +sources: +- file: "/ExperimentalData/2010_TestProject/2019-02-03/*.dat" + description: an example reference to a results file + +sourceCode: +- file: plot.py + description: a plotting script +binaries: +- file: example.deb + description: the binary file +... diff --git a/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_v0.1/example.deb b/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_v0.1/example.deb new file mode 100644 index 0000000000000000000000000000000000000000..685dc927597934520f3189024f4e85e46301d2a3 --- /dev/null +++ b/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_v0.1/example.deb @@ -0,0 +1 @@ +binary file diff --git a/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_v0.1/plot.py b/integrationtests/extroot/Software/2010_TestSoftware/2019-02-03_v0.1/plot.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/integrationtests/extroot/Software/2020NewProject0X/2020-02-03/README.md b/integrationtests/extroot/Software/2020NewProject0X/2020-02-03/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a47ea6e105c20d050ddf2fdc8cd29d4685ba30bf --- /dev/null +++ b/integrationtests/extroot/Software/2020NewProject0X/2020-02-03/README.md @@ -0,0 +1,15 @@ +--- +responsible: +- Only Responsible MPI DS +description: A description of this example analysis. + +sources: +- file: "/ExperimentalData/2010_TestProject/2019-02-03/*.dat" + description: an example reference to a results file + +sourceCode: +- file: plot.py + description: a plotting script +- file: calc.py + description: a calc script +... diff --git a/integrationtests/extroot/Software/2020NewProject0X/2020-02-03/calc.py b/integrationtests/extroot/Software/2020NewProject0X/2020-02-03/calc.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/integrationtests/extroot/Software/2020NewProject0X/2020-02-03/plot.py b/integrationtests/extroot/Software/2020NewProject0X/2020-02-03/plot.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/integrationtests/extroot/Software/2020NewProject0X/2020-02-03_second/README.xlsx b/integrationtests/extroot/Software/2020NewProject0X/2020-02-03_second/README.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..1a2262719f155893c8d88580ed0556f684a4c1b7 Binary files /dev/null and b/integrationtests/extroot/Software/2020NewProject0X/2020-02-03_second/README.xlsx differ diff --git a/integrationtests/extroot/Software/2020NewProject0X/2020-02-03_second/analyse.py b/integrationtests/extroot/Software/2020NewProject0X/2020-02-03_second/analyse.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/integrationtests/extroot/Software/2020NewProject0X/2020-02-03_second/release.deb b/integrationtests/extroot/Software/2020NewProject0X/2020-02-03_second/release.deb new file mode 100644 index 0000000000000000000000000000000000000000..92861e91dfa1bd37957fc9916ab1afd8ff76b40b --- /dev/null +++ b/integrationtests/extroot/Software/2020NewProject0X/2020-02-03_second/release.deb @@ -0,0 +1 @@ +kdjf diff --git a/integrationtests/extroot/Software/2020NewProject0X/2020-02-04/README.md b/integrationtests/extroot/Software/2020NewProject0X/2020-02-04/README.md new file mode 100644 index 0000000000000000000000000000000000000000..97b7137af372c127ee01458c9844b5ff10fd464b --- /dev/null +++ b/integrationtests/extroot/Software/2020NewProject0X/2020-02-04/README.md @@ -0,0 +1,15 @@ +--- +responsible: +- Some Responsible +- Responsible, No, MPI DS +description: A description of this example analysis. + +sources: +- file: "/ExperimentalData/2010_TestProject/2019-02-03/*.dat" + description: an example reference to a results file + +sourceCode: plot.py +binaries: +- file: example.deb + description: the binary file +... diff --git a/integrationtests/extroot/Software/2020NewProject0X/2020-02-04/example.deb b/integrationtests/extroot/Software/2020NewProject0X/2020-02-04/example.deb new file mode 100644 index 0000000000000000000000000000000000000000..685dc927597934520f3189024f4e85e46301d2a3 --- /dev/null +++ b/integrationtests/extroot/Software/2020NewProject0X/2020-02-04/example.deb @@ -0,0 +1 @@ +binary file diff --git a/integrationtests/extroot/Software/2020NewProject0X/2020-02-04/plot.py b/integrationtests/extroot/Software/2020NewProject0X/2020-02-04/plot.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/integrationtests/filldb.sh b/integrationtests/filldb.sh index da1abc7076b8f65dfc41277fd2b41dd9a5f65996..98d22347bd2d40e8384a2a217452fd3ba5bc445f 100755 --- a/integrationtests/filldb.sh +++ b/integrationtests/filldb.sh @@ -5,5 +5,6 @@ python3 -m caosadvancedtools.loadFiles /opt/caosdb/mnt/extroot/ExperimentalData python3 -m caosadvancedtools.loadFiles /opt/caosdb/mnt/extroot/DataAnalysis python3 -m caosadvancedtools.loadFiles /opt/caosdb/mnt/extroot/SimulationData python3 -m caosadvancedtools.loadFiles /opt/caosdb/mnt/extroot/Publications +python3 -m caosadvancedtools.loadFiles /opt/caosdb/mnt/extroot/Software python3 insert_model.py python3 crawl.py / diff --git a/integrationtests/insert_model.py b/integrationtests/insert_model.py index 1dcf5bdb888988089e554dc41bb20fbbe5e60e23..2289f72e83545db0e7eacedfa52868507b6c4760 100755 --- a/integrationtests/insert_model.py +++ b/integrationtests/insert_model.py @@ -1,5 +1,11 @@ #!/usr/bin/env python3 +import caosdb as db from caosmodels.parser import parse_model_from_yaml model = parse_model_from_yaml("model.yml") model.sync_data_model(noquestion=True) + +if len(db.execute_query("FIND Property alias")) == 0: + al = db.Property(name="alias") + al.add_parent(name="name") + al.insert() diff --git a/integrationtests/model.yml b/integrationtests/model.yml index 35f5ef244a85248c45eb79c359dbc5827ea3bc05..39659c008a1c9297a4470f0e5598074616af5aad 100644 --- a/integrationtests/model.yml +++ b/integrationtests/model.yml @@ -10,6 +10,14 @@ Experiment: #recommended_properties: responsible: Project: +SoftwareVersion: + recommended_properties: + version: + datatype: TEXT + description: 'First name of a Person.' + binaries: + sourceCode: + Software: Person: obligatory_properties: firstName: diff --git a/integrationtests/test_cache.py b/integrationtests/test_cache.py index cb9c174e5618cff77b0664bd7d7d43b28aefcca3..4b0a6cedc390b1268e8d2d89393e19a27a83b3be 100644 --- a/integrationtests/test_cache.py +++ b/integrationtests/test_cache.py @@ -22,45 +22,54 @@ # # ** end header +import os +import unittest +from tempfile import NamedTemporaryFile + import caosdb as db from caosadvancedtools.cache import UpdateCache -def setup(): - try: - db.execute_query("FIND Test*").delete() - except Exception: - pass - +class CacheTest(unittest.TestCase): + def empty_db(self): + try: + db.execute_query("FIND Test*").delete() + except Exception: + pass -def teardown(): - setup() + def setUp(self): + self.cache = NamedTemporaryFile(delete=False).name + os.remove(self.cache) + self.empty_db() + def tearDown(self): + self.empty_db() + os.remove(self.cache) -def test_same_old_different_new(): - """Formerly, inserting two containers with different changes to the - same entity into the update cache would result in an - IntegrityException. + def test_same_old_different_new(self): + """Formerly, inserting two containers with different changes to the + same entity into the update cache would result in an + IntegrityException. - """ - rt = db.RecordType(name="TestType").insert() - db.Property(name="TestProp1", datatype=db.TEXT).insert() - db.Property(name="TestProp2", datatype=db.TEXT).insert() - rec = db.Record(name="TestRecord").add_parent(rt).insert() + """ + rt = db.RecordType(name="TestType").insert() + db.Property(name="TestProp1", datatype=db.TEXT).insert() + db.Property(name="TestProp2", datatype=db.TEXT).insert() + rec = db.Record(name="TestRecord").add_parent(rt).insert() - # add TestProp1 to TestRecord - rec.add_property(name="TestProp1", value="blub") - cont = db.Container().append(rec) + # add TestProp1 to TestRecord + rec.add_property(name="TestProp1", value="blub") + cont = db.Container().append(rec) - update = UpdateCache() - run_id = "a" - update.insert(cont, run_id) - assert len(update.get_updates(run_id)) == 1 + update = UpdateCache(db_file=self.cache) + run_id = "a" + update.insert(cont, run_id) + assert len(update.get_updates(run_id)) == 1 - # duplicate and add TestProp2 to TestRecord - rec = db.execute_query("FIND Record TestRecord", unique=True) - rec.add_property(name="TestProp2", value="bla") - cont = db.Container().append(rec) - # same old digest, different new digest - update.insert(cont, run_id) - assert len(update.get_updates(run_id)) == 2 + # duplicate and add TestProp2 to TestRecord + rec = db.execute_query("FIND Record TestRecord", unique=True) + rec.add_property(name="TestProp2", value="bla") + cont = db.Container().append(rec) + # same old digest, different new digest + update.insert(cont, run_id) + assert len(update.get_updates(run_id)) == 2 diff --git a/integrationtests/test_crawler_with_cfoods.py b/integrationtests/test_crawler_with_cfoods.py index cc6f06771c48b41cdbba928051e0620e60586587..c39c3fc67d7ca30e3d013ac205ef398de216ad9c 100755 --- a/integrationtests/test_crawler_with_cfoods.py +++ b/integrationtests/test_crawler_with_cfoods.py @@ -266,3 +266,215 @@ class CrawlerTest(unittest.TestCase): # Test type self.assertEqual(pub.parents[0].name, "Thesis") + + def test_software(self): + ######################## + # # overall software # # + ######################## + + sw = db.execute_query("FIND Record Software") + assert len(sw) == 5 + + ps = db.execute_query("FIND RecordType Software with name!='Software'") + assert len(ps) == 2 + + ############################## + # # first software version # # + ############################## + ana = db.execute_query( + "FIND Software with version='V1.0-rc1'", unique=True) + + sw = db.execute_query( + "FIND Software with name='2010_TestSoftware'", unique=True) + assert sw.get_property("alias").value == "TestSoftware" + + # The software record should inherit from the correct software + assert sw.id == ana.get_parents()[0].id + assert ana.name == "TestSoftware_V1.0-rc1" + + # There should not be a file as binary + self.assertIsNone(ana.get_property("binaries")) + + # There should be a file as script attached with path plot.py + datfile = get_entity_with_id(ana.get_property("sourceCode").value[0]) + datfile2 = get_entity_with_id(ana.get_property("sourceCode").value[1]) + + for d in [datfile, datfile2]: + if datfile.path.endswith("analyse.py"): + assert datfile.description == "a simple script" + elif datfile.path.endswith("calc.py"): + assert datfile.description == "some calculation" + else: + raise Exception("unkown file") + + # Should have two responsible person + self.assertIsNotNone(ana.get_property("responsible")) + person = db.Record(id=ana.get_property("responsible").value[0]) + person.retrieve() + person2 = db.Record(id=ana.get_property("responsible").value[1]) + person2.retrieve() + + for fn in ["Second", "First"]: + found = False + + for p in [person, person2]: + if p.get_property("firstname").value == fn: + found = True + + if not found: + raise Exception("Did not find person") + + # Should have a description + self.assertIsNotNone(ana.description) + + ####################### + # # second software version # # + ####################### + ana = db.execute_query( + "FIND Software with version='v0.1'", unique=True) + + sw = db.execute_query( + "FIND Software with name='2010_TestSoftware'", unique=True) + + # The software record should inherit from the correct software + assert sw.id == ana.get_parents()[0].id + # The software should have the date + assert "2019-02-03" == ana.get_property("date").value + + # There should be a file as binary attached with path release.deb + datfile_id = ana.get_property("binaries").value[0] + datfile = get_entity_with_id(datfile_id) + assert os.path.basename(datfile.path) == "example.deb" + + # There should be a file as script attached with path plot.py + datfile_id = ana.get_property("sourceCode").value[0] + datfile = get_entity_with_id(datfile_id) + assert os.path.basename(datfile.path) == "plot.py" + + # Should have a responsible person + self.assertIsNotNone(ana.get_property("responsible")) + person = db.Record(id=ana.get_property("responsible").value[0]) + person.retrieve() + self.assertEqual("Only", person.get_property("firstname").value) + + # Should have a description + assert "example" in ana.description + + ####################### + # # third software version # # + ####################### + ana = db.execute_query( + "FIND Software with date='2020-02-04' and not version", + unique=True) + + sw = db.execute_query( + "FIND Software with name='2020NewProject0X'", unique=True) + + # The software record should inherit from the correct software + assert sw.id == ana.get_parents()[0].id + # The software should have the date + assert "2020-02-04" == ana.get_property("date").value + + # There should be a file as binary attached with path release.deb + datfile_id = ana.get_property("binaries").value[0] + datfile = get_entity_with_id(datfile_id) + assert os.path.basename(datfile.path) == "example.deb" + + # There should be a file as script attached with path plot.py + datfile_id = ana.get_property("sourceCode").value[0] + datfile = get_entity_with_id(datfile_id) + assert os.path.basename(datfile.path) == "plot.py" + + # Should have two responsible person + self.assertIsNotNone(ana.get_property("responsible")) + person = db.Record(id=ana.get_property("responsible").value[0]) + person.retrieve() + person2 = db.Record(id=ana.get_property("responsible").value[1]) + person2.retrieve() + + for fn in ["Some", "No"]: + found = False + + for p in [person, person2]: + if p.get_property("firstname").value == fn: + found = True + + if not found: + raise Exception("Did not find person") + + # Should have a description + assert "example" in ana.description + + ####################### + # # fourth software version # # + ####################### + ana = db.execute_query( + "FIND Software with date='2020-02-03' and not version", + unique=True) + + sw = db.execute_query( + "FIND Software with name='2020NewProject0X'", unique=True) + assert sw.get_property("alias").value == "NewProject0X" + + # The software record should inherit from the correct software + assert sw.id == ana.get_parents()[0].id + # The software should have the date + assert "2020-02-03" == ana.get_property("date").value + + # There should not be a file as binary + self.assertIsNone(ana.get_property("binaries")) + + # There should be a file as script attached with path plot.py + datfile = get_entity_with_id(ana.get_property("sourceCode").value[0]) + datfile2 = get_entity_with_id(ana.get_property("sourceCode").value[1]) + + for d in [datfile, datfile2]: + if datfile.path.endswith("plot.py"): + assert datfile.description == "a plotting script" + elif datfile.path.endswith("calc.py"): + assert datfile.description == "a calc script" + else: + raise Exception("unkown file") + + # Should have a responsible person + self.assertIsNotNone(ana.get_property("responsible")) + person = db.Record(id=ana.get_property("responsible").value[0]) + person.retrieve() + self.assertEqual("Only", person.get_property("firstname").value) + self.assertEqual("Responsible", person.get_property("lastname").value) + + # Should have a description + assert "example" in ana.description + + ############################## + # # fifth software version # # + ############################## + ana = db.execute_query( + "FIND Software with version='second'", unique=True) + + sw = db.execute_query( + "FIND Software with name='2020NewProject0X'", unique=True) + assert sw.get_property("alias").value == "NewProject0X" + + # The software record should inherit from the correct software + assert sw.id == ana.get_parents()[0].id + assert ana.name == "NewProject0X_second" + + # There should be a file as binary attached with path release.deb + datfile_id = ana.get_property("binaries").value[0] + datfile = get_entity_with_id(datfile_id) + assert os.path.basename(datfile.path) == "release.deb" + + # There should be a file as script attached with path plot.py + datfile_id = ana.get_property("sourceCode").value[0] + datfile = get_entity_with_id(datfile_id) + assert os.path.basename(datfile.path) == "analyse.py" + + # Should have a responsible person + self.assertIsNotNone(ana.get_property("responsible")) + person = db.Record(id=ana.get_property("responsible").value[0]) + person.retrieve() + self.assertEqual("First", person.get_property("firstname").value) + + # Should have a description + self.assertIsNotNone(ana.description) diff --git a/src/caosadvancedtools/cfood.py b/src/caosadvancedtools/cfood.py index 341594cf2efea5dd9ebdf0789fa292062053e4d6..54a6b8093748a2e9ee5986bf5efe2e9f0dbdb078 100644 --- a/src/caosadvancedtools/cfood.py +++ b/src/caosadvancedtools/cfood.py @@ -412,24 +412,24 @@ def assure_object_is_in_list(obj, containing_object, property_name, to_be_updated.append(containing_object) -# TOOD rename to is -# switch arugments and check for old sequence -def assure_has_description(entity, description, to_be_updated=None, - force=False): +def assure_special_is(entity, value, kind, to_be_updated=None, force=False): """ - Checks whether `entity` has the description that is passed. + Checks whether `entity` has the name or description that is passed. If this is the case this function ends. Otherwise the entity is assigned - a new description. The list to_be_updated is supplied, the entity is added to + a new name. The list to_be_updated is supplied, the entity is added to the list in order to indicate, that the entity `entity` should be updated. Otherwise it is directly updated """ - if entity.description == description: + if kind not in ["name", "description"]: + raise RuntimeError("Function cannot be used to set {}".format(kind)) + + if entity.__getattribute__(kind) == value: return - logger.debug("UPDATE: set description of entity {}".format(entity.id)) - entity.description = description + logger.debug("UPDATE: set {} of entity {}".format(kind, entity.id)) + entity.__setattr__(kind, value) if to_be_updated is None: if force: @@ -440,6 +440,37 @@ def assure_has_description(entity, description, to_be_updated=None, to_be_updated.append(entity) +def assure_name_is(entity, name, to_be_updated=None, force=False): + """ + Checks whether `entity` has the name that is passed. + + If this is the case this function ends. Otherwise the entity is assigned + a new name. The list to_be_updated is supplied, the entity is added to + the list in order to indicate, that the entity `entity` should be updated. + Otherwise it is directly updated + """ + + assure_special_is(entity, name, "name", to_be_updated=to_be_updated, + force=force) + + +# TOOD rename to is +# switch arugments and check for old sequence +def assure_has_description(entity, description, to_be_updated=None, + force=False): + """ + Checks whether `entity` has the description that is passed. + + If this is the case this function ends. Otherwise the entity is assigned + a new description. The list to_be_updated is supplied, the entity is added to + the list in order to indicate, that the entity `entity` should be updated. + Otherwise it is directly updated + """ + + assure_special_is(entity, description, "description", + to_be_updated=to_be_updated, force=force) + + def assure_has_parent(entity, parent, to_be_updated=None, force=False, unique=True): """ diff --git a/src/caosadvancedtools/crawler.py b/src/caosadvancedtools/crawler.py index e5bb738c5dc542bbf127a5163d91b2e748959915..6d706bb37a05549989ade5e77325bf513fc07a34 100644 --- a/src/caosadvancedtools/crawler.py +++ b/src/caosadvancedtools/crawler.py @@ -45,10 +45,10 @@ import subprocess import traceback import uuid from datetime import datetime +from sqlite3 import IntegrityError import caosdb as db from caosdb.exceptions import TransactionError -from sqlite3 import IntegrityError from .cache import Cache, UpdateCache, get_pretty_xml from .cfood import RowCFood, add_files, get_ids_for_entities_with_names @@ -293,7 +293,7 @@ class Crawler(object): except Exception as e: try: DataModelProblems.evaluate_exception(e) - except BaseException: + except Exception: pass logger.info("Failed during execution of {}!".format( cfood.__class__.__name__)) @@ -365,6 +365,7 @@ ____________________\n""".format(i+1, len(pending_changes)) + str(el[3])) """ from xml.sax.saxutils import escape + # TODO move path related stuff to sss_helper form = """ <html> diff --git a/src/caosadvancedtools/utils.py b/src/caosadvancedtools/utils.py index cb790a513dd3c15e9e19d9c9e377b95e02d452c7..2504f56976e2f6122f3e3468db1c7ae807bbb8cd 100644 --- a/src/caosadvancedtools/utils.py +++ b/src/caosadvancedtools/utils.py @@ -4,7 +4,8 @@ # ** header v3.0 # This file is a part of the CaosDB Project. # -# Copyright (C) 2019 Henrik tom Wörden +# Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> +# Copyright (C) 2020 Henrik tom Wörden <h.tomwoerden@indiscale.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -58,10 +59,20 @@ def string_to_person(person): """ Creates a Person Record from a string. - Currently only the format <Firstname> <Lastname> <*> is supported. + The following formats are supported: + - `<Firstname> <Lastname> <*>` + - `<Lastname(s)>,<Firstname(s)>,<*>` + + The part after the name can be used for an affiliation for example. """ - firstname = person.split(" ")[0] - lastname = person.split(" ")[1] + + if "," in person: + firstname = person.split(",")[1].strip() + lastname = person.split(",")[0].strip() + else: + firstname = person.split(" ")[0].strip() + lastname = person.split(" ")[1].strip() + pr = db.Record() pr.add_parent("Person") pr.add_property("lastname", lastname)