diff --git a/escpos/cli.py b/escpos/cli.py index 07d0de8..c42624e 100755 --- a/escpos/cli.py +++ b/escpos/cli.py @@ -5,31 +5,26 @@ from __future__ import absolute_import import argparse import sys import serial +import six from escpos import printer parser = argparse.ArgumentParser( description='CLI for python-escpos', epilog='To see help for escpos commands, run with a destination defined.', - usage='python -m escpos.cli destination_type [--args] command [--args]' -) -dest_subparsers = parser.add_subparsers( - title='Destination', ) -parser_dest_file = dest_subparsers.add_parser('file', help='Print to a file') +parser_dest_file = parser.add_argument_group('File Destination') parser_dest_file.set_defaults(func=printer.File) parser_dest_file.add_argument( - '--devfile', + '--file-devfile', help='Destination file', - required=True ) -parser_dest_network = dest_subparsers.add_parser('network', help='Print to a network device') +parser_dest_network = parser.add_argument_group('Network Destination') parser_dest_network.set_defaults(func=printer.Network) parser_dest_network.add_argument( '--host', help='Destination host', - required=True ) parser_dest_network.add_argument( '--port', @@ -37,22 +32,20 @@ parser_dest_network.add_argument( type=int ) parser_dest_network.add_argument( - '--timeout', + '--network-timeout', help='Timeout in seconds', type=int ) -parser_dest_usb = dest_subparsers.add_parser('usb', help='Print to a usb device') +parser_dest_usb = parser.add_argument_group('USB Destination') parser_dest_usb.set_defaults(func=printer.Usb) parser_dest_usb.add_argument( '--idVendor', help='USB Vendor ID', - required=True ) parser_dest_usb.add_argument( '--idProduct', help='USB Device ID', - required=True ) parser_dest_usb.add_argument( '--interface', @@ -61,23 +54,20 @@ parser_dest_usb.add_argument( ) parser_dest_usb.add_argument( '--in_ep', - help='Input end point', + help='In endpoint', type=int ) parser_dest_usb.add_argument( '--out_ep', - help='Output end point', + help='Out endpoint', type=int ) -parser_dest_serial = dest_subparsers.add_parser( - 'serial', - help='Print to a serial device' -) +parser_dest_serial = parser.add_argument_group('Serial Destination') parser_dest_serial.set_defaults(func=printer.Serial) parser_dest_serial.add_argument( - '--devfile', - help='Device file' + '--serial-devfile', + help='Destination device file', ) parser_dest_serial.add_argument( '--baudrate', @@ -90,7 +80,7 @@ parser_dest_serial.add_argument( type=int ) parser_dest_serial.add_argument( - '--timeout', + '--serial-timeout', help='Read/Write timeout in seconds', type=int ) @@ -115,13 +105,7 @@ parser_dest_serial.add_argument( type=bool ) - -cmd_parser = argparse.ArgumentParser( - description='Parser for escpos commands', - usage='{previous command parts} {espos command} ...' -) - -command_subparsers = cmd_parser.add_subparsers( +command_subparsers = parser.add_subparsers( title='ESCPOS Command', ) @@ -342,23 +326,62 @@ parser_command_panel_buttons.add_argument( required=True ) -# Get arguments along with function to pass them to -args, rest = parser.parse_known_args() +# Get only arguments actually passed +args = dict([k, v] for k, v in six.iteritems(vars(parser.parse_args())) if v) -# filter out function name and non passed arguments -func_args = dict((k, v) for k, v in vars(args).iteritems() if v and k != 'func') +# Argparse doesn't tell us what came in which group, so we need to check +# Is it better to dig into parser for this, or keep a hardcoded list? +group_args = { + 'File': ('file_devfile', ), + 'Network': ('host', 'port', 'network_timeout' ), + 'Usb': ('idVendor', 'idProduct', 'interface', 'in_ep', 'out_ep' ), + 'Serial': ('serial_devfile', 'baudrate', 'serial_timeout', 'parity', 'stopbits', 'xonxoff', 'dstdtr' ), +} -# define a printer -p = args.func(**func_args) +argument_translations = { + 'file_devfile': 'devfile', + 'serial_devfile': 'devfile', + 'network_timeout': 'timeout', + 'serial_timeout': 'timeout', +} -if not rest: - cmd_parser.print_help() - sys.exit(1) +# To be found +target_printer = None +printer_arguments = {} -cmd_args = cmd_parser.parse_args(rest) +target_command = args.pop('func') +command_arguments = {} -# filter out function name and non passed arguments -func_args = dict((k, v) for k, v in vars(cmd_args).iteritems() if v and k != 'func') +# Find the printer that matches the arguments sent +for printer_group, arguments in six.iteritems(group_args): + # See if there were any arguments passed that match this group + passed_args = dict([[k, v] for k, v in six.iteritems(args) if k in arguments]) + if not passed_args: + # Nope + continue + # We found a printer + target_printer = printer_group + break + +if not target_printer: + raise Exception('No printer matches passed arguments') + +# Sort the arguments into printer or escpos command +for arg, value in six.iteritems(args): + # This one belongs to the printer + if arg in group_args[target_printer]: + # Translate it if we need to + if arg in argument_translations.keys(): + target_argument = argument_translations[arg] + printer_arguments[target_argument] = value + else: + printer_arguments[arg] = value + else: + # This belongs to the escpos command + command_arguments[arg] = value + +# Create a printer +p = getattr(printer, target_printer)(**printer_arguments) # print command with args -getattr(p, cmd_args.func)(**func_args) +getattr(p, target_command)(**command_arguments)