#!/usr/bin/env python3

# compressor.py
from subprocess import Popen, PIPE

def compress(value):
    """Compresses a byte array with the xz binary"""

    process = Popen(["xz", "--compress", "--force"], stdin=PIPE, stdout=PIPE)
    return process.communicate(value)[0]

def decompress(value):
    """Decompresses a byte array with the xz binary"""

    process = Popen(["xz", "--decompress", "--stdout", "--force"],
                    stdin=PIPE, stdout=PIPE)
    return process.communicate(value)[0]

def compress_file(path):
    """Compress the file at 'path' with the xz binary"""

    process = Popen(["xz", "--compress", "--force", "--stdout", path], stdout=PIPE)
    return process.communicate()[0]

# compressor.py

import os
import sys
from optparse import OptionParser
from sys import argv
import base64
import json
from io import BytesIO

from os.path import basename
from errno import EPIPE

def load():
    ppds_compressed = base64.b64decode(ppds_compressed_b64)
    ppds_decompressed = decompress(ppds_compressed)
    ppds = json.loads(ppds_decompressed.decode(encoding='ASCII'))
    return ppds

def ls():
    binary_name = basename(argv[0])
    ppds = load()
    for key, value in ppds.items():
        if key == 'ARCHIVE': continue
        for ppd in value[2]:
            try:
                print(ppd.replace('"', '"' + binary_name + ':', 1))
            except IOError as e:
                # Errors like broken pipes (program which takes the standard
                # output terminates before this program terminates) should not
                # generate a traceback.
                if e.errno == EPIPE: exit(0)
                raise

def cat(ppd):
    # Ignore driver's name, take only PPD's
    ppd = ppd.split(":")[-1]
    # Remove also the index
    ppd = "0/" + ppd[ppd.find("/")+1:]

    ppds = load()
    # Encode to binary, decode base64, decompress and convert to bytes again
    ppds['ARCHIVE'] = BytesIO(decompress(base64.b64decode(ppds['ARCHIVE'].encode('ASCII'))))

    if ppd in ppds:
        start = ppds[ppd][0]
        length = ppds[ppd][1]
        ppds['ARCHIVE'].seek(start)
        return ppds['ARCHIVE'].read(length)

def main():
    usage = "usage: %prog list\n" \
            "       %prog cat URI"
    version = "%prog 1.0.2\n" \
              "Copyright (c) 2013 Vitor Baptista.\n" \
              "This is free software; see the source for copying conditions.\n" \
              "There is NO warranty; not even for MERCHANTABILITY or\n" \
              "FITNESS FOR A PARTICULAR PURPOSE."
    parser = OptionParser(usage=usage,
                          version=version)
    (options, args) = parser.parse_args()

    if len(args) == 0 or len(args) > 2:
        parser.error("incorrect number of arguments")

    if args[0].lower() == 'list':
        ls()
    elif args[0].lower() == 'cat':
        if not len(args) == 2:
            parser.error("incorrect number of arguments")
        ppd = cat(args[1])
        if not ppd:
            parser.error("Printer '%s' does not have default driver!" % args[1])
        try:
            # avoid any assumption of encoding or system locale; just print the
            # bytes of the PPD as they are
            if sys.version_info.major < 3:
                sys.stdout.write(ppd)
            else:
                sys.stdout.buffer.write(ppd)
        except IOError as e:
            # Errors like broken pipes (program which takes the standard output
            # terminates before this program terminates) should not generate a
            # traceback.
            if e.errno == EPIPE: exit(0)
            raise
    else:
        parser.error("argument " + args[0] + " invalid")

# PPDs Archive
ppds_compressed_b64 = b"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"

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        # We don't want a KeyboardInterrupt throwing a
        # traceback into stdout.
        pass
