Initial commit, state from 36C3
This commit is contained in:
commit
e1be1c5f08
4 changed files with 134 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*.pyc
|
||||
**/__pycache__
|
14
escpos.service
Normal file
14
escpos.service
Normal file
|
@ -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
|
0
escpos/__init__.py
Normal file
0
escpos/__init__.py
Normal file
118
escpos/__main__.py
Normal file
118
escpos/__main__.py
Normal file
|
@ -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='''
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Toilet Paper as a Service</title>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<h1>TPaaS - Toilet Paper as a Service</h1>
|
||||
<h2>Submit Print Job</h2>
|
||||
<form action="/" method="post">
|
||||
Give your print job a name: <input name="printjob" /><br/>
|
||||
<textarea name="txt" cols="44" rows="22"></textarea><br/><br/>
|
||||
<input name="action" value="wrap" type="submit" />
|
||||
<input name="action" value="cut" type="submit" />
|
||||
<input name="action" value="test" type="submit" />
|
||||
</form><br/>
|
||||
A single line on toilet paper is up to 44 characters long.<br/>
|
||||
There are three print modes:
|
||||
<ul>
|
||||
<li><tt>wrap</tt>: Lines longer than 44 characters are wrapped.</li>
|
||||
<li><tt>cut</tt>: Only the first 44 characters of each line are printed.</li>
|
||||
<li><tt>test</tt>: Prints a special test message.</li>
|
||||
</ul>
|
||||
Pick up your print at <a href="https://36c3.c3nav.de/l/c:0:482.75:484.16/">CCC-CH assembly</a>.
|
||||
<h2>Print Queue</h2>
|
||||
<ol>
|
||||
{printqueue}
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
|
||||
|
||||
|
||||
@get('/')
|
||||
def home():
|
||||
with queue.mutex:
|
||||
q = copy.copy(queue.queue)
|
||||
items = [f'{" "*12}<li>{x[0]}</li>\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()
|
Loading…
Reference in a new issue