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