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