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