raven/laserkutter: use nginx as reverse proxy #28
8 changed files with 198 additions and 1 deletions
|
|
@ -4,6 +4,7 @@
|
|||
./dnsmasq.nix
|
||||
./dyndns.nix
|
||||
./labsync
|
||||
./laserkutter.nix
|
||||
./unifi-controller.nix
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
''}
|
||||
'';
|
||||
|
|
|
|||
31
machines/raven/services/laserkutter.nix
Normal file
31
machines/raven/services/laserkutter.nix
Normal 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";
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
@ -2,4 +2,5 @@
|
|||
|
||||
{
|
||||
mitgliedsantrag = callPackage ./mitgliedsantrag { };
|
||||
laser-upload = callPackage ./laser-upload { };
|
||||
}
|
||||
|
|
|
|||
18
pkgs/fablab/laser-upload/default.nix
Normal file
18
pkgs/fablab/laser-upload/default.nix
Normal 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;
|
||||
};
|
||||
}
|
||||
21
pkgs/fablab/laser-upload/src/index.html
Normal file
21
pkgs/fablab/laser-upload/src/index.html
Normal 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 & Drop files here</p>
|
||||
</div>
|
||||
<input type="file" class="file-upload" onchange="fileUploadChanged(event);"/>
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
119
pkgs/fablab/laser-upload/src/index.js
Normal file
119
pkgs/fablab/laser-upload/src/index.js
Normal 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;
|
||||
};
|
||||
|
||||
6
pkgs/fablab/laser-upload/src/style.css
Normal file
6
pkgs/fablab/laser-upload/src/style.css
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
.drop-zone {
|
||||
border: 5px solid blue;
|
||||
width: 600px;
|
||||
height: 337px;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue