Example #1
0
def gcode_delete(org_uuid, uuid):
    validate_uuid(uuid)
    gcode = gcodes.get_gcode(uuid)
    if gcode is None or gcode["organization_uuid"] != org_uuid:
        return abort(make_response(jsonify(message="Not found"), 404))
    user = get_current_user()
    org_role = organization_roles.get_organization_role(org_uuid, user["uuid"])
    if (user["uuid"] != gcode["user_uuid"] and user["system_role"] != "admin"
            and org_role["role"] != "admin"):
        return abort(
            make_response(
                jsonify(message="G-Code does not belong to %s" % user["uuid"]),
                401))
    try:
        files.remove(gcode["absolute_path"])
    except IOError:
        pass
    finally:
        printjobs.update_gcode_data(
            uuid,
            {
                "uuid": gcode["uuid"],
                "user_uuid": gcode["user_uuid"],
                "filename": gcode["filename"],
                "size": gcode["size"],
                "available": False,
            },
        )
        gcodes.delete_gcode(uuid)
    return "", 204
Example #2
0
 def test_upload_path(self, mocked_save, mocked_delay):
     with app.test_client() as c:
         c.set_cookie("localhost", "access_token_cookie", TOKEN_USER)
         data = dict(file=(io.BytesIO(b"my file contents"), "some.gcode"),
                     path="/a/b")
         response = c.post(
             "/organizations/%s/gcodes" % UUID_ORG,
             data=data,
             content_type="multipart/form-data",
             headers={"x-csrf-token": TOKEN_USER_CSRF},
         )
         self.assertEqual(response.status_code, 201)
         args, kwargs = mocked_save.call_args
         self.assertEqual(args[2], "/a/b")
         self.assertTrue("uuid" in response.json)
         self.assertTrue("user_uuid" in response.json)
         self.assertEqual(response.json["user_uuid"], UUID_USER)
         self.assertTrue("path" in response.json)
         self.assertTrue("filename" in response.json)
         self.assertTrue("display" in response.json)
         self.assertTrue("absolute_path" in response.json)
         self.assertTrue("uploaded" in response.json)
         self.assertTrue("size" in response.json)
         gcode_db_data = gcodes.get_gcode(response.json["uuid"])
         self.assertEqual(gcode_db_data["user_uuid"], UUID_USER)
Example #3
0
def gcode_delete(id):
    gcode = gcodes.get_gcode(id)
    if gcode is None:
        return abort(make_response("", 404))
    user = get_current_user()
    if user["uuid"] != gcode["user_uuid"] and user["role"] not in ["admin"]:
        return abort(
            make_response(
                jsonify(message="G-Code does not belong to %s" % user["uuid"]),
                401))
    try:
        files.remove(gcode["absolute_path"])
    except IOError:
        pass
    finally:
        gcodes.delete_gcode(id)
        printjobs.update_gcode_data(
            gcode["id"],
            {
                "id": gcode["id"],
                "user_uuid": gcode["user_uuid"],
                "filename": gcode["filename"],
                "size": gcode["size"],
                "available": False,
            },
        )
    return "", 204
Example #4
0
 def test_delete(self):
     gcode_id = gcodes.add_gcode(
         path="delete-ab/c",
         filename="delete-gcode-specific-file1",
         display="file-display",
         absolute_path="/ab/a/b/c",
         size=123,
         user_uuid=UUID_USER,
     )
     printjobs.add_printjob(
         gcode_id=gcode_id,
         gcode_data={"id": gcode_id},
         printer_uuid="20e91c14-c3e4-4fe9-a066-e69d53324a20",
         printer_data={"host": "172.16.236.11:8080"},
     )
     printjobs.add_printjob(
         gcode_id=gcode_id,
         gcode_data={"id": gcode_id},
         printer_uuid="20e91c14-c3e4-4fe9-a066-e69d53324a20",
         printer_data={"host": "172.16.236.11:8080"},
     )
     with app.test_client() as c:
         c.set_cookie("localhost", "access_token_cookie", TOKEN_USER)
         response = c.delete(
             "/gcodes/%s" % gcode_id, headers={"x-csrf-token": TOKEN_USER_CSRF},
         )
         self.assertEqual(response.status_code, 204)
     self.assertEqual(gcodes.get_gcode(gcode_id), None)
     pjs = [pj for pj in printjobs.get_printjobs() if pj["gcode_id"] == gcode_id]
     self.assertEqual(len(pjs), 2)
     for pj in pjs:
         self.assertFalse(pj["gcode_data"]["available"])
Example #5
0
def gcode_detail(id):
    gcode = gcodes.get_gcode(id)
    if gcode is None:
        return abort(make_response("", 404))
    user = users.get_by_uuid(gcode.get("user_uuid"))
    user_mapping = {}
    if user is not None:
        user_mapping[gcode.get("user_uuid")] = user.get("username")
    return jsonify(make_gcode_response(gcode, None, user_mapping))
Example #6
0
def gcode_detail(org_uuid, uuid):
    validate_uuid(uuid)
    gcode = gcodes.get_gcode(uuid)
    if gcode is None or gcode["organization_uuid"] != org_uuid:
        return abort(make_response(jsonify(message="Not found"), 404))
    user = users.get_by_uuid(gcode.get("user_uuid"))
    user_mapping = {}
    if user is not None:
        user_mapping[gcode.get("user_uuid")] = user.get("username")
    return jsonify(make_gcode_response(gcode, None, user_mapping))
Example #7
0
def gcode_file(id):
    gcode = gcodes.get_gcode(id)
    if gcode is None:
        return abort(make_response("", 404))
    try:
        return send_file(
            gcode["absolute_path"],
            as_attachment=True,
            attachment_filename=gcode["filename"],
        )
    except FileNotFoundError:
        return abort(make_response("", 404))
Example #8
0
def analyze_gcode(gcode_id):
    gcode = gcodes.get_gcode(gcode_id)
    if not gcode:
        app.logger.info("Gcode %s does not exist in database" % gcode_id)
        return
    if gcode.get("analysis", {}) != {}:
        app.logger.info("Gcode %s already has analysis data" % gcode_id)
        return
    try:
        result = {
            "filament": {},
            "temperatures": {},
            "time": {},
            "slicer": None
        }
        # TODO this should be faster if we grep for only lines with ; in shell
        with open(gcode["absolute_path"]) as fp:
            for lno, rawline in enumerate(fp):
                stripped_line = rawline.rstrip()
                line = (stripped_line.decode("utf-8") if hasattr(
                    stripped_line, "decode") else stripped_line)
                if not line or line[0] not in ";M":
                    continue
                # TODO this supports only a single filament
                if not result["slicer"]:
                    result["slicer"] = get_slicer(line)
                filament_props = [
                    ("length_mm", get_filament_used_length),
                    ("volume_cm3", get_filament_used_volume),
                    ("type", get_filament_type),
                ]
                for fprop, evaluator in filament_props:
                    if not result["filament"].get(fprop, None):
                        result["filament"][fprop] = evaluator(line)
                # TODO this supports only a single tool
                temperature_props = [
                    ("bed", get_temperature_bed),
                    ("bed_first", get_temperature_bed_first),
                    ("tool0", get_temperature_tool),
                    ("tool0_first", get_temperature_tool_first),
                ]
                for fprop, evaluator in temperature_props:
                    if not result["temperatures"].get(fprop, None):
                        result["temperatures"][fprop] = evaluator(line)
                time_props = [("estimate_s", get_time_estimate)]
                for fprop, evaluator in time_props:
                    if not result["time"].get(fprop, None):
                        result["time"][fprop] = evaluator(line)
        gcodes.set_analysis(gcode_id, result)
    except FileNotFoundError:
        app.logger.error("Gcode file not found %s" % gcode["absolute_path"])
        return
Example #9
0
def gcode_file(org_uuid, uuid):
    validate_uuid(uuid)
    gcode = gcodes.get_gcode(uuid)
    if gcode is None or gcode["organization_uuid"] != org_uuid:
        return abort(make_response(jsonify(message="Not found"), 404))
    try:
        return send_file(
            gcode["absolute_path"],
            as_attachment=True,
            attachment_filename=gcode["filename"],
        )
    except FileNotFoundError:
        return abort(make_response(jsonify(message="File not found"), 404))
Example #10
0
def printjob_create():
    data = request.json
    if not data:
        return abort(make_response("", 400))
    gcode_id = data.get("gcode", None)
    printer_uuid = data.get("printer", None)
    if not gcode_id or not printer_uuid:
        return abort(make_response("", 400))
    printer = printers.get_printer(printer_uuid)
    if printer is None:
        return abort(make_response("", 404))
    gcode = gcodes.get_gcode(gcode_id)
    if gcode is None:
        return abort(make_response("", 404))
    try:
        printer_inst = clients.get_printer_instance(printer)
        uploaded = printer_inst.upload_and_start_job(gcode["absolute_path"],
                                                     gcode["path"])
        if not uploaded:
            return abort(
                make_response(
                    jsonify(message="Cannot upload the g-code to the printer"),
                    500))
        printjob_id = printjobs.add_printjob(
            gcode_id=gcode["id"],
            printer_uuid=printer["uuid"],
            user_uuid=get_current_user()["uuid"],
            gcode_data={
                "id": gcode["id"],
                "filename": gcode["filename"],
                "size": gcode["size"],
                "available": True,
            },
            printer_data={
                "ip": printer["ip"],
                "port": printer["port"],
                "hostname": printer["hostname"],
                "name": printer["name"],
                "client": printer["client"],
            },
        )
        return (
            jsonify({
                "id": printjob_id,
                "user_uuid": get_current_user()["uuid"]
            }),
            201,
        )
    except clients.utils.PrinterClientException:
        return abort(make_response("", 409))
Example #11
0
def gcode_delete(id):
    gcode = gcodes.get_gcode(id)
    if gcode is None:
        return abort(404)
    try:
        files.remove(gcode["absolute_path"])
    except IOError:
        pass
    finally:
        gcodes.delete_gcode(id)
        printjobs.update_gcode_data(
            gcode["id"],
            {
                "id": gcode["id"],
                "filename": gcode["filename"],
                "size": gcode["size"],
                "available": False,
            },
        )
    return "", 204
Example #12
0
def printjob_create():
    data = request.json
    if not data:
        return abort(400)
    gcode_id = data.get("gcode", None)
    printer_ip = data.get("printer", None)
    if not gcode_id or not printer_ip:
        return abort(400)
    printer = printers.get_printer(printer_ip)
    if printer is None:
        return abort(404)
    gcode = gcodes.get_gcode(gcode_id)
    if gcode is None:
        return abort(404)
    try:
        printer_inst = drivers.get_printer_instance(printer)
        uploaded = printer_inst.upload_and_start_job(gcode["absolute_path"],
                                                     gcode["path"])
        if not uploaded:
            return abort(500, "Cannot upload the g-code to the printer")
        printjob_id = printjobs.add_printjob(
            gcode_id=gcode["id"],
            printer_ip=printer["ip"],
            gcode_data={
                "id": gcode["id"],
                "filename": gcode["filename"],
                "size": gcode["size"],
                "available": True,
            },
            printer_data={
                "ip": printer["ip"],
                "name": printer["name"],
                "client": printer["client"],
            },
        )
        return jsonify({"id": printjob_id}), 201
    except drivers.utils.PrinterDriverException:
        return abort(409)
Example #13
0
def printjob_create(org_uuid):
    data = request.json
    if not data:
        return abort(make_response(jsonify(message="Missing payload"), 400))
    gcode_uuid = data.get("gcode", None)
    printer_uuid = data.get("printer", None)
    if not gcode_uuid or not printer_uuid:
        return abort(
            make_response(jsonify(message="Missing gcode_uuid or printer_uuid"), 400)
        )
    validate_uuid(gcode_uuid)
    validate_uuid(printer_uuid)
    printer = printers.get_printer(printer_uuid)
    if printer is None or printer["organization_uuid"] != org_uuid:
        return abort(make_response(jsonify(message="Not found"), 404))
    gcode = gcodes.get_gcode(gcode_uuid)
    if gcode is None:
        return abort(make_response(jsonify(message="Not found"), 404))
    try:
        network_client = network_clients.get_network_client(
            printer["network_client_uuid"]
        )
        printer_data = dict(network_client)
        printer_data.update(dict(printer))
        printer_inst = clients.get_printer_instance(printer_data)
        uploaded = printer_inst.upload_and_start_job(
            gcode["absolute_path"], gcode["path"]
        )
        if not uploaded:
            return abort(
                make_response(
                    jsonify(message="Cannot upload the g-code to the printer"), 500
                )
            )
        printjob_uuid = guid.uuid4()
        printjobs.add_printjob(
            uuid=printjob_uuid,
            gcode_uuid=gcode["uuid"],
            organization_uuid=org_uuid,
            printer_uuid=printer["uuid"],
            user_uuid=get_current_user()["uuid"],
            gcode_data={
                "uuid": gcode["uuid"],
                "filename": gcode["filename"],
                "size": gcode["size"],
                "available": True,
            },
            printer_data={
                "ip": printer_inst.ip,
                "port": printer_inst.port,
                "hostname": printer_inst.hostname,
                "name": printer_inst.name,
                "client": printer_inst.client,
            },
        )
        return (
            jsonify({"uuid": printjob_uuid, "user_uuid": get_current_user()["uuid"]}),
            201,
        )
    except clients.utils.PrinterClientException as e:
        app.logger.error(e)
        return abort(
            make_response(
                jsonify(message="Cannot schedule a printjob: %s" % str(e)), 409
            )
        )
Example #14
0
def printjob_create(org_uuid):
    data = request.json
    if not data:
        return abort(make_response(jsonify(message="Missing payload"), 400))
    gcode_uuid = data.get("gcode", None)
    printer_uuid = data.get("printer",
                            None)  # FIXME: this should be part of the path
    if not gcode_uuid or not printer_uuid:
        return abort(
            make_response(
                jsonify(message="Missing gcode_uuid or printer_uuid"), 400))

    printer = printers.get_printer(printer_uuid)
    if not printer or printer['organization_uuid'] != org_uuid:
        raise http_exceptions.UnprocessableEntity(
            f"Invalid printer {printer_uuid} - does not exist.")

    gcode = gcodes.get_gcode(gcode_uuid)
    if not gcode:
        raise http_exceptions.UnprocessableEntity(
            "Invalid gcode {gcode_uuid} - does not exist.")

    network_client = network_clients.get_network_client(
        printer["network_client_uuid"])
    printer_data = dict(network_client)
    printer_data.update(dict(printer))
    printer_inst = clients.get_printer_instance(printer_data)
    try:
        printer_inst.upload_and_start_job(gcode["absolute_path"],
                                          gcode["path"])
    except DeviceInvalidState as e:
        raise http_exceptions.Conflict(*e.args)
    except DeviceCommunicationError as e:
        raise http_exceptions.GatewayTimeout(*e.args)
    # TODO: robin - add_printjob should be method of printer and printer a
    #               method of organization
    printjob_uuid = printjobs.add_printjob(
        gcode_uuid=gcode["uuid"],
        organization_uuid=org_uuid,
        printer_uuid=printer["uuid"],
        user_uuid=get_current_user()["uuid"],
        gcode_data={
            "uuid": gcode["uuid"],
            "filename": gcode["filename"],
            "size": gcode["size"],
            "available": True,
        },
        # FIXME: printer data should be kept in printer object only
        printer_data={
            "ip": printer_inst.ip,
            "port": printer_inst.port,
            "hostname": printer_inst.hostname,
            "name": printer_inst.name,
            "client": printer_inst.client,
        },
    )
    return (
        jsonify({
            "uuid": printjob_uuid,
            "user_uuid": get_current_user()["uuid"]
        }),
        201,
    )
Example #15
0
def gcode_detail(id):
    gcode = gcodes.get_gcode(id)
    if gcode is None:
        return abort(404)
    return jsonify(make_gcode_response(gcode))