diff --git a/app.py b/app.py index eb01279..1abdb7a 100755 --- a/app.py +++ b/app.py @@ -1,12 +1,13 @@ #!/usr/bin/env python from flask import Flask, redirect, request, render_template, send_from_directory, session +import io import json import os from os.path import join import sqlite3 import uuid -from typing import Optional +import tarfile from . import db, config, scanner, calibration app = Flask(__name__) @@ -269,6 +270,53 @@ def validate_calibration(): return redirect('/') +@app.route('/download-object/') +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)) + + # 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/{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') + + @app.route('/static/') def send_static(path): return send_from_directory('static', path) diff --git a/templates/object.html b/templates/object.html index 614158e..9366b98 100644 --- a/templates/object.html +++ b/templates/object.html @@ -4,6 +4,7 @@

{{ object.name }}

+ Télécharger les données de l'objet {% if object.acquisitions %}