From e1be1c5f082376e1de403975d6219863148a5a22 Mon Sep 17 00:00:00 2001 From: s3lph Date: Tue, 7 Jan 2020 23:02:26 +0100 Subject: [PATCH] Initial commit, state from 36C3 --- .gitignore | 2 + escpos.service | 14 ++++++ escpos/__init__.py | 0 escpos/__main__.py | 118 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 .gitignore create mode 100644 escpos.service create mode 100644 escpos/__init__.py create mode 100644 escpos/__main__.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7099c39 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.pyc +**/__pycache__ diff --git a/escpos.service b/escpos.service new file mode 100644 index 0000000..cf6443d --- /dev/null +++ b/escpos.service @@ -0,0 +1,14 @@ +[Unit] +Description=ESC/POS Print Job Submission Web Interface +After=multi-user.target + +[Service] +Environment=PYTHONUNBUFFERED=1 +ExecStart=/home/escpos/escpos/venv/bin/python3 /home/escpos/escpos/__main__.py +User=escpos +WorkingDirectory=-/home/escpos/escpos +AmbientCapabilities=CAP_NET_BIND_SERVICE +NoNewPrivileges=true + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/escpos/__init__.py b/escpos/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/escpos/__main__.py b/escpos/__main__.py new file mode 100644 index 0000000..acc537d --- /dev/null +++ b/escpos/__main__.py @@ -0,0 +1,118 @@ +from bottle import run, get, post, request +from threading import Lock, Event, Thread +from queue import Queue +import serial +import cgi +import copy +import sys + + +# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE +# Version 2, December 2004 +# +# Copyright (C) 2019, SPiNNiX +# Everyone is permitted to copy and distribute verbatim or modified +# copies of this license document, and changing it is allowed as long +# as the name is changed. +# +# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE +# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +# +# 0. You just DO WHAT THE FUCK YOU WANT TO. + +lock = Lock() +queue = Queue() +stop_event = Event() + + +TEMPLATE=''' + + + + Toilet Paper as a Service + + + +

TPaaS - Toilet Paper as a Service

+

Submit Print Job

+
+ Give your print job a name:
+

+ + + +

+ A single line on toilet paper is up to 44 characters long.
+ There are three print modes: + + Pick up your print at CCC-CH assembly. +

Print Queue

+
    +{printqueue} +
+ + +''' + + + +@get('/') +def home(): + with queue.mutex: + q = copy.copy(queue.queue) + items = [f'{" "*12}
  • {x[0]}
  • \n' for x in q] + return TEMPLATE.format(printqueue=''.join(items)) + +@post("/") +def web(): + action = 'wrap' + if request.forms.action in ['wrap', 'cut', 'test']: + action = request.forms.action + content = request.forms.get("txt") or '' + name = cgi.html.escape(request.forms.get("printjob") or '') + queue.put((name, content, action)) + return home() + + +def prt(): + with serial.Serial("/dev/ttyUSB0", 19200, xonxoff=True) as s: + print('tty opened', file=sys.stderr) + while not stop_event.is_set(): + name, content, action = queue.get() + print(f'now printing: {name}', file=sys.stderr) + if action == 'wrap': + output = '' + for line in content.split("\r\n"): + while len(line) > 44: + l, line = line[0:44], line[44:] + l = l or ' ' + output += f'{" "*22}{l}\n' + line = line or ' ' + output += f'{" "*22}{line}\n' + nln = len([1 for x in output.split("\n")]) + print(f'Printing {nln} lines in wrap mode', file=sys.stderr) + s.write(output.encode('cp437', errors='ignore')) + elif action == 'cut': + output = '' + for line in content.split("\r\n"): + line = line or ' ' + output += f'{" "*22}{line[0:44]}\n' + nln = len([1 for x in output.split("\n")]) + print(f'Printing {nln} lines in wrap mode', file=sys.stderr) + s.write(output.encode('cp437', errors='ignore')) + elif action == 'test': + print('Printing hello world', file=sys.stderr) + s.write(f'{" "*22}HELLO, 36C3 - TOILET PAPER EXHAUSTION\n'.encode('cp437', errors='ignore')) + +def main(): + t = Thread(target=prt) + t.start() + run(host='0.0.0.0', port=80, debug=True) + + +if __name__ == '__main__': + main()