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