#!/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
