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