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