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