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