Fixed marshaling in zip_builder extension

This commit is contained in:
Joel Collins 2020-01-30 14:22:52 +00:00
parent 65fc58c651
commit 1ba840933b

View file

@ -16,9 +16,47 @@ import logging
from labthings.server.find import find_component from labthings.server.find import find_component
from labthings.server.view import View from labthings.server.view import View
from labthings.server.schema import Schema
from labthings.server import fields
from labthings.server.extensions import BaseExtension from labthings.server.extensions import BaseExtension
from labthings.server.decorators import ThingAction, ThingProperty from labthings.server.decorators import ThingAction, ThingProperty, marshal_task, marshal_with, pre_dump
class ZipObjectSchema(Schema):
id = fields.String()
data_size = fields.Number()
zip_size = fields.Number()
@pre_dump
def generate_links(self, data, **kwargs):
data.links = {
"download": {
"href": url_for(
ZipGetterAPIView.endpoint,
session_id=data.id
),
**description_from_view(ZipGetterAPIView),
},
}
return data
class ZipObjectDescription:
def __init__(self, id, file_pointer, data_size=None):
self.id = id
self.fp = file_pointer
self.data_size = data_size
self.zip_size = os.path.getsize(self.fp.name) * 1e-6
def close(self):
logging.debug(self.fp.name)
self.fp.close()
os.unlink(self.fp.name)
assert not os.path.exists(self.fp.name)
def __del__(self):
self.close()
self.super().__del__()
class ZipManager: class ZipManager:
""" """
@ -74,17 +112,16 @@ class ZipManager:
update_task_progress(int((index / n_files) * 100)) update_task_progress(int((index / n_files) * 100))
session_id = str(uuid.uuid4()) session_id = str(uuid.uuid4())
self.session_zips[session_id] = { session_description = ZipObjectDescription(session_id, fp, data_size=data_size_megabytes)
"id": session_id, self.session_zips[session_id] = session_description
"fp": fp,
"data_size": data_size_megabytes,
"zip_size": os.path.getsize(fp.name) * 1e-6,
}
return self.session_zips[session_id] return self.session_zips[session_id]
def zip_from_id(self, session_id): def marshaled_build_zip_from_capture_ids(self, *args, **kwargs):
return self.session_zips[session_id]["fp"] return ZipObjectSchema().dump(self.build_zip_from_capture_ids(*args, **kwargs))
def zip_fp_from_id(self, session_id):
return self.session_zips[session_id].fp
# Create a global ZIP manager # Create a global ZIP manager
@ -93,21 +130,23 @@ default_zip_manager = ZipManager()
@ThingAction @ThingAction
class ZipBuilderAPIView(View): class ZipBuilderAPIView(View):
@marshal_task
def post(self): def post(self):
ids = list(JsonResponse(request).json) ids = list(JsonResponse(request).json)
microscope = find_component("org.openflexure.microscope") microscope = find_component("org.openflexure.microscope")
task = taskify(default_zip_manager.build_zip_from_capture_ids)(microscope, ids) task = taskify(default_zip_manager.marshaled_build_zip_from_capture_ids)(microscope, ids)
# Return a handle on the autofocus task # Return a handle on the autofocus task
return task.state, 201 return task
@ThingProperty @ThingProperty
class ZipListAPIView(View): class ZipListAPIView(View):
@marshal_with(ZipObjectSchema(many=True))
def get(self): def get(self):
return default_zip_manager.session_zips return default_zip_manager.session_zips.values()
class ZipGetterAPIView(View): class ZipGetterAPIView(View):
@ -118,7 +157,7 @@ class ZipGetterAPIView(View):
logging.info(f"Session ID: {session_id}") logging.info(f"Session ID: {session_id}")
return send_file( return send_file(
default_zip_manager.zip_from_id(session_id).name, default_zip_manager.zip_fp_from_id(session_id).name,
mimetype="application/zip", mimetype="application/zip",
as_attachment=True, as_attachment=True,
attachment_filename=f"{session_id}.zip", attachment_filename=f"{session_id}.zip",
@ -128,15 +167,9 @@ class ZipGetterAPIView(View):
if not session_id in default_zip_manager.session_zips: if not session_id in default_zip_manager.session_zips:
return abort(404) # 404 Not Found return abort(404) # 404 Not Found
logging.info(f"Session ID: {session_id}") # Close the file
default_zip_manager.session_zips[session_id].close()
fp = default_zip_manager.zip_from_id(session_id) # Delete the file reference
logging.debug(fp.name)
fp.close()
os.unlink(fp.name)
assert not os.path.exists(fp.name)
del default_zip_manager.session_zips[session_id] del default_zip_manager.session_zips[session_id]
return {"return": session_id} return {"return": session_id}