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