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