raven/laserkutter: use nginx as reverse proxy #28

Open
jalr wants to merge 2 commits from laserkutter into main
8 changed files with 198 additions and 1 deletions
Showing only changes of commit 12829bdedc - Show all commits

View file

@ -4,6 +4,7 @@
./dnsmasq.nix
./dyndns.nix
./labsync
./laserkutter.nix
./unifi-controller.nix
];
}

View file

@ -22,7 +22,7 @@
no-hosts
addn-hosts=${pkgs.writeText "hosts.dnsmasq" ''
192.168.94.1 raven labsync unifi
192.168.94.1 raven labsync unifi upload.laserkutter.lab.fablab-nea.de proxy.laserkutter.lab.fablab-nea.de
192.168.94.2 switch
''}
'';

View file

@ -0,0 +1,31 @@
{ pkgs, ... }:
{
services.nginx.virtualHosts."upload.laserkutter.lab.fablab-nea.de" = {
root = pkgs.fablab.laser-upload;
};
services.nginx.virtualHosts."proxy.laserkutter.lab.fablab-nea.de" = {
# "/rr_upload"
#basicAuthFile =
# Basic Auth password file for a vhost. Can be created via: htpasswd -c <filename> <username>. WARNING: The generate file contains the users' passwords in a non-cryptographically-securely hashed way.
extraConfig = ''
set $duet_web "laserkutter.lab.fablab-nea.de";
allow 192.168.94.0/24;
deny all;
location / {
if ($request_method = OPTIONS ) {
add_header 'Access-Control-Allow-Origin' 'http://upload.laserkutter.lab.fablab-nea.de';
add_header 'Access-Control-Allow-Methods' 'POST';
add_header 'Access-Control-Allow-Headers' 'Content-Type';
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
break;
}
add_header 'Access-Control-Allow-Origin' 'http://upload.laserkutter.lab.fablab-nea.de';
proxy_set_header Origin "http://$duet_web";
proxy_pass "http://$duet_web";
}
'';
};
}

View file

@ -2,4 +2,5 @@
{
mitgliedsantrag = callPackage ./mitgliedsantrag { };
laser-upload = callPackage ./laser-upload { };
}

View file

@ -0,0 +1,18 @@
{ lib, stdenvNoCC }:
stdenvNoCC.mkDerivation {
name = "laser-upload";
src = ./src;
dontBuild = true;
installPhase = ''
mkdir $out
cp * $out
'';
meta = with lib; {
license = licenses.mit;
platforms = platforms.all;
};
}

View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>LaserKutter Job Control</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<input type="checkbox" id="autostart" name="autostart" value="enable">
<label for="autostart"> Nach dem Upload automatisch starten</label><br>
<div class="drop-zone" ondrop="dropHandler(event);" ondragover="event.preventDefault();">
<p>Drag &amp; Drop files here</p>
</div>
<input type="file" class="file-upload" onchange="fileUploadChanged(event);"/>
<script src="index.js"></script>
</body>
</html>

View file

@ -0,0 +1,119 @@
var lasercutter = "http://proxy.laserkutter.lab.fablab-nea.de";
// https://gist.github.com/azat/2762138
var crc32 = function(str) {
for(var i=256, tbl=[], crc, j; i--; tbl[i]=crc>>>0){
j=8;for(crc=i;j--;)crc=crc&1?crc>>>1^0xEDB88320:crc>>>1;
}
return function(str) {
for(var n=0, crc=-1; n<str.length; ++n)
crc=tbl[crc&255^str.charCodeAt(n)]^crc>>>8;
return crc^-1;
}
}();
function signedToUnsigned(number, bits){
let msb=1 <<(bits - 1);
let mask=~((~0) <<(bits - 1));
if (number & msb) {
return (number & mask) + msb * Math.sign(msb);
}
else {
return number;
}
}
function crc32_hex(data) {
return signedToUnsigned(crc32(data), 32).toString(16);
}
function connect(fn) {
var xhr = new XMLHttpRequest();
xhr.open("GET", `${lasercutter}/rr_connect?password=`);
xhr.addEventListener('load', fn());
xhr.send(content);
};
function uploadFile(file) {
connect(function() {
var uploadName=`0:/gcodes/${file.name}`;
const reader = new FileReader();
reader.addEventListener('load', function() {
var content = this.result;
var invalid = /^M5$/gm;
var content = content.replace(invalid, "");
var content = content.replace(/^M8$/gm, "M106 P1 S255 ; Air-assist on");
var content = content.replace(/^M9$/gm, "M106 P1 S0 ; Air-assist off");
console.log(content);
var checksum = crc32_hex(content);
var now = new Date().toISOString();
var url = `${lasercutter}/rr_upload?name=${uploadName}&time=${now}&crc32=${checksum}`;
var xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.addEventListener('loadend', function() {
console.log(xhr.responseText);
});
xhr.addEventListener('load', function() {
if (document.querySelector('#autostart').checked) {
startGcode(uploadName);
}
});
xhr.send(content);
});
reader.readAsText(file);
});
};
function startGcode(name) {
connect(function() {
var url = `${lasercutter}/rr_gcode?gcode=M32 "${name}"`;
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
console.log(xhr.responseText);
}
};
xhr.send();
});
};
function dropHandler(ev) {
ev.preventDefault();
if (!ev.dataTransfer.items) {
return;
}
for (var i = 0; i < ev.dataTransfer.items.length; i++) {
if (ev.dataTransfer.items[i].kind !== 'file') {
continue;
}
var file = ev.dataTransfer.items[i].getAsFile();
uploadFile(file);
}
};
function fileUploadChanged(ev) {
for (var i = 0; i < ev.target.files.length; i++) {
var file = ev.target.files[i];
uploadFile(file);
}
ev.target.value = null;
};

View file

@ -0,0 +1,6 @@
.drop-zone {
border: 5px solid blue;
width: 600px;
height: 337px;
}