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