Commit 4e67d248 authored by Joel Collins's avatar Joel Collins
Browse files

Added capture state endpoint

parent 52d667fe
Loading
Loading
Loading
Loading
+48 −23
Original line number Diff line number Diff line
@@ -30,6 +30,19 @@ var fovY = 3146;
window.onload = function() {
    getStagePositions()
    updateTextBoxes()
    getCaptures()
}

function getCaptures() {
    function updateCapturesCallback(response, status) {
        console.log(status);
        updateCaptures(response);
    }
    safeRequest("GET", baseURI+"/capture", null, updateCapturesCallback, false)
}

function updateCaptures(response) {
    console.log(response)
}

function updateTextBoxes() {
@@ -53,7 +66,7 @@ function getStagePositions() {
        console.log(status, response);
        updateStagePositions(response);
    }
    safeRequest("GET", baseURI+"/position", null, updatePositionCallback)
    safeRequest("GET", baseURI+"/position", null, updatePositionCallback, false)
}

function setStagePositions(x_abs, y_abs, z_abs) {
@@ -169,11 +182,20 @@ addEventListener("keyup", function (e) {
}, false);

// Methods for making requests
function safeRequest(method, url, payload, callback) {
    if (requestLock == false) {
function safeRequest(method, url, payload, callback, lock=true, force=false) {
    if (force == true) {
        allowRequest = true;
    }
    else {
        allowRequest = !(requestLock);
    }
    if (allowRequest == true) {
        var xhr = new XMLHttpRequest();   // new HttpRequest instance 
        xhr.open(method, url);

        if (lock == true) {
            requestLock = true;
        }

        xhr.onload = function (e) {
            if (xhr.readyState === 4) {
@@ -182,7 +204,10 @@ function safeRequest(method, url, payload, callback) {
                } 
                callback(JSON.parse(xhr.responseText), xhr.status);
            }

            if (lock == true) {
                requestLock = false;
            }
        };

        if (method == "POST" || method == "PUT") {
+9 −0
Original line number Diff line number Diff line
@@ -64,3 +64,12 @@ img {
    display: table;
}

/* Data divs */

#captures {
    font-size:12px;
}

.capture {
    background-color: #d3d3d3;
}
 No newline at end of file
+5 −1
Original line number Diff line number Diff line
@@ -73,7 +73,11 @@

      <div class="column right">
        <h2>Captures</h2>
        <div id="captures">
          <p>Not yet implemented.</p>
          <div class="capture">Capture 1</div>
        </div>
        
      </div>

      <div class="column middle">
+11 −0
Original line number Diff line number Diff line
@@ -13,3 +13,14 @@ def gen(camera):

        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')


def get_bool(get_arg):
    """Convert GET request argument string to a Python bool"""
    if (
        get_arg == 'true' or
        get_arg == 'True' or
        get_arg == '1'):
        return True
    else:
        return False
 No newline at end of file
+59 −1
Original line number Diff line number Diff line
#!/usr/bin/env python
"""
TODO: Add proper docstrings
TODO: Bind to port 80
TODO: Reimplement capture methods
TODO: Implement API route to cleanly shut down server
@@ -18,7 +19,7 @@ from flask import (

import numpy as np

from openflexure_microscope.api.utilities import parse_payload, gen
from openflexure_microscope.api.utilities import parse_payload, gen, get_bool

from openflexure_microscope import Microscope
from openflexure_microscope.camera.pi import StreamingCamera
@@ -59,6 +60,9 @@ def stream():
    """Video streaming route. Put this in the src attribute of an img tag."""
    global microscope

    # Restart stream worker thread
    microscope.camera.start_worker()

    return Response(
        gen(microscope.camera),
        mimetype='multipart/x-mixed-replace; boundary=frame')
@@ -115,5 +119,59 @@ def position():

    return jsonify(microscope.state['position'])

# Capture routes
@app.route(uri('/capture'), methods=['GET', 'POST', 'PUT'])
def capture():
    """Return JSONified microscope state"""
    global microscope

    if request.method == 'POST' or request.method == 'PUT':
        state = parse_payload(request)
        print(state)

        if 'filename' in state:
            filename = state['filename']
        else:
            filename = None

        if 'keep_on_disk' in state:
            keep_on_disk = bool(state['keep_on_disk'])
        else:
            keep_on_disk = True

        if 'use_video_port' in state:
            use_video_port = bool(state['use_video_port'])
        else:
            use_video_port = False

        if 'size' in state:
            if 'width' in state['size'] and 'height' in state['size']:
                resize = (state['size']['width'], state['size']['height'])
            else:
                raise Exception("Invalid resize parameters passed. Ensure both width and height are specified.")
        else:
            resize = None

        capture_obj = microscope.camera.capture(
            write_to_file=True,  # Always write data to disk when using API
            keep_on_disk=keep_on_disk,
            use_video_port=use_video_port,
            filename=filename,
            resize=resize)

        return jsonify(capture_obj.metadata)

    else:  # GET requests
        include_unavailable = get_bool(request.args.get('include_unavailable'))

        if include_unavailable:
            captures = [image for image in microscope.camera.images if image.metadata['available']]
        else:
            captures = microscope.camera.images

        metadata_array = [capture.metadata for capture in captures]

        return jsonify(metadata_array)

if __name__ == '__main__':
    app.run(host='0.0.0.0', threaded=True, debug=True, use_reloader=False)
Loading