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