#!/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
try:
    import cPickle as pickle
except ImportError:
    import pickle
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 = pickle.loads(ppds_decompressed)
    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()
    ppds['ARCHIVE'] = BytesIO(decompress(ppds['ARCHIVE']))

    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
