#!/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.1\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
