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