python-escpos/escpos/cli.py

292 lines
7.6 KiB
Python
Executable File

#!/usr/bin/env python
from __future__ import absolute_import
import argparse
import sys
import serial
import six
import os
import itertools
from ConfigParser import ConfigParser
from escpos import printer
config_filenames = [
'.python-escpos',
'python-escpos.ini'
]
config_dirs = [
os.path.join(os.environ['HOME'], '.config')
]
for environ in ('HOME', 'XDG_CONFIG_HOME'):
try:
config_dirs.append(os.environ[environ])
except (KeyError):
pass
config_files = [os.path.join(x, y) for x, y in list(itertools.product(config_dirs, config_filenames))]
config = ConfigParser()
files_read = config.read(config_files)
if not files_read:
raise Exception('Couldn\'t find config files at {config_files}'.format(
config_files=config_files,
))
if 'printer' not in config.sections():
raise Exception('Couldn\'t find [printer] config section in config_file(s): {files}'.format(
files="\n".join(files_read),
))
printer_config = dict(config.items('printer'))
printer_name = printer_config.pop('type').title()
if not hasattr(printer, printer_name):
raise Exception('Couldn\'t find printer type {printer_name}'.format(
printer_name=printer_name,
))
try:
target_printer = getattr(printer, printer_name)(**printer_config)
except TypeError as e:
raise Exception('Unable to create {printer_name} printer: {error}'.format(
printer_name=printer_name,
error=str(e),
))
parser = argparse.ArgumentParser(
description='CLI for python-escpos',
epilog='Printer configuration is defined in the python-escpos config file.',
)
command_subparsers = parser.add_subparsers(
title='ESCPOS Command',
)
# From here on func needs to be a string, since we don't have a printer to work on yet
parser_command_qr = command_subparsers.add_parser('qr', help='Print a QR code')
parser_command_qr.set_defaults(func='qr')
parser_command_qr.add_argument(
'--text',
help='Text to print as a qr code',
required=True
)
parser_command_barcode = command_subparsers.add_parser('barcode', help='Print a barcode')
parser_command_barcode.set_defaults(func='barcode')
parser_command_barcode.add_argument(
'--code',
help='Barcode data to print',
required=True
)
parser_command_barcode.add_argument(
'--bc',
help='Barcode format',
required=True
)
parser_command_barcode.add_argument(
'--height',
help='Barcode height in px',
type=int
)
parser_command_barcode.add_argument(
'--width',
help='Barcode width',
type=int
)
parser_command_barcode.add_argument(
'--pos',
help='Label position',
choices=['BELOW', 'ABOVE', 'BOTH', 'OFF']
)
parser_command_barcode.add_argument(
'--font',
help='Label font',
choices=['A', 'B']
)
parser_command_barcode.add_argument(
'--align_ct',
help='Align barcode center',
type=bool
)
parser_command_barcode.add_argument(
'--function_type',
help='ESCPOS function type',
choices=['A', 'B']
)
parser_command_text = command_subparsers.add_parser('text', help='Print plain text')
parser_command_text.set_defaults(func='text')
parser_command_text.add_argument(
'--txt',
help='Text to print',
required=True
)
parser_command_block_text = command_subparsers.add_parser('block_text', help='Print wrapped text')
parser_command_block_text.set_defaults(func='block_text')
parser_command_block_text.add_argument(
'--txt',
help='block_text to print',
required=True
)
parser_command_block_text.add_argument(
'--columns',
help='Number of columns',
type=int
)
parser_command_cut = command_subparsers.add_parser('cut', help='Cut the paper')
parser_command_cut.set_defaults(func='cut')
parser_command_cut.add_argument(
'--mode',
help='Type of cut',
choices=['FULL', 'PART']
)
parser_command_cashdraw = command_subparsers.add_parser('cashdraw', help='Kick the cash drawer')
parser_command_cashdraw.set_defaults(func='cashdraw')
parser_command_cashdraw.add_argument(
'--pin',
help='Which PIN to kick',
choices=[2, 5]
)
parser_command_image = command_subparsers.add_parser('image', help='Print an image')
parser_command_image.set_defaults(func='image')
parser_command_image.add_argument(
'--path_img',
help='Path to image',
required=True
)
parser_command_fullimage = command_subparsers.add_parser('fullimage', help='Print an fullimage')
parser_command_fullimage.set_defaults(func='fullimage')
parser_command_fullimage.add_argument(
'--img',
help='Path to img',
required=True
)
parser_command_fullimage.add_argument(
'--max_height',
help='Max height of image in px',
type=int
)
parser_command_fullimage.add_argument(
'--width',
help='Max width of image in px',
type=int
)
parser_command_fullimage.add_argument(
'--histeq',
help='Equalize the histrogram',
type=bool
)
parser_command_fullimage.add_argument(
'--bandsize',
help='Size of bands to divide into when printing',
type=int
)
# Not supported
# parser_command_direct_image = command_subparsers.add_parser('direct_direct_image', help='Print an direct_image')
# parser_command_direct_image.set_defaults(func='direct_image')
parser_command_charcode = command_subparsers.add_parser('charcode', help='Set character code table')
parser_command_charcode.set_defaults(func='charcode')
parser_command_charcode.add_argument(
'--code',
help='Character code',
required=True
)
parser_command_set = command_subparsers.add_parser('set', help='Set text properties')
parser_command_set.set_defaults(func='set')
parser_command_set.add_argument(
'--align',
help='Horizontal alignment',
choices=['left', 'center', 'right']
)
parser_command_set.add_argument(
'--font',
help='Font choice',
choices=['left', 'center', 'right']
)
parser_command_set.add_argument(
'--text_type',
help='Text properties',
choices=['B', 'U', 'U2', 'BU', 'BU2', 'NORMAL']
)
parser_command_set.add_argument(
'--width',
help='Width multiplier',
type=int
)
parser_command_set.add_argument(
'--height',
help='Height multiplier',
type=int
)
parser_command_set.add_argument(
'--density',
help='Print density',
type=int
)
parser_command_set.add_argument(
'--invert',
help='White on black printing',
type=bool
)
parser_command_set.add_argument(
'--smooth',
help='Text smoothing. Effective on >= 4x4 text',
type=bool
)
parser_command_set.add_argument(
'--flip',
help='Text smoothing. Effective on >= 4x4 text',
type=bool
)
parser_command_hw = command_subparsers.add_parser('hw', help='Hardware operations')
parser_command_hw.set_defaults(func='hw')
parser_command_hw.add_argument(
'--hw',
help='Operation',
choices=['INIT', 'SELECT', 'RESET'],
required=True
)
parser_command_control = command_subparsers.add_parser('control', help='Control sequences')
parser_command_control.set_defaults(func='control')
parser_command_control.add_argument(
'--ctl',
help='Control sequence',
choices=['LF', 'FF', 'CR', 'HT', 'VT'],
required=True
)
parser_command_control.add_argument(
'--pos',
help='Horizontal tab position (1-4)',
type=int
)
parser_command_panel_buttons = command_subparsers.add_parser('panel_buttons', help='Disables panel buttons')
parser_command_panel_buttons.set_defaults(func='panel_buttons')
parser_command_panel_buttons.add_argument(
'--enable',
help='Feed button enabled',
type=bool,
required=True
)
# Get only arguments actually passed
args = dict([k, v] for k, v in six.iteritems(vars(parser.parse_args())) if v)
target_command = args.pop('func')
command_arguments = args
# print command with args
getattr(target_printer, target_command)(**command_arguments)