Initial commit
This commit is contained in:
parent
abed247bd9
commit
53c566e641
16
README.md
16
README.md
@ -1,3 +1,19 @@
|
||||
# pos-printer-server
|
||||
|
||||
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)
|
||||
|
||||
|
21
maze/LICENSE
Normal file
21
maze/LICENSE
Normal file
@ -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.
|
145
maze/mazy.py
Normal file
145
maze/mazy.py
Normal file
@ -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()
|
86
print_log.py
Executable file
86
print_log.py
Executable file
@ -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()
|
||||
|
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
python_escpos
|
Loading…
Reference in New Issue
Block a user