@@ -964,13 +964,14 @@ def __init__(self, temp_prefix_ro="tmp", orcid=None, full_name=None):
964
964
self .orcid = _valid_orcid (orcid )
965
965
self .full_name = full_name or None
966
966
self .folder = os .path .abspath (tempfile .mkdtemp (prefix = temp_prefix_ro )) # type: Optional[Text]
967
+ self .final_location = None # type: Optional[Text]
967
968
# map of filename "data/de/alsdklkas": 12398123 bytes
968
969
self .bagged_size = {} # type: Dict
969
970
self .tagfiles = set () # type: Set
970
971
self ._file_provenance = {} # type: Dict
971
- self ._external_aggregates = [] # type: List[Dict]
972
- self .annotations = [] # type: List[Dict]
973
- self ._content_types = {} # type: Dict[Text,str]
972
+ self ._external_aggregates = [] # type: List[Dict]
973
+ self .annotations = [] # type: List[Dict]
974
+ self ._content_types = {} # type: Dict[Text,str]
974
975
975
976
# These should be replaced by generate_prov_doc when workflow/run IDs are known:
976
977
self .engine_uuid = "urn:uuid:%s" % uuid .uuid4 ()
@@ -986,9 +987,16 @@ def __init__(self, temp_prefix_ro="tmp", orcid=None, full_name=None):
986
987
_logger .debug (u"[provenance] Temporary research object: %s" ,
987
988
self .folder )
988
989
990
+ def self_check (self ): # type: () -> None
991
+ """Raises ValueError if this RO is closed."""
992
+ if not self .folder :
993
+ raise ValueError (
994
+ "This ResearchObject has already been closed and is not "
995
+ "available for futher manipulation." )
996
+
989
997
def __str__ (self ):
990
998
return "ResearchObject <%s> in <%s>" % (
991
- self .ro_uuid , self .folder )
999
+ self .ro_uuid , self .folder or self . final_location )
992
1000
993
1001
def _initialize (self ):
994
1002
# type: (...) -> None
@@ -1018,6 +1026,7 @@ def _finalize(self):
1018
1026
def user_provenance (self , document ):
1019
1027
# type: (ProvDocument) -> None
1020
1028
"""Add the user provenance."""
1029
+ self .self_check ()
1021
1030
(username , fullname ) = _whoami ()
1022
1031
1023
1032
if not self .full_name :
@@ -1049,6 +1058,7 @@ def user_provenance(self, document):
1049
1058
def write_bag_file (self , path , encoding = ENCODING ):
1050
1059
# type: (Text, Optional[str]) -> IO
1051
1060
"""Write the bag file into our research object."""
1061
+ self .self_check ()
1052
1062
# For some reason below throws BlockingIOError
1053
1063
#fp = BufferedWriter(WritableBagFile(self, path))
1054
1064
bag_file = cast (IO , WritableBagFile (self , path ))
@@ -1062,6 +1072,7 @@ def write_bag_file(self, path, encoding=ENCODING):
1062
1072
def add_tagfile (self , path , when = None ):
1063
1073
# type: (Text, datetime.datetime) -> None
1064
1074
"""Add tag files to our research object."""
1075
+ self .self_check ()
1065
1076
checksums = {}
1066
1077
# Read file to calculate its checksum
1067
1078
if os .path .isdir (path ):
@@ -1215,6 +1226,7 @@ def guess_mediatype(rel_path):
1215
1226
1216
1227
def add_uri (self , uri , when = None ):
1217
1228
# type: (str, Optional[datetime.datetime]) -> Dict
1229
+ self .self_check ()
1218
1230
aggr = self ._self_made (when = when )
1219
1231
aggr ["uri" ] = uri
1220
1232
self ._external_aggregates .append (aggr )
@@ -1223,6 +1235,7 @@ def add_uri(self, uri, when=None):
1223
1235
def add_annotation (self , about , content , motivated_by = "oa:describing" ):
1224
1236
# type: (str, List[str], str) -> str
1225
1237
"""Cheap URI relativize for current directory and /."""
1238
+ self .self_check ()
1226
1239
curr = self .base_uri + METADATA + "/"
1227
1240
content = [c .replace (curr , "" ).replace (self .base_uri , "../" )
1228
1241
for c in content ]
@@ -1342,6 +1355,7 @@ def _write_bag_info(self):
1342
1355
1343
1356
def generate_snapshot (self , prov_dep ):
1344
1357
# type: (MutableMapping[Text, Any]) -> None
1358
+ self .self_check ()
1345
1359
"""Copy all of the CWL files to the snapshot/ directory."""
1346
1360
assert self .folder
1347
1361
for key , value in prov_dep .items ():
@@ -1374,6 +1388,7 @@ def generate_snapshot(self, prov_dep):
1374
1388
1375
1389
def packed_workflow (self , packed ): # type: (Text) -> None
1376
1390
"""Pack CWL description to generate re-runnable CWL object in RO."""
1391
+ self .self_check ()
1377
1392
rel_path = posixpath .join (_posix_path (WORKFLOW ), "packed.cwl" )
1378
1393
# Write as binary
1379
1394
with self .write_bag_file (rel_path , encoding = None ) as write_pack :
@@ -1383,12 +1398,14 @@ def packed_workflow(self, packed): # type: (Text) -> None
1383
1398
1384
1399
def has_data_file (self , sha1hash ):
1385
1400
# type: (str) -> bool
1401
+ self .self_check ()
1386
1402
assert self .folder
1387
1403
folder = os .path .join (self .folder , DATA , sha1hash [0 :2 ])
1388
1404
return os .path .isfile (os .path .join (folder , sha1hash ))
1389
1405
1390
1406
def add_data_file (self , from_fp , when = None , content_type = None ):
1391
1407
# type: (IO, Optional[datetime.datetime], Optional[str]) -> Text
1408
+ self .self_check ()
1392
1409
"""Copy inputs to data/ folder."""
1393
1410
with tempfile .NamedTemporaryFile (
1394
1411
prefix = self .temp_prefix , delete = False ) as tmp :
@@ -1439,6 +1456,7 @@ def _self_made(self, when=None):
1439
1456
def add_to_manifest (self , rel_path , checksums ):
1440
1457
# type: (Text, Dict[str,str]) -> None
1441
1458
"""Add files to the research object manifest."""
1459
+ self .self_check ()
1442
1460
if posixpath .isabs (rel_path ):
1443
1461
raise ValueError ("rel_path must be relative: %s" % rel_path )
1444
1462
@@ -1608,6 +1626,7 @@ def close(self, save_to=None):
1608
1626
assert self .folder
1609
1627
shutil .move (self .folder , save_to )
1610
1628
_logger .info (u"[provenance] Research Object saved to %s" , save_to )
1629
+ self .final_location = save_to
1611
1630
# Forget our temporary folder, which should no longer exists
1612
1631
# This makes later close() a no-op
1613
1632
self .folder = None
0 commit comments