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