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