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