#!/usr/bin/env python

# compressor.py
from subprocess import Popen, PIPE

def compress(value):
    """Compresses a string with the xz binary"""

    process = Popen(["xz", "--compress", "--force"], stdin=PIPE, stdout=PIPE)
    return process.communicate(value)[0]

def decompress(value):
    """Decompresses a string 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

from optparse import OptionParser
from sys import argv
import base64
import cPickle
from cStringIO import StringIO
from os.path import basename

def load():
    ppds_compressed = base64.b64decode(ppds_compressed_b64)
    ppds_decompressed = decompress(ppds_compressed)
    ppds = cPickle.loads(ppds_decompressed)
    return ppds

def ls():
    binary_name = basename(argv[0])
    ppds = load()
    for key, value in ppds.iteritems():
        if key == 'ARCHIVE': continue
        for ppd in value[2]:
            print ppd.replace('"', '"' + binary_name + ':', 1)

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'] = StringIO(decompress(ppds['ARCHIVE']))

    if ppds.has_key(ppd):
        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 0.4.9\n" \
              "Copyright (c) 2010 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])
        print ppd
    else:
        parser.error("argument " + args[0] + " invalid")

# PPDs Archive
ppds_compressed_b64 = "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"

if __name__ == "__main__":
    try:
        main()
    except (IOError, KeyboardInterrupt):
        # We don't want neither IOError nor KeyboardInterrupt throwing a
        # traceback into stdout.
        pass
