#!/usr/bin/env python3

# A script for usage with the ForceCommand sshd_config option.
# It calls lpr with some standard arguments, but also parses
# SSH_ORIGINAL_COMMAND to potentially provide a different set of arguments to
# lpr.
#
# This wrapper is written for interacting with the Brother QL 500 label printer.
#
# The following options can be provided as an SSH command and this script will
# then pass them to the lpr call: <MediaType> <PageSize>
# - MediaType can be one of:
#   - Labels
#   - Tape (this is the default)
# - PageSize can be one of:
#   - 12mm
#   - 12mm-circular
#   - 17x54mm
#   - 17x87mm
#   - 23x23mm
#   - 24mm-circular
#   - 29mm
#   - 29x90mm
#   - 38mm
#   - 38x90mm
#   - 50mm
#   - 54mm
#   - 58mm-circular
#   - 62mm
#   - 62x29mm
#   - 62x100mm
#   - Custom.WIDTHxHEIGHT (with WIDTH and HEIGHT needing to be either one to
#     three digits)
#   - label-wide (this being a convenience alias for Custom.62x35mm and it also
#     being the default)
#   - label-item (this being a convenience alias for 38x90mm)
# 
# So using these options in a complete setup would look like this for example:
# cat label-item.pdf | ssh print@ptouch-print-server.z9.ccchh.net labels label-item
# This being equivalent to:
# cat label-item.pdf | ssh print@ptouch-print-server.z9.ccchh.net Labels 38x90mm
#
# The options are case-insensitive.
#
# The options are derived from: lpoptions -p Brother-QL-500 -l

import os, re, subprocess

mediaType = "Tape"
pageSize = "Custom.62x35mm"

def parseGivenOptions():
    givenOptionsString = os.environ["SSH_ORIGINAL_COMMAND"]
    givenOptionsIterator = iter(givenOptionsString.split(" "))

    givenMediaType = next(givenOptionsIterator, "")
    givenPageSize = next(givenOptionsIterator, "")

    global mediaType
    if givenMediaType.lower() == "labels":
        mediaType = "Labels"
    elif givenMediaType.lower() == "tape":
        mediaType = "Tape"

    global pageSize
    pageSizeRegex = re.compile(r"^((12mm(-circular)?)|(24mm-circular)|(58mm-circular)|(((17x(54|87))|(23x23)|((29|38)(x90)?)|(62x(29|100))|50|54|62)mm))$", re.ASCII | re.IGNORECASE)
    pageSizeMatch = pageSizeRegex.match(givenPageSize)
    pageSizeCustomRegex = re.compile(r"^custom\.(\d{1,3})x(\d{1,3})$", re.ASCII | re.IGNORECASE)
    pageSizeCustomMatch = pageSizeCustomRegex.match(givenPageSize)
    if givenPageSize.lower() == "label-wide":
        pageSize = "Custom.62x35mm"
    elif givenPageSize.lower() == "label-item":
        pageSize = "38x90mm"
    elif pageSizeMatch:
        pageSize = givenPageSize.lower()
    elif pageSizeCustomMatch:
        width = pageSizeCustomMatch.group(1)
        height = pageSizeCustomMatch.group(2)
        pageSize = "Custom.{}x{}".format(width, height)

if "SSH_ORIGINAL_COMMAND" in os.environ:
    parseGivenOptions()

subprocess.run(["lpr", "-P", "Brother-QL-500", "-o", "MediaType={}".format(mediaType), "-o", "PageSize={}".format(pageSize)])