112 lines
3.4 KiB
Python
112 lines
3.4 KiB
Python
import json
|
|
import math
|
|
import os
|
|
import subprocess
|
|
import time
|
|
|
|
import cairocffi as cairo
|
|
import flask
|
|
import img2pdf
|
|
import pangocffi as pango
|
|
import pangocairocffi as pangocairo
|
|
import requests
|
|
|
|
class App(flask.Flask):
|
|
def __init__(self, *args, **kwargs):
|
|
super(App, self).__init__(*args, **kwargs)
|
|
self.last = 0
|
|
|
|
app = App(__name__)
|
|
|
|
class Renderer(object):
|
|
INCH_PER_MM = 0.039
|
|
DPI = 300
|
|
def __init__(self, size=(36, 89)):
|
|
width, height = [int(s * self.INCH_PER_MM * self.DPI) for s in size]
|
|
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
|
|
context = cairo.Context(surface)
|
|
|
|
context.rectangle(0, 0, width, height)
|
|
context.set_source_rgb(1, 1, 1)
|
|
context.fill()
|
|
|
|
context.translate(width, 0)
|
|
context.rotate(math.pi/2)
|
|
|
|
self.width, self.height = height, width
|
|
self.font = pango.FontDescription()
|
|
|
|
self.context = context
|
|
self.surface = surface
|
|
|
|
def export_png(self, name):
|
|
with open(name, 'wb') as f:
|
|
self.surface.write_to_png(f)
|
|
|
|
def render_text(self, text, fontname, x, y, html=False):
|
|
print("Fontname:", fontname)
|
|
self.context.save()
|
|
if y != -1:
|
|
self.context.translate(x, y)
|
|
self.context.set_antialias(cairo.ANTIALIAS_SUBPIXEL)
|
|
layout = pangocairo.create_layout(self.context)
|
|
layout._set_width(pango.units_from_double(self.width))
|
|
layout._set_alignment(pango.Alignment.CENTER)
|
|
if html:
|
|
# Absolutely horrifying hack to fix broken text wrapping
|
|
layout.apply_markup('<span font_desc="%s">%s</span>' % (fontname, text))
|
|
else:
|
|
self.font.family = fontname.split()[0]
|
|
self.font.size = pango.units_from_double(int(fontname.split()[1]))
|
|
|
|
layout.font_description = self.font
|
|
layout.text = text
|
|
if y == -1:
|
|
self.context.translate(0, (self.height - pango.units_to_double(layout.get_size()[1]))/2)
|
|
|
|
self.context.set_source_rgb(0, 0, 0)
|
|
pangocairo.update_layout(self.context, layout)
|
|
pangocairo.show_layout(self.context, layout)
|
|
|
|
self.context.restore()
|
|
|
|
@app.route('/')
|
|
def index():
|
|
return flask.render_template('index.html')
|
|
|
|
@app.route('/api/preview/<int:size>/')
|
|
def stuff_preview(size):
|
|
text = flask.request.args.get('text')
|
|
html = flask.request.args.get('html') == '1'
|
|
renderer = Renderer()
|
|
renderer.render_text(text, 'Sans {}'.format(size), 0, -1, html)
|
|
|
|
preview = renderer.surface.write_to_png()
|
|
return flask.Response(preview, mimetype='image/png')
|
|
|
|
DELAY = 5
|
|
@app.route('/api/print/<int:size>/', methods=['POST'])
|
|
def stuff_print(size):
|
|
last = app.last
|
|
print(last, time.time() - last)
|
|
if time.time() - last < DELAY:
|
|
return 'Please wait {} more seconds before next print.'.format(int(DELAY - (time.time() - last)))
|
|
text = flask.request.args.get('text')
|
|
html = flask.request.args.get('html') == '1'
|
|
renderer = Renderer()
|
|
renderer.render_text(text, 'Sans {}'.format(size), 0, -1, html)
|
|
|
|
data = renderer.surface.write_to_png()
|
|
payload = {'printer': 'dymo_labelwriter450', 'copies': 1, 'body': data}
|
|
r = requests.post(os.environ.get('PRINTSERVANT_HOST') + '/print', params=payload)
|
|
print('Printing job response', r.text)
|
|
|
|
app.last = time.time()
|
|
return 'ok'
|
|
|
|
def main():
|
|
app.run(host="0.0.0.0", port=5000, debug=True)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|