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