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