15
15
16
16
from aiida .common .exceptions import NotExistent
17
17
18
+ # TODO: Possibly mirror hierarchy of mirrored directory inside json file
19
+ # TODO: Currently, json file has only top-level "groups", "workflows", and "calculations"
20
+
18
21
19
22
@dataclass
20
23
class DumpLog :
@@ -94,10 +97,12 @@ class DumpLogStoreCollection:
94
97
95
98
calculations : DumpLogStore
96
99
workflows : DumpLogStore
100
+ groups : DumpLogStore
101
+ # data: DumpLogStore
97
102
98
103
99
104
class DumpLogger :
100
- """Main logger class using dataclasses for better structure ."""
105
+ """Main dumping logger singleton ."""
101
106
102
107
DUMP_LOG_FILE : str = '.dump_log.json'
103
108
_instance : 'DumpLogger | None' = None # Class-level singleton instance
@@ -116,7 +121,8 @@ def __init__(
116
121
dump_parent_path : Path | None = None ,
117
122
calculations : DumpLogStore | None = None ,
118
123
workflows : DumpLogStore | None = None ,
119
- # counter: int = 0,
124
+ groups : DumpLogStore | None = None ,
125
+ # data: DumpLogStore | None = None,
120
126
) -> None :
121
127
# Ensure __init__ is only called once
122
128
if hasattr (self , '_initialized' ) and self ._initialized :
@@ -125,7 +131,8 @@ def __init__(
125
131
self .dump_parent_path = dump_parent_path or Path .cwd ()
126
132
self .calculations = calculations or DumpLogStore ()
127
133
self .workflows = workflows or DumpLogStore ()
128
- # self.counter = counter
134
+ self .groups = groups or DumpLogStore ()
135
+ # self.dat = data or DumpLogStore()
129
136
130
137
# Mark the object as initialized
131
138
self ._initialized = True
@@ -144,20 +151,26 @@ def del_entry(self, store: DumpLogStore, uuid: str) -> bool:
144
151
@property
145
152
def log (self ) -> DumpLogStoreCollection :
146
153
"""Retrieve the current state of the log as a dataclass."""
147
- return DumpLogStoreCollection (calculations = self .calculations , workflows = self .workflows )
154
+ return DumpLogStoreCollection (calculations = self .calculations , workflows = self .workflows , groups = self . groups )
148
155
149
156
def save_log (self ) -> None :
150
157
"""Save the log to a JSON file."""
151
158
152
159
def serialize_logs (container : DumpLogStore ) -> dict :
153
160
serialized = {}
154
161
for uuid , entry in container .entries .items ():
155
- serialized [uuid ] = {'path' : str (entry .path ), 'time' : entry .time .isoformat ()}
162
+ serialized [uuid ] = {
163
+ 'path' : str (entry .path ),
164
+ 'time' : entry .time .isoformat (),
165
+ 'links' : [str (link ) for link in entry .links ],
166
+ }
156
167
return serialized
157
168
158
169
log_dict = {
159
170
'calculations' : serialize_logs (self .calculations ),
160
171
'workflows' : serialize_logs (self .workflows ),
172
+ 'groups' : serialize_logs (self .groups ),
173
+ # 'data': serialize_logs(self.data),
161
174
}
162
175
163
176
with self .log_file_path .open ('w' , encoding = 'utf-8' ) as f :
@@ -185,12 +198,20 @@ def deserialize_logs(category_data: dict) -> DumpLogStore:
185
198
container = DumpLogStore ()
186
199
for uuid , entry in category_data .items ():
187
200
container .add_entry (
188
- uuid , DumpLog (path = Path (entry ['path' ]), time = datetime .fromisoformat (entry ['time' ]))
201
+ uuid ,
202
+ DumpLog (
203
+ path = Path (entry ['path' ]),
204
+ time = datetime .fromisoformat (entry ['time' ]),
205
+ links = [Path (p ) for p in entry ['links' ]],
206
+ ),
189
207
)
208
+
190
209
return container
191
210
192
211
instance .calculations = deserialize_logs (data ['calculations' ])
193
212
instance .workflows = deserialize_logs (data ['workflows' ])
213
+ instance .groups = deserialize_logs (data ['groups' ])
214
+ # instance.data = deserialize_logs(data['data'])
194
215
195
216
except (json .JSONDecodeError , OSError ):
196
217
raise
@@ -206,7 +227,7 @@ def get_store_by_uuid(self, uuid: str) -> DumpLogStore:
206
227
if uuid in store .entries :
207
228
return store
208
229
209
- msg = f" No corresponding `DumpLogStore` found for UUID: `{ uuid } `."
230
+ msg = f' No corresponding `DumpLogStore` found for UUID: `{ uuid } `.'
210
231
raise NotExistent (msg )
211
232
212
233
def get_path_by_uuid (self , uuid : str ) -> Path | None :
@@ -215,13 +236,17 @@ def get_path_by_uuid(self, uuid: str) -> Path | None:
215
236
216
237
try :
217
238
current_store = self .get_store_by_uuid (uuid = uuid )
218
- path = current_store .entries [uuid ].path
219
- return path
220
239
except NotExistent as exc :
221
240
raise NotExistent (exc .args [0 ]) from exc
241
+ try :
242
+ path = current_store .entries [uuid ].path
243
+ return path
222
244
except KeyError as exc :
223
- msg = f" UUID: `{ uuid } ` not contained in store `{ current_store } `."
245
+ msg = f' UUID: `{ uuid } ` not contained in store `{ current_store } `.'
224
246
raise KeyError (msg ) from exc
225
247
except :
226
248
# For debugging
249
+ import ipdb
250
+
251
+ ipdb .set_trace ()
227
252
raise
0 commit comments