Commit 6de315fd authored by Joel Collins's avatar Joel Collins
Browse files

Drafted ZipBuilder plugin

parent af655d20
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -39,7 +39,8 @@ def plugins_representation(plugin_loader_object: PluginLoader):

        for view_id, view_data in plugin.views.items():
            logging.debug(f"Representing view {view_id}")
            uri = url_for(f"v2_plugins_blueprint.{plugin._name_python_safe}_{view_id}")
            uri = url_for(f"v2_plugins_blueprint.plugins") + view_data["rule"][1:]
            # uri = view_data["rule"]
            # Make links dictionary if it doesn't yet exist
            view_d = {"links": {"self": uri}}

@@ -90,6 +91,7 @@ def construct_blueprint(microscope_obj):
                    microscope=microscope_obj,
                    plugin=plugin,
                ),
                **plugin_view["kwargs"],
            )

    return blueprint
+0 −1
Original line number Diff line number Diff line
@@ -122,7 +122,6 @@ class BaseCamera(metaclass=ABCMeta):

        self.status = {"board": None}

        # TODO: Load/save these to config
        self.paths = {"default": BASE_CAPTURE_PATH, "temp": TEMP_CAPTURE_PATH}

        # Capture data
+1 −0
Original line number Diff line number Diff line
from .plugin import ZipBuilderPlugin
+80 −0
Original line number Diff line number Diff line
from openflexure_microscope.devel import (
    MicroscopePlugin,
    MicroscopeViewPlugin,
    JsonResponse,
    request,
    jsonify,
    taskify,
)

from flask import send_file, abort

import uuid
import zipfile
import tempfile
import logging


class ZipBuilderAPIView(MicroscopeViewPlugin):
    def post(self):

        ids = list(JsonResponse(request).json)

        task = taskify(self.plugin.build_zip_from_capture_ids)(ids)

        # Return a handle on the autofocus task
        return jsonify(task.state), 201


class ZipListAPIView(MicroscopeViewPlugin):
    def get(self):
        return jsonify(list(self.plugin.session_zips.keys()))


class ZipGetterAPIView(MicroscopeViewPlugin):
    def get(self, session_id="No session ID"):
        logging.info(f"Session ID: {session_id}")

        return send_file(
            self.plugin.zip_from_id(session_id),
            mimetype="application/zip",
            as_attachment=True,
            attachment_filename=f"{session_id}.zip",
        )


class ZipBuilderPlugin(MicroscopePlugin):
    """
    ZIP-builder plugin
    """

    def __init__(self):
        super().__init__()

        self.session_zips = {}

        self.add_view("/get/<string:session_id>", ZipGetterAPIView)
        self.add_view("/get", ZipListAPIView)

        self.add_view("/build", ZipBuilderAPIView)

    def build_zip_from_capture_ids(self, capture_id_list):
        logging.debug(capture_id_list)

        fp = tempfile.NamedTemporaryFile(delete=False)

        with zipfile.ZipFile(fp, "w") as zipObj:
            for capture_id in capture_id_list:
                capture_obj = self.microscope.camera.image_from_id(capture_id)
                filePath = capture_obj.file
                zipObj.write(filePath)

        session_id = uuid.uuid4().hex
        self.session_zips[session_id] = fp

        return session_id

    def zip_from_id(self, session_id):
        fp = self.session_zips[session_id]
        fp.seek(0)
        return fp
+3 −3
Original line number Diff line number Diff line
@@ -250,7 +250,7 @@ class BasePlugin:
    def views(self):
        return self._views

    def add_view(self, rule, view_class):
    def add_view(self, rule, view_class, **kwargs):
        # Remove all leading slashes from view route
        cleaned_rule = rule
        while cleaned_rule[0] == "/":
@@ -259,13 +259,13 @@ class BasePlugin:
        # Expand the rule to include plugin name
        full_rule = "/{}/{}".format(self._name_uri_safe, cleaned_rule)

        view_id = cleaned_rule.replace("/", "_")
        view_id = cleaned_rule.replace("/", "_").replace("<", "").replace(">", "")

        # Create a Python-safe route ID
        logging.debug(view_id)

        # Store route information in a dictionary
        d = {"rule": full_rule, "view": view_class}
        d = {"rule": full_rule, "view": view_class, "kwargs": kwargs}

        # Add view to private views dictionary
        self._views[view_id] = d