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