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