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