-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththermald.py
executable file
·138 lines (106 loc) · 3.44 KB
/
thermald.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/python
import argparse
import os
import time
from functools import wraps
from http import HTTPStatus
from io import BytesIO
from queue import Queue
from threading import Thread
from uuid import uuid4
import requests
import waitress
from PIL import Image
from flask import Flask, request
from flask_cors import CORS
from adapters.tagadapter import TagAdapter
from adathermal import ThermalPrinter
app = Flask(__name__)
CORS(app)
print_queue = Queue()
stop_sentinel = object()
class PrintTask:
def __init__(self, format_type, body):
self.format_type = format_type
self.body = body
def requires_auth():
def wrapper(f):
@wraps(f)
def wrapped(*wargs, **kwargs):
if request.headers.get("X-API-KEY") != os.environ.get("API_KEY"):
return "You are not authorized to perform this action", HTTPStatus.UNAUTHORIZED
return f(*wargs, **kwargs)
return wrapped
return wrapper
@app.route("/", methods=["GET"])
@requires_auth()
def index():
return ""
@app.route("/print", methods=["POST"])
@requires_auth()
def add_print_task():
format_type = request.json.get("format", "tag")
if format_type not in ["plain", "tag"]:
return "Bad format", HTTPStatus.BAD_REQUEST
body = request.json["body"]
print_queue.put(PrintTask(format_type, body))
return "OK"
@app.route("/print-image", methods=["POST"])
@requires_auth()
def add_image_print_task():
if 'file' not in request.files:
return "Missing `file`", HTTPStatus.BAD_REQUEST
path = "/tmp/{}".format(uuid4())
request.files['file'].save(path)
print_queue.put(PrintTask("image-file", path))
return "OK"
@app.route("/print-image-url", methods=["POST"])
@requires_auth()
def add_image_print_url_task():
image_url = request.json.get("url")
image_data = requests.get(image_url).content
print_queue.put(PrintTask("image-data", BytesIO(image_data)))
return "OK"
def create_printer(args):
if not args.stdout:
return ThermalPrinter("/dev/serial0", 19200, timeout=5)
else:
return ThermalPrinter()
def print_loop(args):
printer = create_printer(args)
tag_adapter = TagAdapter(printer)
while True:
try:
# Attempt a write to verify that printer is connected
printer.set_size('S')
except IOError as e:
print("Failed to connect to printer: {}".format(e))
time.sleep(1)
printer = create_printer(args)
continue
try:
task = print_queue.get()
if task is stop_sentinel:
break
if task.format_type == "tag":
tag_adapter.print(task.body)
elif task.format_type == "image-file":
printer.print_image(Image.open(task.body))
os.remove(task.body)
elif task.format_type == "image-data":
printer.print_image(Image.open(task.body))
else:
printer.print(task.body)
printer.print("\n" * 3)
print_queue.task_done()
except IOError as e:
print("Failed to print task: {}".format(e))
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--stdout', action='store_true')
args = parser.parse_args()
Thread(target=print_loop, args=(args,)).start()
waitress.serve(app, port=8080)
print_queue.put(stop_sentinel)
if __name__ == "__main__":
main()