def SnapAndPrint(self): subprocess.run(PIC_COMMAND.split(" ")) dummy = Dummy() dummy.text("\n\n\nBravoLT - GRPS - 2019\n\n\n") dummy.image("out.jpg") dummy.text("\n\n\nBravoLT - GRPS - 2019") self.printer._raw(dummy.output)
def main(): imageIn = sys.argv[1] fileOut = imageIn + "_tmp.txt" p = Dummy() p.image(imageIn) f = File(fileOut) f._raw(p.output) f.cut() subprocess.call("lpr -P THERMAL -o raw " + fileOut, shell=True) os.remove(fileOut)
def print_ticket_windows_ar(pname, ti, ofc, tnu, tas, cticket, ip, l=None): def fsizeit(text, t, f): return f.getsize(t) def center(text, t, f): fs1, fs2 = fsizeit(text, t, f) return ((text.size[0] - fs1) / 2, (text.size[1] - fs2) / 2) if name == 'nt': fpath = absolute_path('static\\gfonts\\arial.ttf') else: fpath = absolute_path('static/gfonts/arial.ttf') fonts = [ ImageFont.truetype(fpath, 50), ImageFont.truetype(fpath, 30), ImageFont.truetype(fpath, 25) ] logo = 'FQM ' + VERSION[:4] title = u'نظام إدارة الحشود الحر' title = arabic_reshaper.reshape(title) title = get_display(title) link = 'http://fqms.github.io' border = "#" * 20 ticket = str(ti) officet = u'المكتب : ' + ofc office = arabic_reshaper.reshape(officet) office = get_display(office) try: taskt = u'المهمة : ' + tas except Exception: taskt = tas task = arabic_reshaper.reshape(taskt) task = get_display(task) datet = u'الوقت : ' datet += str(datetime.now())[:-7] date = arabic_reshaper.reshape(datet) date = get_display(date) aheadt = u'تذاكر قبلك : ' aheadt += str(tnu) ahead = arabic_reshaper.reshape(aheadt) ahead = get_display(ahead) cutit = u'التذكرة الحالية : ' cutit += str(cticket) cuti = arabic_reshaper.reshape(cutit) cuti = get_display(cuti) w = 400 bt_1 = Image.new('RGB', (w, 60), "white") bt_2 = Image.new('RGB', (w, 60), "white") bt_3 = Image.new('RGB', (w, 60), "white") st_1 = Image.new('RGB', (w, 50), "white") st_2 = Image.new('RGB', (w, 50), "white") st_3 = Image.new('RGB', (w, 50), "white") st_4 = Image.new('RGB', (w, 50), "white") st_5 = Image.new('RGB', (w, 50), "white") st_6 = Image.new('RGB', (w, 50), "white") st_7 = Image.new('RGB', (w, 50), "white") st_8 = Image.new('RGB', (w, 50), "white") tt = 50 * 8 tt += 60 * 3 mt = Image.new('RGB', (w, tt), "white") bd_1 = ImageDraw.Draw(bt_1) bd_2 = ImageDraw.Draw(bt_2) bd_3 = ImageDraw.Draw(bt_3) sd_1 = ImageDraw.Draw(st_1) sd_2 = ImageDraw.Draw(st_2) sd_3 = ImageDraw.Draw(st_3) sd_4 = ImageDraw.Draw(st_4) sd_5 = ImageDraw.Draw(st_5) sd_6 = ImageDraw.Draw(st_6) sd_7 = ImageDraw.Draw(st_7) sd_8 = ImageDraw.Draw(st_8) md = ImageDraw.Draw(mt) b = "black" bd_1.text(center(bt_1, logo, fonts[0]), logo, font=fonts[0], fill=b) bd_2.text(center(bt_2, title, fonts[1]), title, font=fonts[1], fill=b) bd_3.text(center(bt_3, ticket, fonts[0]), ticket, font=fonts[0], fill=b) sd_1.text(center(st_1, link, fonts[2]), link, font=fonts[2], fill=b) sd_2.text(center(st_2, border, fonts[2]), border, font=fonts[2], fill=b) sd_3.text(center(st_3, border, fonts[2]), border, font=fonts[2], fill=b) sd_4.text(center(st_4, office, fonts[2]), office, font=fonts[2], fill=b) sd_5.text(center(st_5, task, fonts[2]), task, font=fonts[2], fill=b) sd_6.text(center(st_6, date, fonts[2]), date, font=fonts[2], fill=b) sd_7.text(center(st_7, ahead, fonts[2]), ahead, font=fonts[2], fill=b) sd_8.text(center(st_8, cuti, fonts[2]), cuti, font=fonts[2], fill=b) tts = 0 mt.paste(bt_1, (0, 0)) tts += bt_1.size[1] mt.paste(bt_2, (0, tts)) tts += bt_2.size[1] mt.paste(st_1, (0, tts)) tts += st_1.size[1] mt.paste(st_2, (0, tts)) tts += st_2.size[1] mt.paste(bt_3, (0, tts)) tts += bt_3.size[1] mt.paste(st_3, (0, tts)) tts += st_3.size[1] mt.paste(st_4, (0, tts)) tts += st_4.size[1] mt.paste(st_8, (0, tts)) tts += st_8.size[1] mt.paste(st_7, (0, tts)) tts += st_7.size[1] mt.paste(st_5, (0, tts)) tts += st_5.size[1] mt.paste(st_6, (0, tts)) sffs = [] sfs = [ f'{uuid.uuid4()}'.replace('-', '') + '.jpg', f'{uuid.uuid4()}'.replace('-', '') + '.txt' ] for f in sfs: sffs.append(path.join(getcwd(), f)) mt.save(sfs[0], format="JPEG") p = Dummy() p.image(sfs[0], fragment_height=tt, high_density_vertical=True) p.cut() f = open(sfs[1], 'wb+') f.write(p.output) p.close() f.close() text = f'print /D:\\\localhost\\"{pname}" "{sfs[1]}"' system(text) for f in sffs: if path.isfile(f): remove(f)
class Receipt: def __init__(self, uid, pid): self.p = Dummy() self.qanswered = 0 self.id = uid self.pid = pid def startRecording(self): self.start_time = time.time() self.sequence = [] self.chord = [] def recordNote(self, note): curr_time = time.time() if curr_time < self.start_time + 0.125: self.chord.append(note) else: self.sequence.append(self.chord) self.chord = [note] num_rest = (curr_time - (self.start_time + 0.125)) / 0.125 for r in xrange(int(num_rest)): self.sequence.append(None) self.start_time = self.start_time + (num_rest + 1) * 0.125 def endRecording(self): self.sequence.append(self.chord) self.addSequence(self.sequence, True) def startFreeRecording(self): self.sequence = [] def recordFreeNote(self, note): self.sequence.append((note, time.time())) def endFreeRecording(self): self.addFreeSequence(self.sequence) def saveToText(self, fn): f = File(fn) f._raw(self.p.output) f.cut() def addFreeSequence(self, sequence): seq_len = len(sequence) if seq_len != 0: self.createFreeSequence(sequence[0][1] - 0.5, sequence[seq_len - 1][1] + 0.5, sequence) self.p.image("line.ppm") def addSequence(self, notes_list, half=False): for n in notes_list: if n is None: self.addRest(half) else: self.addChord(n, half) def addChord(self, notes, half=False): if half: self.createChordHalf(notes) else: self.createChord(notes) self.p.image("line.ppm") def addRest(self, half=False): if half: self.p.image("empty_half.ppm") else: self.p.image("empty.ppm") def createFreeSequence(self, start_time, end_time, sequence): width = col_end + 1 height = int(row_height * (end_time - start_time) / 0.25) img = Image.new('RGB', (width, height), "white") pixels = img.load() for n, t in sequence: x_cent = self.getXForNote(n) y_cent = int(row_height * (t - start_time) / 0.25) for i in xrange(x_cent - 5, x_cent + 5): for j in xrange(y_cent - 5, y_cent + 5): pixels[i, j] = (0, 0, 0) for j in xrange(height): pixels[col_end, j] = (0, 0, 0) img.save('line.ppm') def createChord(self, notes): width = col_end + 1 height = row_height img = Image.new('RGB', (width, height), "white") pixels = img.load() for n in notes: i_cent = self.getXForNote(n) for i in xrange(i_cent - 5, i_cent + 5): for j in xrange(row_height / 2 - 5, row_height / 2 + 5): pixels[i, j] = (0, 0, 0) for j in xrange(height): pixels[col_end, j] = (0, 0, 0) img.save('line.ppm') def createChordHalf(self, notes): width = col_end + 1 height = row_height_half img = Image.new('RGB', (width, height), "white") pixels = img.load() for n in notes: i_cent = self.getXForNote(n) for i in xrange(i_cent - 5, i_cent + 5): for j in xrange(row_height_half / 2 - 5, row_height_half / 2 + 5): pixels[i, j] = (0, 0, 0) for j in xrange(height): pixels[col_end, j] = (0, 0, 0) img.save('line.ppm') def resetRest(self): img = Image.new('RGB', (col_end + 1, row_height), "white") pixels = img.load() for j in xrange(row_height): pixels[col_end, j] = (0, 0, 0) img.save('empty.ppm') img = Image.new('RGB', (col_end + 1, row_height_half), "white") pixels = img.load() for j in xrange(row_height_half): pixels[col_end, j] = (0, 0, 0) img.save('empty_half.ppm') def getXForNote(self, note): return col_lead + col_width * note
class Receipt: def __init__(self): from escpos.printer import Usb, Dummy self.eps = Usb(0x4b8, 0x0e03) self.dps = Dummy() def print_header(self, opts): """Responsible for printing the header part of the receipt, :param:opts: include all options that could go into the header like logo, company name and all that """ if COMPANY_LOGO in opts.keys(): self.imgesprint(opts[COMPANY_LOGO]) self.esprint(LINE_BREAK) if COMPANY_NAME in opts.keys(): self.esprint(opts[COMPANY_NAME]) self.esprint(LINE_BREAK) if COMPANY_CONTACT in opts.keys(): self.esprint(TEL) self.esprint(opts[COMPANY_CONTACT]) self.esprint(LINE_BREAK) if COMPANY_LOCATION in opts.keys(): self.esprint(LOC) self.esprint(opts[COMPANY_LOCATION]) self.esprint(LINE_BREAK) self.n_char(SN_RULER, PAPER_MAX_WIDTH, w=1, h=1) self.esprint(LINE_BREAK) if RECEIPT_NAME in opts.keys(): RNO = opts[RECEIPT_NUMBER] if RECEIPT_NUMBER in opts.keys() else '' RECEIPT = opts[RECEIPT_NAME] + SPACE_CHAR + HASH_NO + RNO self.cesprint(RECEIPT) char = len(RECEIPT) self.cesprint(self.n_char_generate(DO_RULER, char), w=1, h=2) self.esprint(LINE_BREAK) if CUSTOMER_NAME in opts.keys(): self.lesprint(CUSTOMER, LEFT_PROPERTY_WIDTH) self.esprint(COLON_CHAR) self.n_char(SPACE_CHAR, LR_ALIGN) self.esprint(opts[CUSTOMER_NAME]) self.esprint(LINE_BREAK) if CASHIER_NAME in opts.keys(): self.lesprint(CASHIER, LEFT_PROPERTY_WIDTH) self.esprint(COLON_CHAR) self.n_char(SPACE_CHAR, LR_ALIGN) self.esprint(opts[CASHIER_NAME]) self.esprint(LINE_BREAK) if RECEIPT_DATE in opts.keys(): self.lesprint(DATE, LEFT_PROPERTY_WIDTH) self.esprint(COLON_CHAR) self.n_char(SPACE_CHAR, LR_ALIGN) self.esprint(opts[RECEIPT_DATE]) self.esprint(LINE_BREAK) if CURRENCY_NAME in opts.keys(): self.lesprint(CURRENCY_NAME_TITLE, LEFT_PROPERTY_WIDTH) self.esprint(COLON_CHAR) self.n_char(SPACE_CHAR, LR_ALIGN) self.esprint(opts[CURRENCY_NAME]) self.esprint(LINE_BREAK) def print_items(self, items): """Responsible for printing the receipt part of the receipt. """ self.n_char(SN_RULER, PAPER_MAX_WIDTH, w=1, h=1) self.esprint(LINE_BREAK) self.esprint(ITEM_TITLE) self.n_char(SPACE_CHAR, ITEM_TITLE_SPACE_AFTER) self.esprint(QTY_TITLE) self.n_char(SPACE_CHAR, QTY_TITLE_SPACE_AFTER) self.esprint(SP_TITLE) self.n_char(SPACE_CHAR, SP_TITLE_SPACE_AFTER) self.esprint(TOTAL_TITLE) self.n_char(SPACE_CHAR, TOTAL_TITLE_SPACE_AFTER) self.esprint(LINE_BREAK) self.n_char(DO_RULER, PAPER_MAX_WIDTH, w=1, h=2) self.esprint(LINE_BREAK) sum_total = 0 for item in items: product = item[ITEM] if len(item[ITEM]) < ITEM_MAX_WIDTH else item[ ITEM][:ITEM_MAX_WIDTH - ELIPSES_WIDTH] + ELIPSES qty = item[QTY] if isinstance(item[QTY], int) else round( str_2_num(item[QTY]), 2) price = round(str_2_num(item[SP]), 2) total = round(qty * price, 2) sum_total += total self.print_space(product, ITEM_MAX_WIDTH) self.print_space(str(qty), QTY_MAX_WIDTH) self.print_space(str(price), SP_MAX_WIDTH) self.print_space(str(total), TOTAL_MAX_WIDTH) self.esprint(LINE_BREAK) self.n_char(SN_RULER, PAPER_MAX_WIDTH, w=1, h=1) self.esprint(LINE_BREAK) self.esprint(TOTAL_TXT) leave = TOTAL_TXT_WIDTH self.n_char(SPACE_CHAR, PAPER_MAX_WIDTH - TOTAL_MAX_WIDTH - leave, w=1, h=1) self.esprint(str(sum_total)) self.esprint(LINE_BREAK) self.n_char(DO_RULER, PAPER_MAX_WIDTH, w=1, h=2) self.esprint(LINE_BREAK) def print_message(self, msg): self.cesprint(msg, char=STAR_CHAR) self.esprint(LINE_BREAK) def print_vat(self, vmsg): self.esprint(LINE_BREAK) self.cesprint(vmsg) self.esprint(LINE_BREAK) def print_me(self, me): self.esprint(me) def print_space(self, text, width, w=1, h=1): """Print text and then print space character for remaining space = width - texlen. For now texlen is not expected to be greater than width, if so just truncate to width. """ texlen = len(text) if texlen > width: text = text[:width] self.lesprint(text, width) def imgesprint(self, path, align='center'): """Responsible for image printing""" self.dps.set(align=align) self.dps.image(path) def esprint(self, text, w=1, h=1): """A prudent wrapper around printing text with [self.eps.text()]""" self.dps.set(height=h, width=w) self.dps.text(text) def escut(self): self.eps.cut() def estop(self): self.eps.close() def cesprint(self, text, width=PAPER_MAX_WIDTH, char=SPACE_CHAR, w=1, h=1): """center align text and fill space left with :param:char:""" texlen = len(text) if texlen > width: diff = width % texlen else: diff = width - texlen if diff == 0: ldiff = rdiff = 0 elif diff % 2 == 0: ldiff = rdiff = diff // 2 else: ldiff = diff // 2 rdiff = ldiff + 1 self.n_char(char, ldiff) self.esprint(text, w, h) self.n_char(char, rdiff) def resprint(self, text, width=PAPER_MAX_WIDTH, char=SPACE_CHAR, w=1, h=1): """right align text and fill space left with :param:char:""" texlen = len(text) diff = width - texlen self.n_char(char, diff) self.esprint(text, w, h) def lesprint(self, text, width=PAPER_MAX_WIDTH, char=SPACE_CHAR, w=1, h=1): """light align text and fill space left with :param:char:""" texlen = len(text) diff = width - texlen self.esprint(text, w, h) self.n_char(char, diff, w, h) def n_char(self, char, n, w=1, h=1): """Print char n times""" for i in range(n): self.esprint(char, w, h) def n_char_generate(self, char, n): """ Return string of char n time""" return char * n def get_longest_item(self, items): """Return the length of the longest Item name in the list of items """ # Assume longest is initially zero longest = 0 for item in items: # get length of item name length = len(item[ITEM]) if length > longest: longest = length return longest def esecute(self): self.eps._raw(self.dps.output)
class EscPosPrint(BasePrint): ''' print data to a ESC/POS printer. ''' font = 'A' def __init__(self, encode=None, **kwargs): BasePrint.__init__(self, **kwargs) from escpos.printer import Dummy self.dummy = Dummy() if encode: self.dummy.codepage = encode self.dummy.hw('init') self.texts = [] def _get_char_width(self, c): w = BasePrint._get_char_width(self, c) if self.font == 'A': w = w * 12 elif self.font == 'B': if w == 1: w = 9 else: w = 16 return w def print_text(self, text): self.texts.append(text) self.dummy.text(text) def _set_with_node(self, node): font = get_node_attr(node, 'font', '') align = get_node_attr(node, 'align', '') size = get_node_attr_int(node, 'size', 0) text_type = 'B' if get_node_attr(node, 'bold', '') else '' + 'U' if get_node_attr(node, 'underline', '') else '' setd = {} if font: setd['font'] = font self.font = font if align: setd['align'] = align if size: setd['width'] = size setd['height'] = size if text_type: setd['text_type'] = text_type if setd: self.dummy.set(**setd) def _handle_node(self, node): tag = node.tagName.lower() if tag in ['table', 'text', 'td', 'tr']: self._set_with_node(node) BasePrint._handle_node(self, node) def handle_cut(self, node): self.dummy.cut() def handle_image(self, node): src = get_node_attr(node, 'src', '') path = self.get_url_to_path(src) if path: from PIL import Image img = Image.open(path) img = align_image(img, self.width, get_node_attr(node, 'align', 'left')) self.dummy.image(img) def handle_img(self, node): self.handle_image(node) def handle_qrcode(self, node): native = get_node_attr(node, 'native', 'False').upper() == 'TRUE' code = get_node_text(node) size = get_node_attr_int(node, 'size', 5) if not native: img = get_qrcode_image(code, size=size) img = align_image(img, self.width, get_node_attr(node, 'align', 'left')) self.dummy.image(img) else: self.dummy.qr(code, size=size, native=native) def handle_barcode(self, node): native = get_node_attr(node, 'native', 'False').upper() == 'TRUE' codetype = get_node_attr(node, 'type', 'EAN13').lower() code = get_node_text(node) if not native: import qrcode img = get_barcode_image(code, codetype=codetype) img = align_image(img, self.width, get_node_attr(node, 'align', 'left')) self.dummy.image(img) else: self.dummy.barcode(code, codetype.upper(), font=get_node_attr(node, 'font', 'A').upper(), pos=get_node_attr(node, 'pos', 'BELOW').upper(), function_type=get_node_attr(node, 'function', 'B').upper()) def handle_beep(self, node): self.dummy._raw(b'\x1B\x42\x01\x01') def raw_send(self, msg): self.dummy._raw(msg) def get_data(self): return self.dummy.output def get_text(self): return ''.join(self.texts)