예제 #1
0
def main():
    parser = ArgumentParser(
        description="Print an illustration for a proxy by ID")
    parser.add_argument("id", help="ID of the proxy to print")
    parser.add_argument("-d",
                        "--database-path",
                        help="Path to RandomProxyPrinter basic database",
                        required=True,
                        dest="database_path")
    parser.add_argument("-p",
                        "--printer",
                        help="Path to printer device",
                        required=True)
    parser.add_argument("-r",
                        "--printer-baudrate",
                        help="Printer baudrate",
                        default=19200,
                        dest="baudrate")

    args = parser.parse_args()

    printer = Serial(args.printer, baudrate=args.baudrate)
    connection = connect(args.database_path)
    connection.row_factory = Row
    cursor = connection.cursor()

    cursor.execute("SELECT illustration FROM proxies WHERE id = ?",
                   (args.id, ))
    row = cursor.fetchone()

    printer.image(Image.open(BytesIO(row["illustration"])),
                  impl="bitImageColumn")
예제 #2
0
class bonprinter:
    def __init__(self, logger, config, printq):
        self.logger = logger
        self.cf = config
        self.printq = printq
        #self.p = None
        self.p = Serial(devfile='/dev/ttyUSB1',
                        baudrate=38400,
                        bytesize=8,
                        parity='N',
                        stopbits=1,
                        timeout=1.00,
                        dsrdtr=False,
                        profile="TM-T88II")
        self.pprint = printerpreter(self.p)  # pretty printer

    def brrr(self, context):
        for item in self.printq:
            if item['printed'] is False:
                context.bot.send_message(chat_id=item['id'], text=printing_text)
                self.printq.update(tdbop.set("printed", True), Query().date == item['date'])
                # mark as printed so errors dont result in infinite loops
                if item['text'] is not None:
                    self.pprint.printbon(item['text'])
                if item['image'] is not None:
                    self.p.image(item['image'], impl='bitImageRaster')
                self.p.text("\n------------------------------------------\n")
                if self.cf['auto_cut'] is True:
                    self.p.cut(mode='FULL', feed=True, lines=4)
                if item['image'] is not None:
                    sleep(2)  # timeout so printer can cool down
예제 #3
0
class Imprimir:
    def __init__(self, porta_serial):
        self.p = Serial(porta_serial)
        self.p.charcode("MULTILINGUAL")
        self.nome_serial = porta_serial

    def imprimir_texto(self, texto):
        self.p.text(str(texto))
        self.p.cut()

    def imprimir_imagem(self, imagem):
        self.p.image(str(imagem))
        self.p.cut()

    def imprimir_qr_code(self, texto):
        self.p.qr(str(texto))
        self.p.cut()

    def retornar_impressora(self):
        return str(self.nome_serial)
예제 #4
0
class printout:
    """Print stuff from Twitter"""
    def __init__(self, printerConf):
        self.p = Serial(devfile=printerConf['dev'],
                        baudrate=[
                            int(printerConf['baudrate'])
                            if 'baudrate' in printerConf else 9600
                        ][0])
        self.p.open()
        self.printerWidth = printerConf['printerWidth']
        self.basedir = dirname(realpath(__file__)) + sep + pardir + sep
        self.printerConf = printerConf

    def imBox(self, width, height):
        """Create a white rectangle"""
        img = Image.new("1", (width, height))
        draw = ImageDraw.Draw(img)
        bgColor = 255
        draw.rectangle((0, 0) + img.size, fill=bgColor)
        return img

    def imText(self,
               text,
               align="left",
               textSize=None,
               rotate=None,
               bgColor=255,
               fontColor=0,
               scale=None,
               leading=0.25,
               txtWidth=None):
        """Render an image using a truetype font. Text may be be a list of string
        objects (one object per line). If a line is too wide the function will try to line wrap.
        Arg. 'leading' is the interline spacing in as a proportion of the height of a line.
        Arg. 'scale' is the proportion of the width of the paper."""
        if not textSize:
            textSize = int(self.printerConf['textSize'])
        if not txtWidth:
            txtWidth = self.printerConf['printerWidth']
        font = ImageFont.truetype(self.printerConf['fontFile'], textSize)

        def splitList(txtWidth, txtList, font, newlineSplitOnly=False):
            """Each str/unicode in txtList equals one line when printet. Split at newlines and furthermore split if a line is too wide."""
            # First of search for newlines and split the list if a newline is found
            withoutNewlines = []
            for txt in txtList:
                withoutNewlines.extend(txt.split("\n"))
            txtList = withoutNewlines
            if newlineSplitOnly:
                return txtList

            txtListWrapped = []
            for txt in txtList:
                # If the whole line is too wide, remove words until we are good
                if font.getsize(txt)[0] > txtWidth:
                    txtLen = len(txt)
                    for i in range(txtLen)[::-1]:
                        if font.getsize(txt[:i + 1])[0] <= txtWidth:
                            whitespaceEtc = [" ", "\t", "-"]
                            if txt[i] in whitespaceEtc:
                                txtSplit = [txt[:i + 1].rstrip(), txt[i + 1:]]
                                if font.getsize(txtSplit[1])[0] > txtWidth:
                                    txtSplit = splitList(
                                        txtWidth, txtSplit, font)
                                    break
                                else:
                                    break
                            # If there are no whitespaces etc. then split the word
                            elif not any(w in txt[:i + 1]
                                         for w in whitespaceEtc):
                                if font.getsize(txt[:i + 1] +
                                                "-")[0] <= txtWidth:
                                    txtSplit = [
                                        txt[:i + 1].rstrip() + "-", txt[i + 1:]
                                    ]
                                    if font.getsize(txtSplit[1])[0] > txtWidth:
                                        txtSplit = splitList(
                                            txtWidth, txtSplit, font)
                                        break
                                    else:
                                        break
                            else:
                                continue
                else:
                    txtSplit = [txt]
                txtListWrapped.extend(txtSplit)
            return txtListWrapped

        # If txtList is a simple string make it a list
        if type(text) is list:
            txtList = text
        else:
            txtList = [text]
        # Spacing between lines as a proportion of the width of a danish letter for the current text size.
        leadingDots = int(font.getsize(u"Å")[0] * leading)
        if rotate in [90, 270]:
            # Don't wrap lines based on width when turned 90 or 270 degrees
            txtList = splitList(txtWidth, txtList, font, newlineSplitOnly=True)
        else:
            # Do wordwrapping etc.
            txtList = splitList(txtWidth, txtList, font)

        # Determine the size of the resulting text image
        size = [0, 0]
        lineHeight = font.getsize("a")[1]
        size = [0, (leadingDots + lineHeight) * len(txtList) + leadingDots]
        # Find the width
        if rotate is 180:
            # Avoid right alignment of rotated text, if a line is less wide than the paper / printerConf['printerWidth']
            size[0] = self.printerConf['printerWidth']
        else:
            for txt in txtList:
                maxWidth = font.getsize(txt)[0]
                if maxWidth > size[0]:
                    size[0] = maxWidth
        # Create the actual image containing the text
        img = Image.new("1", size)
        draw = ImageDraw.Draw(img)
        draw.rectangle((0, 0) + img.size, fill=bgColor)
        pointer = [0, 0]
        # For each line..
        for txt in txtList:
            txtPxWidth = font.getsize(txt)[0]
            if align == "left":
                pointer[0] = 0
            elif align == "right":
                pointer[0] = size[0] - txtPxWidth
            elif align == "center":
                pointer[0] = (size[0] - txtPxWidth) / 2
            draw.text(pointer, txt, font=font, fill=fontColor)
            pointer[1] += lineHeight + leadingDots

        if rotate:
            angles = [0, 90, 180, 270]
            if rotate in angles:
                img = img.rotate(rotate, expand=True)
            else:
                raise ValueError("rotate must be part of %s if set " %
                                 str(angles))
        if rotate in [90, 270]:
            if img.size[0] > self.printerConf['printerWidth'] and not scale:
                raise Exception(
                    "The textSize is too large to print. Use either a smaller textSize or the scale parameter"
                )
        else:
            if img.size[0] > self.printerConf['printerWidth']:
                raise Exception(
                    "Could not print the text. One or more lines are too wide. Did you choose a very large font?"
                )

        if align is not "left":
            imgOld = img
            img = Image.new("1", (txtWidth, imgOld.size[1]))
            draw = ImageDraw.Draw(img)
            draw.rectangle((0, 0) + img.size, fill=bgColor)
            pointer = [0, 0]
            if align is "center":
                i = 2
            else:
                i = 1
            img.paste(imgOld, ((txtWidth - imgOld.size[0]) / i, 0))
        return img

    def printLine(self,
                  pxWidth=False,
                  width=1.0,
                  pxThickness=4,
                  pxHeading=10,
                  pxTrailing=10):
        """Prints a horisontal line.
        If width is set then pxWidth is ignored. width higher than 1.0 is ignored."""
        # calculate dimensions
        if not pxWidth:
            pxWidth = int(self.printerConf['printerWidth'] * width)
        pxHeight = pxHeading + pxThickness + pxTrailing
        img = Image.new("1", (self.printerConf['printerWidth'], pxHeight))
        draw = ImageDraw.Draw(img)
        draw.rectangle((0, 0, self.printerConf['printerWidth'], pxHeight),
                       fill=255)
        draw.rectangle(
            ((self.printerConf['printerWidth'] - pxWidth) / 2, pxHeading,
             (self.printerConf['printerWidth'] - pxWidth) / 2 + pxWidth,
             pxHeading + pxThickness),
            fill=0)
        return img

    def combinePILObjects(self,
                          imgArray,
                          doPrint=True,
                          multiCol=False,
                          ignoreRotate=False):
        """Combine objects and print them"""
        if multiCol:
            # Multiple columns object (e.g. printing wearther forecast). imgArray is then an array of arrays.
            imArray = [
                self.combinePILObjects(i, doPrint=False, ignoreRotate=True)
                for i in imgArray
            ]
            # Determine height pre multicol
            orgMaxHeight = 0
            for im in imArray:
                h = im[0].size[1]
                if h > orgMaxHeight:
                    orgMaxHeight = h
            numCols = len(imArray)
            imgMaster = self.imBox(self.printerConf['printerWidth'],
                                   orgMaxHeight / numCols)
            # Paste the columns together
            offset = 0
            numCols = len(imArray)
            colWidth = self.printerConf['printerWidth'] / numCols
            for i in imArray:
                imgMaster.paste(
                    i[0].resize([colWidth,
                                 int(i[0].size[1] * 1. / numCols)]),
                    (offset, 0))
                offset += colWidth
        else:
            # Calculate height
            height = 0
            imgTooWide = False
            for i in range(len(imgArray)):
                img = imgArray[i]
                # If an image is too large
                if img.size[0] > self.printerConf['printerWidth']:
                    # resize image
                    imgArray[i] = img.resize([
                        self.printerConf['printerWidth'],
                        int(img.size[1] *
                            float(self.printerConf['printerWidth']) /
                            img.size[0])
                    ])
                height += imgArray[i].size[1]
            # Create
            imgMaster = self.imBox(self.printerConf['printerWidth'], height)
            offset = 0
            for img in imgArray:
                imgMaster.paste(img, (0, offset))
                offset += img.size[1]
            if self.printerConf['rotate'] and not ignoreRotate:
                imgMaster = imgMaster.rotate(180)

        height = imgMaster.size[1]
        bytes_io = BytesIO()
        imgMaster.save(bytes_io, format="PNG")
        bytes_io.seek(0)
        imgData = bytes_io.read()
        if doPrint:
            bytes_io.seek(0)
            self.p.image(bytes_io, impl=self.printerConf['printType'])
        # return: PIL-object, height (int), PNG-file
        return (imgMaster, height, imgData)

    def qrIcon(self, url, size=120):
        iconHeight = size
        qr = qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_M,
            box_size=10,
            border=4,
        )
        qr.add_data(url)
        qr.make(fit=True)
        img = qr.make_image()
        return img.resize((iconHeight, iconHeight))

    def commonPrint(self, conn, srcType):
        try:
            dbPrinter = conn.cursor()
            dbPrinter.execute(
                """SELECT printout.id, printout.jdoc 
                FROM printout INNER JOIN srcType 
                ON srcType.id = printout.srcType 
                WHERE srcType.shortName = %s AND printed = 0
                ORDER BY printout.id ASC LIMIT 1""", (srcType, ))
            row = dbPrinter.fetchone()
            # if there is something unprinted waiting for us for the given srcType
            if row is not None:
                data = json.loads(row[1])
                printFunc = getattr(self, srcType.lower())
                printData = printFunc(data)
                # Hmm. one could argue that if printing something fails,
                # then the message should not be marked as printed in the db..
                dbPrinter.execute(
                    """UPDATE printout SET height = %s, 
                    printed = 1, printedImg = _binary %s, printedImgRotated = %s, 
                    printedImgMimeType = %s WHERE id=%s""",
                    (str(printData[0]), printData[1], str(
                        printData[2]), printData[3], str(row[0])))
            dbPrinter.close()
        except Exception, e:
            print(e)
            try:
                print(
                    "The id for the failed message in the printout table: %i" %
                    row[0])
            except:
                pass
        else:
예제 #5
0
    area = (0, STRIP_WIDTH * i, img_w, STRIP_WIDTH * (i + 1))
    strips[i] = image.crop(area)
if img_h % STRIP_WIDTH != 0:
    strips[-1] = strips[-1].crop((0, 0, img_w, img_h % STRIP_WIDTH))

# Dump strips into a temporary directory
if not os.path.exists('.temp'):
    os.mkdir('.temp')
for i in range(num_strips):
    strips[i].save(os.path.join('.temp', "strip{0:03}.png".format(i)))

# Do the printing
p = Serial(devfile='COM5',
           baudrate=9600,
           parity='N',
           stopbits=1,
           timeout=1.00,
           dsrdtr=True)

p.text("\033@")  # Reset
p.text("\033C\20")  # Set sheet eject length
p.text("\0331")  # Select 1/8-inch line spacing
p.text("\033$\000\000")  # Set left margin
p.text("\033a\001")  # Center align

for i in range(num_strips):
    p.image(os.path.join('.temp', "strip{0:03}.png".format(i)))

p.text("\033a\000")  # Left align
#p.cut()
예제 #6
0
           parity='N',
           stopbits=1,
           timeout=1.00,
           dsrdtr=True)

p.text("\033@")  # Reset
p.text("\033C\100")  # Set sheet eject length
p.text("\0331")  # Select 1/8-inch line spacing
p.text("\033$\000\030")  # Set left margin

p.text("\033a\000")  # Left align
p.text("See back of receipt for your chance\n")
p.text("to win $1000 ID #:7N77MVS1VUY\n")

p.text("\033a\001")  # Center align
p.image("C:\\Users\\Alexander\\Desktop\\download.jpg")
p.text("978-851-6265 Mgr:BETH WATERHOUSE\n")
p.text("333 MAIN ST\n")
p.text("TEWKSBURY MA 01876\n")

p.text("\033a\000")  # Left align
p.text("ST# 02222 OP# 009056 TE# 56 TR# 00079\n")

p.text("PRNCS DIA RING 00128182447 F  52000.00 T\n")
p.text("PRNCS DIA RING 00128182447 F  52000.00 T\n")
p.text("PRNCS DIA RING 00128182447 F  52000.00 T\n")
p.text("PRNCS DIA RING 00128182447 F  52000.00 T\n")
p.text("PRNCS DIA RING 00128182447 F  52000.00 T\n")
p.text("PRNCS DIA RING 00128182447 F  52000.00 T\n")
p.text("PRNCS DIA RING 00128182447 F  52000.00 T\n")
p.text("PRNCS DIA RING 00128182447 F  52000.00 T\n")