179 lines
6.7 KiB
Python
179 lines
6.7 KiB
Python
# Importing the module to mage the connection to the printer.
|
||
from flask import flash
|
||
from escpos.printer import Usb, USBNotFoundError
|
||
from time import sleep, gmtime, strftime
|
||
import os.path
|
||
from PIL import Image
|
||
|
||
|
||
class Printer(object):
|
||
"""
|
||
# The connection is based on the ESC/POS library
|
||
|
||
## Connection to the USB printer
|
||
|
||
## Making sure the printer is alive
|
||
|
||
## Making sure it has paper
|
||
|
||
## Define default print settings
|
||
|
||
## Print starting message, log time of first print, cut.
|
||
|
||
## Annonce readyness : return a positive pong message.
|
||
"""
|
||
|
||
# Is the printer ready to accept a new print ?
|
||
ready = False
|
||
|
||
def __init__(self, app, device_id, vendor_id):
|
||
super(Printer, self).__init__()
|
||
self.app = app
|
||
self.ready = False
|
||
self.printer = None
|
||
self.device_id = device_id
|
||
self.vendor_id = vendor_id
|
||
self.usb_args = {}
|
||
self.usb_args['idVendor'] = self.device_id
|
||
self.usb_args['idProduct'] = self.vendor_id
|
||
|
||
def check_paper(self) -> bool:
|
||
# Let's check paper status
|
||
self.app.logger.debug('Checking paper status...')
|
||
self.printer.open(self.usb_args)
|
||
status = self.printer.paper_status()
|
||
match status:
|
||
case 0:
|
||
self.app.logger.error('Printer has no more paper, aborting...')
|
||
flash("No more paper on the printer. Sorry.",category='error')
|
||
self.printer.close()
|
||
return False
|
||
case 1:
|
||
self.app.logger.warning('Printer needs paper to be changed very soon ! ')
|
||
flash('Printer needs paper to be changed very soon ! ', category='info')
|
||
self.printer.close()
|
||
return True
|
||
case 2:
|
||
self.app.logger.debug('Printer has paper, good to go')
|
||
self.printer.close()
|
||
return True
|
||
|
||
def init_printer(self):
|
||
|
||
# Is the printer online ? Is the communication with the printer successfull ?
|
||
waiting_elapsed = 30
|
||
self.app.logger.debug('Waiting for printer to get online...')
|
||
|
||
while not self.ready:
|
||
try:
|
||
# This also calls open(), which we need to close()
|
||
# or else the device will appear as busy.
|
||
p = Usb(self.device_id, self.vendor_id, 0, profile="TM-P80")
|
||
except USBNotFoundError as e:
|
||
self.app.logger.error("The USB device is not plugged in, trying again : " + str(e))
|
||
pass
|
||
|
||
try:
|
||
if p.is_online():
|
||
self.ready = True
|
||
self.app.logger.debug('Printer online !')
|
||
except Exception as e:
|
||
pass
|
||
|
||
sleep(1)
|
||
waiting_elapsed -= 1
|
||
if waiting_elapsed < 1:
|
||
self.app.logger.error('Printer took more than 30 seconds to get online, aborting...')
|
||
waiting_elapsed = 30 # Reset the waiting time for the next print.
|
||
return False
|
||
|
||
|
||
|
||
|
||
# Setting up the printing options.
|
||
p.set(align='center', font='a', bold=False, underline=0, width=1, height=1, density=9, invert=False, smooth=False, flip=False, double_width=False, double_height=False, custom_size=False)
|
||
# Beware : if we print every time the printer becomes ready, it means
|
||
# we are printing before and after every print !
|
||
self.printer = p
|
||
self.ready = True;
|
||
self.printer.close();
|
||
|
||
if not self.check_paper():
|
||
return False
|
||
|
||
return True
|
||
|
||
def print_sms(self, msg, signature) -> bool:
|
||
clean_msg = str(msg)
|
||
clean_signature = str(signature)
|
||
|
||
if not self.check_paper():
|
||
return False
|
||
|
||
if len(clean_msg) > 256 or len(clean_msg) < 3 :
|
||
self.app.logger.warning("Could not print message of this length: " + str(len(clean_msg)))
|
||
flash("Could not print message of this length :" + str(len(clean_msg)) + ", needs to between 3 and 256 caracters long.",category='error')
|
||
return False
|
||
|
||
if len(signature) > 256 or len(signature) < 3:
|
||
self.app.logger.warning("Could not print message without a signature.")
|
||
flash("Could not print message without a signature.",category='error')
|
||
return False
|
||
|
||
if not os.getenv('LIPY_DEBUG') == True:
|
||
try:
|
||
self.printer.open(self.usb_args);
|
||
self.printer.set(align='left', font='a', bold=False, underline=0, width=1, height=1, density=8, invert=False, smooth=True, flip=False, double_width=False, double_height=False, custom_size=False)
|
||
self.printer.textln(clean_msg)
|
||
self.printer.set(align='left', font='b', bold=False, underline=1, width=1, height=1, density=9, invert=False, smooth=True, flip=False, double_width=False, double_height=False, custom_size=False)
|
||
self.printer.textln("> " + clean_signature + " @ " + strftime("%Y-%m-%d %H:%M:%S", gmtime()))
|
||
self.printer.cut()
|
||
self.printer.close
|
||
except Exception as e:
|
||
flash("Unable to print because : " + e)
|
||
|
||
flash("Message printed : " + clean_msg ,category='info')
|
||
return True
|
||
|
||
def print_img(self, path, sign):
|
||
clean_signature = str(sign)
|
||
|
||
if not os.path.isfile(str(path)):
|
||
self.app.logger.warning("File does not exist : " + str(path))
|
||
flash('The file path for this image :' + str(path) + " wasn't found. Please try again.", 'error')
|
||
return False
|
||
else:
|
||
self.app.logger.debug("Printing file from " + str(path))
|
||
|
||
|
||
|
||
try:
|
||
self.app.logger.debug("Resizing the image")
|
||
with Image.open(path) as im:
|
||
|
||
basewidth = 575
|
||
img = Image.open(path)
|
||
wpercent = (basewidth/float(img.size[0]))
|
||
hsize = int((float(img.size[1])*float(wpercent)))
|
||
img = img.resize((basewidth,hsize), Image.ANTIALIAS)
|
||
if img.height > 1000:
|
||
flash("Image is too long, sorry ! Keep it below 500×1000 pixels.",'error')
|
||
return False
|
||
img.save(path)
|
||
except Exception as e:
|
||
flash(str(e))
|
||
self.app.logger.error(str(e))
|
||
|
||
try:
|
||
self.printer.open(self.usb_args)
|
||
self.printer.textln("> " + clean_signature + " @ " + strftime("%Y-%m-%d %H:%M:%S", gmtime()))
|
||
self.printer.image(path)
|
||
self.printer.cut()
|
||
self.printer.close()
|
||
self.app.logger.debug("Printed an image : " + str(path))
|
||
return True
|
||
except Exception as e:
|
||
self.printer.close()
|
||
flash(str(e),'error')
|
||
return False
|