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