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