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