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