Example #1
0
def write_image_surface(doc, printer, resolution=96):
    dppx = resolution / 96

    # This duplicates the hinting logic in Page.paint. There is a
    # dependency cycle otherwise:
    #   this → hinting logic → context → surface → this
    # But since we do no transform here, cairo_context.user_to_device and
    # friends are identity functions.
    widths = [int(math.ceil(p.width * dppx)) for p in doc.pages]
    heights = [
        int(math.ceil(p._page_box.children[0].height * dppx))
        for p in doc.pages
    ]

    max_width = max(widths)
    printer._raw(escpos.constants.ESC + b"3\x16")
    for page, width, height in zip(doc.pages, widths, heights):
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, max_width, height)
        context = cairo.Context(surface)
        pos_x = (max_width - width) / 2
        page.paint(context, pos_x, 0, scale=dppx, clip=True)
        target = io.BytesIO()
        surface.write_to_png(target)
        target.seek(0)
        im = Image.open(target)
        im.load()
        im = convert_image(im)
        print_image(im, printer)
    printer._raw(escpos.constants.ESC + b"2")
Example #2
0
def on_message(client, userdata: Context, msg: mqtt.MQTTMessage):
    try:
        payload = json.loads(msg.payload)
    except json.decoder.JSONDecodeError as e:
        print(f"JSON decode error {e}", flush=True)
        return

    subject = payload.get("subject")
    if subject is None:
        subject = "None"
    message = payload.get("message")
    if message is None:
        return
    attachments = payload.get("attachments")
    if attachments is None:
        attachments = {}
    sender = payload.get("from")

    formatted_time = time.strftime("%Y-%m-%dT%H:%M:%S")
    printer = userdata.printer

    print(f"New email from {sender}, subject: {subject}", flush=True)
    print(message, flush=True)

    # Print header
    parse_html(
        printer,
        TEMPLATE.render(subject=subject, time=formatted_time, sender=sender),
        {})

    # Print message
    parse_html(printer, message, attachments)
    printer._raw(b"\n" * 3)
    print("Done!", flush=True)
Example #3
0
def print_image(im: Image.Image, printer: escpos.escpos.Escpos):
    outp = []
    header = escpos.constants.ESC + b"*\x21" + struct.pack("<H", im.width)
    im = im.transpose(Image.ROTATE_270).transpose(Image.FLIP_LEFT_RIGHT)
    line_height = 24
    width_pixels, height_pixels = im.size
    top = 0
    left = 0
    while left < width_pixels:
        box = (left, top, left + line_height, top + height_pixels)
        im_slice = im.transform((line_height, height_pixels), Image.EXTENT,
                                box)
        im_bytes = im_slice.tobytes()
        outp.append(header + im_bytes + b"\n")
        left += line_height
    printer._raw(b''.join(outp))
Example #4
0
def print_codepage(printer, codepage):
    printer.charcode(codepage)

    # Table header
    printer.set(text_type='B')
    printer._raw("  %s\n" % " ".join(map(lambda s: hex(s)[2:], range(0, 16))))
    printer.set()

    # The table
    for x in range(0, 16):
        # First column
        printer.set(text_type='B')
        printer._raw("%s " % hex(x)[2:])
        printer.set()

        for y in range(0, 16):
            byte = six.int2byte(x * 16 + y)

            if byte in (ESC, CTL_LF, CTL_FF, CTL_CR, CTL_HT, CTL_VT):
                byte = ' '

            printer._raw(byte)
            printer._raw(" ")
        printer._raw('\n')
def print_codepage(printer, codepage):
    if codepage.isdigit():
        codepage = int(codepage)
        printer._raw(CODEPAGE_CHANGE + six.int2byte(codepage))
        printer._raw("after")
    else:
        printer.charcode(codepage)

    sep = ""

    # Table header
    printer.set(text_type='B')
    printer._raw("  {}\n".format(
        sep.join(map(lambda s: hex(s)[2:], range(0, 16)))))
    printer.set()

    # The table
    for x in range(0, 16):
        # First column
        printer.set(text_type='B')
        printer._raw("{} ".format(hex(x)[2:]))
        printer.set()

        for y in range(0, 16):
            byte = six.int2byte(x * 16 + y)

            if byte in (ESC, CTL_LF, CTL_FF, CTL_CR, CTL_HT, CTL_VT):
                byte = ' '

            printer._raw(byte)
            printer._raw(sep)
        printer._raw('\n')
def print_codepage(printer, codepage):
    if codepage.isdigit():
        codepage = int(codepage)
        printer._raw(CODEPAGE_CHANGE + six.int2byte(codepage))
        printer._raw("after")
    else:
        printer.charcode(codepage)

    sep = ""

    # Table header
    printer.set(text_type='B')
    printer._raw("  {}\n".format(sep.join(map(lambda s: hex(s)[2:], range(0, 16)))))
    printer.set()

    # The table
    for x in range(0, 16):
        # First column
        printer.set(text_type='B')
        printer._raw("{} ".format(hex(x)[2:]))
        printer.set()

        for y in range(0, 16):
            byte = six.int2byte(x * 16 + y)

            if byte in (ESC, CTL_LF, CTL_FF, CTL_CR, CTL_HT, CTL_VT):
                byte = ' '

            printer._raw(byte)
            printer._raw(sep)
        printer._raw('\n')
Example #7
0
    # Print header
    parse_html(
        printer,
        TEMPLATE.render(subject=subject, time=formatted_time, sender=sender),
        {})

    # Print message
    parse_html(printer, message, attachments)
    printer._raw(b"\n" * 3)
    print("Done!", flush=True)


if __name__ == "__main__":
    printer = escpos.printer.Usb(0x0416, 0x5011)
    #printer = escpos.printer.Dummy()
    printer._raw(escpos.constants.ESC + b"@")

    context = Context(printer)

    client = mqtt.Client(userdata=context)
    client.on_connect = on_connect
    client.message_callback_add("printer/print", on_message)

    client.connect(os.getenv("MQTT_SERVER", "172.30.2.10"), 1883, 60)

    while True:
        try:
            client.loop()
        except (KeyboardInterrupt, SystemExit):
            print("Bye!")
            break