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