From c7e1e423f51c4703c61419d95725cbcc3dd47051 Mon Sep 17 00:00:00 2001 From: Thomas Forgione Date: Mon, 22 Jul 2024 15:31:16 +0200 Subject: [PATCH] Export group by calibration --- app.py | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ db.py | 1 - 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/app.py b/app.py index 64678ec..19aeee0 100755 --- a/app.py +++ b/app.py @@ -1,6 +1,7 @@ #!/usr/bin/env python from flask import Flask, redirect, request, render_template, send_from_directory, session +import itertools import io import json import os @@ -275,22 +276,29 @@ def download_object(id: int): conn = db.get() object = db.Object.get_from_id(id, conn).full(conn) - def generate(): - for acquisition_index, acquisition in enumerate(object.acquisitions): - acquisition_dir = join(config.OBJECT_DIR, str(object.id), str(acquisition.id)) + # Group acquisitions sharing calibration + def keyfunc(x: db.Calibration) -> int: + return x.calibration_id + + acquisitions_sorted = sorted(object.acquisitions, key=keyfunc) + acquisitions_grouped = [(db.Calibration.get_from_id(k, conn), list(g)) for k, g in itertools.groupby(acquisitions_sorted, key=keyfunc)] + + def generate(): + for calibration_index, (calib, acquisitions) in enumerate(acquisitions_grouped): # Send each image - for image in os.listdir(acquisition_dir): + calibration_dir = join(config.CALIBRATION_DIR, str(calib.id)) + for image in os.listdir(calibration_dir): # Generate tar header for file - image_path = join(acquisition_dir, image) + image_path = join(calibration_dir, image) bytes = io.BytesIO() stat = os.stat(image_path) # Create dummy tar to extract tar header for file with tarfile.open(fileobj=bytes, mode='w') as buffer: tar_info = tarfile.TarInfo(image_path) - tar_info.name = f'object/{acquisition_index}/{image}' + tar_info.name = f'object/{calibration_index}/calibration/{image}' tar_info.size = stat.st_size buffer.addfile(tar_info) @@ -314,6 +322,44 @@ def download_object(id: int): yield b'\x00' * (512 - bytes_len % 512) + for acquisition_index, acquisition in enumerate(acquisitions): + acquisition_dir = join(config.OBJECT_DIR, str(object.id), str(acquisition.id)) + + # Send each image + for image in os.listdir(acquisition_dir): + + # Generate tar header for file + image_path = join(acquisition_dir, image) + bytes = io.BytesIO() + stat = os.stat(image_path) + + # Create dummy tar to extract tar header for file + with tarfile.open(fileobj=bytes, mode='w') as buffer: + tar_info = tarfile.TarInfo(image_path) + tar_info.name = f'object/{calibration_index}/{acquisition_index}/{image}' + tar_info.size = stat.st_size + buffer.addfile(tar_info) + + # Yield header + value = bytes.getvalue() + yield value[:512] + + # Yield file content, by chunks of 4MiB + chunk_size = 4_194_304 + bytes_len = 0 + + with open(image_path, 'rb') as file: + while True: + bytes = file.read(chunk_size) + + if len(bytes) == 0: + break + + bytes_len += len(bytes) + yield bytes + + yield b'\x00' * (512 - bytes_len % 512) + return app.response_class( generate(), mimetype='application/x-tar', diff --git a/db.py b/db.py index 9004f9c..6df26ec 100755 --- a/db.py +++ b/db.py @@ -245,7 +245,6 @@ class Object: [self.id] ) acquisitions = list(map(lambda x: Acquisition.from_row(x), response.fetchall())) - print(acquisitions) return FullObject(self.id, self.name, acquisitions)