Compare commits
4 commits
627be60a6c
...
ce6f228d79
Author | SHA1 | Date | |
---|---|---|---|
ce6f228d79 | |||
be87d1f78c | |||
3753236897 | |||
54200ef718 |
9 changed files with 110 additions and 43 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,9 +1,8 @@
|
||||||
conf/*.json
|
queue/*
|
||||||
conf/*.db
|
archive/*
|
||||||
.DS_Store
|
.DS_Store
|
||||||
node_modules/
|
node_modules/
|
||||||
__pycache__
|
__pycache__
|
||||||
storage/*
|
|
||||||
npm-debug*.log
|
npm-debug*.log
|
||||||
ssl/*.pem
|
ssl/*.pem
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
|
58
dist/index.html
vendored
58
dist/index.html
vendored
|
@ -1,22 +1,52 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<link rel="stylesheet" type="text/css" href="/static/css/iziToast.min.css">
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
<script src="/static/js/iziToast.min.js"></script>
|
<link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/css/jquery.toast.min.css">
|
||||||
|
<script src="/static/js/jquery-3.4.1.min.js"></script>
|
||||||
|
<script src="/static/js/bootstrap.min.js"></script>
|
||||||
|
<script src="/static/js/jquery.toast.min.js"></script>
|
||||||
<script src="/static/js/httprint.js"></script>
|
<script src="/static/js/httprint.js"></script>
|
||||||
<title>HTTPrint</title>
|
<title>HTTPrint</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Upload a file to print</h1>
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
File to print: <input id="upload-file" type="file" />
|
<div class="col-sm">
|
||||||
<br>
|
<div class="jumbotron jumbotron-fluid">
|
||||||
<br>
|
<div class="container">
|
||||||
Number of copies: <input id="copies" type="number" min="1" max="10" value="1" />
|
<h1 class="display-4">HTTPrint</h1>
|
||||||
<br>
|
<p class="lead">Upload and print a <strong>PDF file</strong>. The maximum number of pages that can be printed is <strong>10</strong>.</p>
|
||||||
<br>
|
Instructions:
|
||||||
<button onClick="uploadFile();">print</button>
|
<ol>
|
||||||
|
<li>Upload a file, select the number of copies and click the "print" button</li>
|
||||||
|
<li>Write down the code you will receive</li>
|
||||||
|
<li>head to the printer</li>
|
||||||
|
<li>insert the code in the touchpad</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="upload-file">File to print</label>
|
||||||
|
<input id="upload-file" type="file" class="form-control-file">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="copies">Number of copies</label>
|
||||||
|
<input id="copies" type="number" min="1" max="10" value="1" class="form-control">
|
||||||
|
</div>
|
||||||
|
<button id="print-btn" class="btn-lg btn-primary">print</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="footer mt-auto py-3">
|
||||||
|
<div class="container">
|
||||||
|
<span class="text-muted">
|
||||||
|
HTTPrint <a href="https://github.com/alberanid/httprint">https://github.com/alberanid/httprint</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
7
dist/static/css/bootstrap.min.css
vendored
Normal file
7
dist/static/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/static/css/jquery.toast.min.css
vendored
Normal file
1
dist/static/css/jquery.toast.min.css
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
.jq-toast-wrap,.jq-toast-wrap *{margin:0;padding:0}.jq-toast-wrap{display:block;position:fixed;width:250px;pointer-events:none!important;letter-spacing:normal;z-index:9000!important}.jq-toast-wrap.bottom-left{bottom:20px;left:20px}.jq-toast-wrap.bottom-right{bottom:20px;right:40px}.jq-toast-wrap.top-left{top:20px;left:20px}.jq-toast-wrap.top-right{top:20px;right:40px}.jq-toast-single{display:block;width:100%;padding:10px;margin:0 0 5px;border-radius:4px;font-size:12px;font-family:arial,sans-serif;line-height:17px;position:relative;pointer-events:all!important;background-color:#444;color:#fff}.jq-toast-single h2{font-family:arial,sans-serif;font-size:14px;margin:0 0 7px;background:0 0;color:inherit;line-height:inherit;letter-spacing:normal}.jq-toast-single a{color:#eee;text-decoration:none;font-weight:700;border-bottom:1px solid #fff;padding-bottom:3px;font-size:12px}.jq-toast-single ul{margin:0 0 0 15px;background:0 0;padding:0}.jq-toast-single ul li{list-style-type:disc!important;line-height:17px;background:0 0;margin:0;padding:0;letter-spacing:normal}.close-jq-toast-single{position:absolute;top:3px;right:7px;font-size:14px;cursor:pointer}.jq-toast-loader{display:block;position:absolute;top:-2px;height:5px;width:0;left:0;border-radius:5px;background:red}.jq-toast-loaded{width:100%}.jq-has-icon{padding:10px 10px 10px 50px;background-repeat:no-repeat;background-position:10px}.jq-icon-info{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=);background-color:#31708f;color:#d9edf7;border-color:#bce8f1}.jq-icon-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=);background-color:#8a6d3b;color:#fcf8e3;border-color:#faebcc}.jq-icon-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=);background-color:#a94442;color:#f2dede;border-color:#ebccd1}.jq-icon-success{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==);color:#dff0d8;background-color:#3c763d;border-color:#d6e9c6}
|
7
dist/static/js/bootstrap.min.js
vendored
Normal file
7
dist/static/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
61
dist/static/js/httprint.js
vendored
61
dist/static/js/httprint.js
vendored
|
@ -1,42 +1,61 @@
|
||||||
function uploadFile() {
|
function uploadFile() {
|
||||||
let photo = document.getElementById("upload-file").files[0];
|
let photo = document.getElementById("upload-file").files[0];
|
||||||
let copies = document.getElementById('copies').value;
|
let copies = document.getElementById("copies").value;
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
|
|
||||||
formData.append("file", photo);
|
formData.append("file", photo);
|
||||||
formData.append("copies", copies);
|
formData.append("copies", copies);
|
||||||
var uploadField = document.getElementById('upload-file');
|
var uploadField = document.getElementById("upload-file");
|
||||||
fetch("/api/upload", {method: "POST", body: formData})
|
fetch("/api/upload", {method: "POST", body: formData})
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
return response.json();
|
return response.json();
|
||||||
})
|
})
|
||||||
.then(function(reply) {
|
.then(function(reply) {
|
||||||
if (reply && !reply.error) {
|
if (reply && !reply.error) {
|
||||||
iziToast.success({
|
$.toast({
|
||||||
title: "DONE!",
|
text: reply.message || "file sent to printer",
|
||||||
message: reply.message,
|
heading: "DONE!",
|
||||||
position: 'topCenter',
|
icon: "success",
|
||||||
timeout: false,
|
showHideTransition: "fade",
|
||||||
closeOnEscape: true,
|
allowToastClose: true,
|
||||||
layout: 2
|
hideAfter: false,
|
||||||
|
stack: 5,
|
||||||
|
position: "top-center"
|
||||||
});
|
});
|
||||||
|
uploadField.value = null;
|
||||||
|
copies.value = 1;
|
||||||
} else {
|
} else {
|
||||||
iziToast.error({
|
$.toast({
|
||||||
title: "ERROR!",
|
text: reply.message || "unable to print file",
|
||||||
message: reply.message,
|
heading: "ERROR!",
|
||||||
position: 'topCenter',
|
icon: "error",
|
||||||
layout: 2
|
showHideTransition: "fade",
|
||||||
|
allowToastClose: true,
|
||||||
|
hideAfter: 5000,
|
||||||
|
stack: 5,
|
||||||
|
position: "top-center"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
uploadField.value = null;
|
|
||||||
})
|
})
|
||||||
.catch(function(err) {
|
.catch(function(err) {
|
||||||
iziToast.error({
|
console.log(err);
|
||||||
title: "ERROR!",
|
$.toast({
|
||||||
message: "failed to send file",
|
text: "failed to send file",
|
||||||
position: 'topCenter',
|
heading: "ERROR!",
|
||||||
layout: 2
|
icon: "error",
|
||||||
|
showHideTransition: "fade",
|
||||||
|
allowToastClose: true,
|
||||||
|
hideAfter: 5000,
|
||||||
|
stack: 5,
|
||||||
|
position: "top-center"
|
||||||
});
|
});
|
||||||
uploadField.value = null;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function(event) {
|
||||||
|
let pbutton = document.getElementById("print-btn");
|
||||||
|
pbutton.addEventListener("click", function(event) {
|
||||||
|
uploadFile();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
2
dist/static/js/jquery-3.4.1.min.js
vendored
Normal file
2
dist/static/js/jquery-3.4.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/static/js/jquery.toast.min.js
vendored
Normal file
1
dist/static/js/jquery.toast.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -241,10 +241,11 @@ class UploadHandler(BaseHandler):
|
||||||
failure = True
|
failure = True
|
||||||
out = out.decode('utf-8', errors='ignore')
|
out = out.decode('utf-8', errors='ignore')
|
||||||
pages = int(re_pages.findall(out)[0])
|
pages = int(re_pages.findall(out)[0])
|
||||||
if pages * copies > self.cfg.max_pages and self.cfg.check_pdf_pages:
|
if pages * copies > self.cfg.max_pages and self.cfg.check_pdf_pages and not failure:
|
||||||
self.build_error('too many pages to print (%d)' % (pages * copies))
|
self.build_error('too many pages to print (%d)' % (pages * copies))
|
||||||
failure = True
|
failure = True
|
||||||
except Exception:
|
except Exception:
|
||||||
|
if not failure:
|
||||||
self.build_error('unable to get PDF information')
|
self.build_error('unable to get PDF information')
|
||||||
failure = True
|
failure = True
|
||||||
pass
|
pass
|
||||||
|
|
Loading…
Reference in a new issue