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