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