Added methods to add, update, and save capture metadata in a yaml file
This commit is contained in:
parent
7cd8d26ea5
commit
2c2932f5aa
1 changed files with 68 additions and 8 deletions
|
|
@ -4,6 +4,7 @@ import os
|
||||||
import glob
|
import glob
|
||||||
import datetime
|
import datetime
|
||||||
import copy
|
import copy
|
||||||
|
import yaml
|
||||||
import logging
|
import logging
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import atexit
|
import atexit
|
||||||
|
|
@ -59,6 +60,9 @@ class CaptureObject(object):
|
||||||
self.filename = "{}.{}".format(filename, fmt)
|
self.filename = "{}.{}".format(filename, fmt)
|
||||||
self.folder = folder
|
self.folder = folder
|
||||||
|
|
||||||
|
# Dictionary for storing custom metadata
|
||||||
|
self._metadata = {}
|
||||||
|
|
||||||
# Initialise the capture stream
|
# Initialise the capture stream
|
||||||
self.initialise_capture()
|
self.initialise_capture()
|
||||||
|
|
||||||
|
|
@ -100,6 +104,9 @@ class CaptureObject(object):
|
||||||
else:
|
else:
|
||||||
logging.debug("Target for {} set to 'file'".format(self.id))
|
logging.debug("Target for {} set to 'file'".format(self.id))
|
||||||
self.stream = self.file
|
self.stream = self.file
|
||||||
|
|
||||||
|
# Save initial metadata file
|
||||||
|
self.save_metadata()
|
||||||
|
|
||||||
def build_file_path(
|
def build_file_path(
|
||||||
self,
|
self,
|
||||||
|
|
@ -122,7 +129,6 @@ class CaptureObject(object):
|
||||||
|
|
||||||
# Move to tmp directory if not being kept
|
# Move to tmp directory if not being kept
|
||||||
if not self.keep_on_disk:
|
if not self.keep_on_disk:
|
||||||
# TODO: Empty tmp folder on module load and atexit
|
|
||||||
self.file_notmp = self.file # Store originally defined folder
|
self.file_notmp = self.file # Store originally defined folder
|
||||||
self.filefolder = TEMP_CAPTURE_PATH
|
self.filefolder = TEMP_CAPTURE_PATH
|
||||||
self.file = os.path.join(self.filefolder, self.filename)
|
self.file = os.path.join(self.filefolder, self.filename)
|
||||||
|
|
@ -169,18 +175,57 @@ class CaptureObject(object):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def metadata_file(self) -> str:
|
||||||
|
return "{}.yaml".format(os.path.splitext(self.file)[0])
|
||||||
|
|
||||||
|
def put_metadata(self, data: dict) -> None:
|
||||||
|
self._metadata.update(data)
|
||||||
|
self.save_metadata()
|
||||||
|
|
||||||
|
def save_metadata(self) -> None:
|
||||||
|
logging.debug("Writing metadata to file {}".format(self.metadata_file))
|
||||||
|
with open(self.metadata_file, 'w') as outfile:
|
||||||
|
yaml.dump(self.metadata, outfile, default_flow_style=False)
|
||||||
|
|
||||||
|
def delete_metadata(self) -> None:
|
||||||
|
if os.path.isfile(self.metadata_file):
|
||||||
|
logging.info("Deleting file {}".format(self.metadata_file))
|
||||||
|
os.remove(self.metadata_file)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def metadata(self) -> dict:
|
def metadata(self) -> dict:
|
||||||
"""Return dictionary of StreamObject properties."""
|
# Create basic metadata dictionary
|
||||||
d = {
|
d = {
|
||||||
'id': self.id,
|
'id': self.id,
|
||||||
'locked': self.locked,
|
|
||||||
'keep_on_disk': self.keep_on_disk,
|
|
||||||
'filename': self.filename,
|
'filename': self.filename,
|
||||||
'path': self.file,
|
'path': self.file,
|
||||||
'time': self.timestring
|
'time': self.timestring
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Add custom metadata to dictionary
|
||||||
|
d.update(self._metadata)
|
||||||
|
|
||||||
|
return d
|
||||||
|
|
||||||
|
@property
|
||||||
|
def exists(self) -> bool:
|
||||||
|
return self.stream_exists or self.file_exists
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state(self) -> dict:
|
||||||
|
"""Return dictionary of StreamObject properties."""
|
||||||
|
|
||||||
|
# Create basic state dictionary
|
||||||
|
d = {
|
||||||
|
'locked': self.locked,
|
||||||
|
'keep_on_disk': self.keep_on_disk,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add metadata to state
|
||||||
|
d['metadata'] = self.metadata
|
||||||
|
d['metadata_path'] = self.metadata_file
|
||||||
|
|
||||||
# Check bytestream
|
# Check bytestream
|
||||||
if self.stream_exists:
|
if self.stream_exists:
|
||||||
d['bytestream'] = True
|
d['bytestream'] = True
|
||||||
|
|
@ -188,14 +233,14 @@ class CaptureObject(object):
|
||||||
d['bytestream'] = False
|
d['bytestream'] = False
|
||||||
|
|
||||||
# Combined availability of data
|
# Combined availability of data
|
||||||
if self.stream_exists or self.file_exists:
|
if self.exists:
|
||||||
d['available'] = True
|
d['available'] = True
|
||||||
else:
|
else:
|
||||||
d['available'] = False
|
d['available'] = False
|
||||||
|
|
||||||
# Check if file was manually deleted
|
# Check if file was manually deleted
|
||||||
if self.keep_on_disk and not self.file_exists:
|
if self.keep_on_disk and not self.file_exists:
|
||||||
d['path'] = "{} (Deleted)".format(d['path'])
|
d['metadata']['path'] = "{} (Deleted)".format(d['metadata']['path'])
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
@ -273,15 +318,29 @@ class CaptureObject(object):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def save(self) -> None:
|
||||||
|
"""Write stream to file, and save/update metadata file"""
|
||||||
|
# Try to save the file (only succeeds if an unsaved stream exists)
|
||||||
|
self.save_file()
|
||||||
|
|
||||||
|
# If a stream OR file exists, save the metadata file
|
||||||
|
if self.exists:
|
||||||
|
self.save_metadata()
|
||||||
|
|
||||||
def delete_stream(self):
|
def delete_stream(self):
|
||||||
"""Clear the BytesIO bytestream of the StreamObject."""
|
"""Clear the BytesIO bytestream of the StreamObject."""
|
||||||
self.bytestream = io.BytesIO()
|
self.bytestream = io.BytesIO()
|
||||||
|
|
||||||
def delete_file(self) -> bool:
|
def delete_file(self) -> bool:
|
||||||
"""If the StreamObject has been saved, delete the file."""
|
"""If the StreamObject has been saved, delete the file."""
|
||||||
|
if os.path.isfile(self.metadata_file):
|
||||||
|
logging.info("Deleting file {}".format(self.metadata_file))
|
||||||
|
os.remove(self.metadata_file)
|
||||||
|
|
||||||
if os.path.isfile(self.file):
|
if os.path.isfile(self.file):
|
||||||
logging.info("Deleting file {}".format(self.file))
|
logging.info("Deleting file {}".format(self.file))
|
||||||
os.remove(self.file)
|
os.remove(self.file)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
@ -291,11 +350,12 @@ class CaptureObject(object):
|
||||||
logging.info("Deleting {}".format(self.id))
|
logging.info("Deleting {}".format(self.id))
|
||||||
self.delete_stream()
|
self.delete_stream()
|
||||||
self.delete_file()
|
self.delete_file()
|
||||||
|
self.delete_metadata()
|
||||||
|
|
||||||
def shunt(self):
|
def shunt(self):
|
||||||
"""Demote the StreamObject from being stored in memory."""
|
"""Demote the StreamObject from being stored in memory."""
|
||||||
if not self.file_exists: # If file doesn't already exist
|
if not self.file_exists: # If file doesn't already exist
|
||||||
self.save_file() # Save bytestream to disk, if it exists
|
self.save() # Save bytestream to disk, if it exists
|
||||||
self.delete_stream() # Delete the bytestream from memory
|
self.delete_stream() # Delete the bytestream from memory
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
|
|
@ -303,6 +363,6 @@ class CaptureObject(object):
|
||||||
logging.info("Closing {}".format(self.id))
|
logging.info("Closing {}".format(self.id))
|
||||||
self.delete_stream()
|
self.delete_stream()
|
||||||
if not self.keep_on_disk:
|
if not self.keep_on_disk:
|
||||||
self.delete_file()
|
self.delete()
|
||||||
|
|
||||||
atexit.register(clear_tmp)
|
atexit.register(clear_tmp)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue