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