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