diff --git a/README.md b/README.md index adf3ee1..64ce129 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,19 @@ # pos-printer-server -ESC/POS Thermal Printer Server \ No newline at end of file +ESC/POS Thermal Printer Server + +Prints logs. + +Prints images, randomly-generated mazes. + +## Install + +``` +pip install -r requirements.txt +``` + +## Resources + +- [escposprinter Python library](https://github.com/Simonefardella/escposprinter) +- [RPi Maze Printer](https://github.com/mattiasjahnke/rpi-maze-printer) + diff --git a/maze/LICENSE b/maze/LICENSE new file mode 100644 index 0000000..14ee928 --- /dev/null +++ b/maze/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Engineerish + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/maze/mazy.py b/maze/mazy.py new file mode 100644 index 0000000..a5756f4 --- /dev/null +++ b/maze/mazy.py @@ -0,0 +1,145 @@ +#!/usr/bin/python + +# import modules used here -- sys is a very standard one +import sys +from PIL import Image, ImageDraw +import math +import random + +class Cell: + walls = int('1111', 2) + visited = False + + def __init__(self, x, y): + self.x = x + self.y = y + + def draw(self, draw): + global start, end, margin + + if self.walls & 1 == 1: + draw.line([(margin + cellSize * self.x, margin + cellSize * self.y + cellSize), (margin + cellSize * self.x + cellSize, margin + cellSize * self.y + cellSize)], fill="black", width=3) + if (self.walls >> 1 & 1) == 1: + draw.line([(margin + cellSize * self.x + cellSize, margin + cellSize * self.y), (margin + cellSize * self.x + cellSize, margin + cellSize * self.y + cellSize)], fill="black", width=3) + if (self.walls >> 2 & 1) == 1: + draw.line([(margin + cellSize * self.x, margin + cellSize * self.y), (margin + cellSize * self.x + cellSize, margin + cellSize * self.y)], fill="black", width=3) + if (self.walls >> 3 & 1) == 1: + draw.line([(margin + cellSize * self.x, margin + cellSize * self.y), (margin + cellSize * self.x, margin + cellSize * self.y + cellSize)], fill="black", width=3) + + if self.x == start[0] and self.y == start[1]: + draw.ellipse([margin + cellSize * self.x + cellSize / 4, margin + cellSize * self.y + cellSize / 4, margin + cellSize * self.x + cellSize / 4 + cellSize / 2, margin + cellSize * self.y + cellSize / 4 + cellSize / 2], fill="blue") + elif self.x == end[0] and self.y == end[1]: + draw.ellipse([margin + cellSize * self.x + cellSize / 4, margin + cellSize * self.y + cellSize / 4, margin + cellSize * self.x + cellSize / 4 + cellSize / 2, margin + cellSize * self.y + cellSize / 4 + cellSize / 2], fill="green") + +rows = 0 +cols = 0 +#image = Image.new('RGB', (380, 400 * 2), (0, 0, 0)) +image = Image.new('RGB', (500, 400 * 4), (0, 0, 0)) +draw = ImageDraw.Draw(image) +cellSize = 20 +margin = 10 + +matrix = [] +stack = [] +currentCell = None +biggestStack = 0 +start = (0, 0) +end = (0, 0) + +# Gather our code in a main() function +def main(): + global matrix, stack, currentCell, start, rows, cols, cellSize, margin + # Setup + if len(sys.argv) > 1: + cellSize = int(sys.argv[1]) + + random.seed() + + drawingWidth = image.width - margin * 2 + drawingHeight = image.height - margin * 2 + + draw.rectangle([margin, margin, margin + drawingWidth, margin + drawingHeight], fill="white") + + rows = int(math.floor(drawingHeight / cellSize)) + cols = int(math.floor(drawingWidth / cellSize)) + + print(cellSize) + + for y in range(rows): + for x in range(cols): + matrix.append(Cell(x, y)) + + currentCell = matrix[0] + start = (currentCell.x, currentCell.y) + + while nrOfUnvisitedCells() > 0: + runMazeStep() + + # Draw + for cell in matrix: + cell.draw(draw) + + image.save("maze.png") + +def runMazeStep(): + global currentCell, stack, end, biggestStack + + currentCell.visited = True + + nei = [] + + if currentCell.x > 0: + cell = matrix[index(currentCell.x - 1, currentCell.y)] + if not cell.visited: + nei.append(cell) + if currentCell.y > 0: + cell = matrix[index(currentCell.x, currentCell.y - 1)] + if not cell.visited: + nei.append(cell) + if currentCell.x < cols - 1: + cell = matrix[index(currentCell.x + 1, currentCell.y)] + if not cell.visited: + nei.append(cell) + if currentCell.y < rows - 1: + cell = matrix[index(currentCell.x, currentCell.y + 1)] + if not cell.visited: + nei.append(cell) + + if len(nei) > 0: + chosen = random.choice(nei) + stack.append(currentCell) + if len(stack) > biggestStack: + biggestStack = len(stack) + end = (chosen.x, chosen.y) + + if chosen.x < currentCell.x: + chosen.walls &= ~(1 << 1) + currentCell.walls &= ~(1 << 3) + elif chosen.x > currentCell.x: + chosen.walls &= ~(1 << 3) + currentCell.walls &= ~(1 << 1) + elif chosen.y > currentCell.y: + chosen.walls &= ~(1 << 2) + currentCell.walls &= ~(1 << 0) + elif chosen.y < currentCell.y: + chosen.walls &= ~(1 << 0) + currentCell.walls &= ~(1 << 2) + + currentCell = chosen + else: + currentCell = stack.pop() + + +def nrOfUnvisitedCells(): + global matrix + res = len([cell for cell in matrix if not cell.visited]) + return res + +def index(x, y): + global cols + return y * cols + x + +# Standard boilerplate to call the main() function to begin +# the program. +if __name__ == '__main__': + main() diff --git a/print_log.py b/print_log.py new file mode 100755 index 0000000..c8385fb --- /dev/null +++ b/print_log.py @@ -0,0 +1,86 @@ +#!/bin/env python3 +from escpos.printer import Usb +import getopt +import sys +import datetime + +TEXT_LIMIT=256 + +class PrintOptions: + title = None + text = None + verbose = False + image = None + +def get_printer(): + return Usb(0x0525, 0xa700) # <-- change based on your printer vendor and product ID + +def do_print(options): + p = get_printer() + p.set(align='center') + p.text(str(datetime.datetime.now().strftime("%H:%M:%S"))) + p.text(' ') + p.text(str(datetime.date.today())) + p.text('\n') + if (options.title): + p.set(align='center', text_type='B') # center bold + p.text(options.title + '\n') + p.set() + if len(options.text) > TEXT_LIMIT: + p.text(options.text[:TEXT_LIMIT] + '[...]\n(truncated)') + else: + p.text(options.text + '\n') + if options.image != None: + p.image(options.image) + p.cut() + +def do_print_image(path): + p = get_printer() + p.image(path) + p.cut() + +def usage(): + print(f'usage: {sys.argv[0]} [OPTIONS] TEXT...') + print(f' OPTIONS') + print(f' -v ... verbose') + print(f' -h ... help') + print(f' -t --title=X ... title to prepend') + print(f' -i --image=X ... image path') + print(f' TEXT is taken as the rest of argumenats if present,') + print(f' otherwise from STDIN (terminated by Ctrl+D).') + +def main(): + try: + opts, args = getopt.getopt(sys.argv[1:], "ht:i:v", ["help", "title=", "image="]) + except getopt.GetoptError as err: + print(err) + usage() + sys.exit(2) + title = None + verbose = False + image = None + for o, a in opts: + if o == "-v": + verbose = True + elif o in ("-h", "--help"): + usage() + sys.exit() + elif o in ("-i", "--image"): + image = a + elif o in ("-t", "--title"): + title = a + else: + assert False, "unhandled option" + options = PrintOptions() + options.title = title + options.verbose = verbose + options.text = " ".join(args) + options.image = image + if len(options.text) <= 0: + for line in sys.stdin: + options.text = options.text + line + do_print(options) + +if __name__ == "__main__": + main() + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..db31fa4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +python_escpos