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