From 69e97ba5a3b20ec21eb06442732e26b4874a557d Mon Sep 17 00:00:00 2001 From: Joel Collins Date: Tue, 20 Nov 2018 13:56:51 +0000 Subject: [PATCH] Fixed non-clashing basename generation --- openflexure_microscope/camera/base.py | 18 ++++++++++++ openflexure_microscope/camera/capture.py | 36 +++++++----------------- openflexure_microscope/camera/pi.py | 34 ++++++++++++++-------- 3 files changed, 50 insertions(+), 38 deletions(-) diff --git a/openflexure_microscope/camera/base.py b/openflexure_microscope/camera/base.py index 76f828cd..e5550b9d 100644 --- a/openflexure_microscope/camera/base.py +++ b/openflexure_microscope/camera/base.py @@ -3,6 +3,7 @@ import time import io import threading from PIL import Image +import datetime import logging try: @@ -33,6 +34,11 @@ def entry_by_id(id: str, object_list: list): return found +def generate_basename(): + """Return a default filename based on the capture datetime""" + return datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + + class CameraEvent(object): """ A frame-signaller object used by any instances or subclasses of BaseCamera. @@ -222,6 +228,18 @@ class BaseCamera(object): self.videos, shunt_others=shunt_others) + # INTELLIGENTLY GENERATE FILENAMES + def generate_basename(self, obj_list: list) -> str: + initial_basename = generate_basename() + basename = initial_basename + # Handle clashing + iterator = 1 + while basename in [obj.basename for obj in obj_list]: + basename = initial_basename + "_{}".format(iterator) + iterator += 1 + + return basename + # WORKER THREAD def _thread(self): diff --git a/openflexure_microscope/camera/capture.py b/openflexure_microscope/camera/capture.py index c1ced0e6..4856297e 100644 --- a/openflexure_microscope/camera/capture.py +++ b/openflexure_microscope/camera/capture.py @@ -29,20 +29,10 @@ class StreamObject(object): # Store file format self.format = fmt - # Create file name - iterator = 0 - f_path, f_name = self.build_file_path(filename, folder, fmt) - - while os.path.isfile(f_name): # While file already exists - iterator += 1 # Add a file name iterator - f_path, f_name = self.build_file_path( - filename, - folder, - fmt, - iterator=iterator) # Rebuild file name - - self.file = f_path - self.filename = f_name + # Create file name. Default to UUID + if not filename: + filename = self.id + self.build_file_path(filename, folder, fmt) # Byte stream properties self.stream = io.BytesIO() # Byte stream that data will be written to @@ -85,21 +75,13 @@ class StreamObject(object): self, filename: str, folder: str, - fmt: str, - iterator: int=0) -> str: + fmt: str): """ Construct a full file path, based on filename, folder, and file format. - Defaults to datestamp. - Iterator adds a numeric increment to the file name. + Defaults to datestamp. """ - if filename: - file_name = "{}.{}".format(filename, fmt) - else: - file_name_base = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") - if iterator: - file_name_base = "{}_{}".format(file_name_base, iterator) - file_name = "{}.{}".format(file_name_base, fmt) + file_name = "{}.{}".format(filename, fmt) # Create folder and file if folder: @@ -110,7 +92,9 @@ class StreamObject(object): else: file_path = file_name - return (file_path, file_name) + self.basename = filename + self.file = file_path + self.filename = file_name def lock(self): """Set locked flag to True.""" diff --git a/openflexure_microscope/camera/pi.py b/openflexure_microscope/camera/pi.py index a11805ae..2bc63d19 100644 --- a/openflexure_microscope/camera/pi.py +++ b/openflexure_microscope/camera/pi.py @@ -238,11 +238,13 @@ class StreamingCamera(BaseCamera): # If no target is specified, store to StreamingCamera if not target: # Create a new video and add to the video list - target_obj = self.new_video(StreamObject( - write_to_file=write_to_file, - filename=filename, - folder=folder, - fmt=fmt)) + target_obj = self.new_video( + StreamObject( + write_to_file=write_to_file, + filename=filename, + folder=folder, + fmt=fmt) + ) # Lock the StreamObject while recording target_obj.lock() @@ -355,16 +357,24 @@ class StreamingCamera(BaseCamera): fmt (str): Format of the capture. resize ((int, int)): Resize the captured image. """ + # If no filename is specified, build a non-clashing one + if not filename: + filename = self.generate_basename(self.images) + logging.debug(filename) + # If no target is specified, store to StreamingCamera if not target: + # TODO: Handle clashing file names here instead of in capture method. # Create a new image and add to the image list - target_obj = self.new_image(StreamObject( - write_to_file=write_to_file, - keep_on_disk=keep_on_disk, - filename=filename, - folder=folder, - fmt=fmt)) - target = target_obj.target # Store to the StreamObject BytesIO + target_obj = self.new_image( + StreamObject( + write_to_file=write_to_file, + keep_on_disk=keep_on_disk, + filename=filename, + folder=folder, + fmt=fmt) + ) + target = target_obj.target # Store to the StreamObject BytesIO else: target_obj = target