#!/usr/bin/env python3

# compressor.py
from subprocess import Popen, PIPE

def compress(value):
    """Compresses a byte array with the xz binary"""

    process = Popen(["xz", "--compress", "--force"], stdin=PIPE, stdout=PIPE)
    return process.communicate(value)[0]

def decompress(value):
    """Decompresses a byte array 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

import os
import sys
from optparse import OptionParser
from sys import argv
import base64
try:
    import cPickle as pickle
except ImportError:
    import pickle
from io import BytesIO

from os.path import basename
from errno import EPIPE

def load():
    ppds_compressed = base64.b64decode(ppds_compressed_b64)
    ppds_decompressed = decompress(ppds_compressed)
    ppds = pickle.loads(ppds_decompressed)
    return ppds

def ls():
    binary_name = basename(argv[0])
    ppds = load()
    for key, value in ppds.items():
        if key == 'ARCHIVE': continue
        for ppd in value[2]:
            try:
                print(ppd.replace('"', '"' + binary_name + ':', 1))
            except IOError as e:
                # Errors like broken pipes (program which takes the standard
                # output terminates before this program terminates) should not
                # generate a traceback.
                if e.errno == EPIPE: exit(0)
                raise

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'] = BytesIO(decompress(ppds['ARCHIVE']))

    if ppd in ppds:
        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 1.0.2\n" \
              "Copyright (c) 2013 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])
        try:
            # avoid any assumption of encoding or system locale; just print the
            # bytes of the PPD as they are
            if sys.version_info.major < 3:
                sys.stdout.write(ppd)
            else:
                sys.stdout.buffer.write(ppd)
        except IOError as e:
            # Errors like broken pipes (program which takes the standard output
            # terminates before this program terminates) should not generate a
            # traceback.
            if e.errno == EPIPE: exit(0)
            raise
    else:
        parser.error("argument " + args[0] + " invalid")

# PPDs Archive
ppds_compressed_b64 = b"/Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4BIEEIFdAEAAyynXgKBkJTK2v/boY8vTM+VnO/xZoOWVLKXI05htzFFf7dt0+zl9MEtzHxpVMurUar+c6FZ2LoV1dC9QYiZJLP4SxAFfNGhV/yzT0ir9QRgoH6ZYaAjWusSi0yvHt74F26tFV62O4GLlDyJmjmCHZVa1Kbjm0ag4+DXyDO3/GW8mbrzVqKTUt6SqK6LIDcbeyVKL5LqS1qM/zPR5yZRat7uKJ44z6UHfNk3VRrtVTq2capN4i77vACiZRkfuPBBrXYEg5HXkxtRVnYk/AwKkU8WFBvbwdM0BelBUgT0bfrtEbdEa2Fjr7S3jcXOgMsxugjOycLMqs3fefeq17SLryZ60wz5aznv15Ot3YYvXKjYt2yYlbL0xvKpKEPUCM0g7AH+omZb8TN96r32UliQuHwf9FosUQwPJT33aQLa/kjzpkvZbDe8nC6M9px0XcWw8kyUyXqTS8NeFdlhvAHxv/uIJwzVdAwCqg8cfmCMsYpsug8Wblq+UunaHC773gu1oJZavv3hqaBqLL3BseX/YtuFFYyp6hkezmKbB6FYMvhmBiVK8iGkh6X2SabgOLiKMqcsu/QdLVPvfa6x8PlGtUYjwkYa3rbTCgyhLxQhWmw1R9AyAvOg+5mMJi/V7lZkk80iLGAgkzttMR3Po9u/4QTJCJ4lw0VSENb50ma3EFwPA1uafjrJM89Ha/QoOlKwWzH5fd21gbq8UGM7CnmYGY1IN1O+UoTrjcI+MdZ6TFVp7SDQ+lSJZqf/l2/AGSFrEn/Q4YE7sSuAUaXRe8VWA8asyN8Gap1MIFgsh8SgDyiWE/oCmfR9QCjHOnK7DGcElKEWfg8fL4RE6uia0rnom/eU6akowl3qCn5ucqZTxiT8HghV+dvx7U9gGJJozLzdOXjGikA2ZY/qIILWhKanLSOQq6M3BnYSUIPCqq5AJv6DsnsFBBprexc0t/218rXXyshcieTGQxZk+2xIf8+TxkB046SG23GitaJxZWZmp/kaeHfshkCwHJ6xYSXKdHkIYy/t9hZcuXShtMEfa45tL0VOyIC41Gb6OuTh1k1MTt1E9kWYkW9mHXwMsHwH/PPDNmyNGWkdI6gcoT+XvTnFZ9ksjpdP6gO/q15SaQDBEWic1Mo25pO0GYX8tXFLzlMNwT0HQoXUyQ3wTNbKegfeQHNiXSfe8avFEJWJ9FZsXc0IsWXIOzkGNrsUDqafQZFaUk58fWUDxa2u1yjZnQJr/6t7ceFNBZ9W/BJI+08zRbtfw69sTHcvNdJvbmjyXdCbkh0jLpBSSJi0Mi0v5nqHNIizCOZgHOPJlmAMGAETCJ+3b0+UTfWdpMgIDp6hBKBYHywquoPeCgW28sJaFG5ue8d6sNLWoOc/2O5Eu+LP8hfVM5jaO2WApBSuTr2V74AhxfWsfQOBb/LBxf19JSyKLinFBtu7AaNN5YKwrQMcpEhsjrlOwW5LY125SIr31X5F9st6DshKnNXfgbGwEjtBBHSOSmT4+6KkxvYyNOSopjh+CkcOyyfNagj/P4hEyPiK0KPlRL9fcQoaVbYGGCWlauLBEdqXH6lBgJaCXakAQLRtP76eN01k4f317kYM3ZrhNhmXx7CZLuxer/LpZx4tnA+eJ01Tkoy988dqj/nHraGeREnxBz9Sxs0swrnuZlwTlXJaTZtwCbewsjMAP0SDbp0MkrI9fsftkxStPP+CmGcyFx8ZEG6mE2cg7smbFsRTIzGwTiHrBlic43YQ+OjdczDOqbRQUfDFfRULkdtPS5QxRIhWMMi2d2w51YpPRpDKA6D76LveK4+Epl16RRNk8V9eyqu1iY1xcgxLFJz80snNCDxoqlt2KO970y8CEUHkGh/0YQ+yoVcGjvKcb6wqV+CNbIpBicfadWsb4b8zmGkz6rRIicrck300P+h0JC3AZjX2hXOo8LYMHgwW/Wrz1tmnXQY+7F0LWzKN5qQclBe5XY/vrxEEOkYcWt80SO+Jq3qGt917+6GBuTg2JRHXtDPqsnBtc0ueFOo3Up2+/zlyfztDYw9UzlWxhbozsDsUCNreWA6u1azxT+tiL8AiV2c9QPjob0k4hc37AniPtM7hZX64U3LvcNgEY0ck8ixE1SYzjSYjgj6hsRB8+i2EdaO/VkSht58ukOLIHrH9WdR5FKJpyojunNL1A7zdW7qcWdxP+56YTd5A8P8jbls+QiVkCd7wCYvte7mLtrljQ/XNVqfvriZjDgJbCoSuCqQsVBHd5gdSiVJxlTrF31gkvfT7Wqj2oavWgh7xECBWrax4+Tt6G72TXwNFyXj7AwtBwwFVcoVX5g+0TXVJ2fpVOzfhsdK3MqgTFvP6Q6NS+ULbRA/9YVia0JTXzODEqm5nJbIkEF69gT2IG7OQyXjQJxN3vD6lO9KtwsK44vNvDdwqRqtZ0fG2cvbfkA23KZ/ySfEo0TodjDd+EoMb3j9rd/DEauvQzfWYbgQAkpIv8Olt8xYypQx410N7HPwWULl7zLguJC4ijoo2R2O/spaB9OBcpV8wWEPdo1NKZAods7FWdHTi/j13TqSPG0/QHYu2yc2DniKqofXxBDIc+7oKjVOvjgp3vsPAMGtpi20vUgkIyRcRIkMGjfDbCp3i7l2anKAnIWcMcKmLDpEVyselTQpnmw5gTrxfNttQKyzzcDoq5IspUakLgaij1S+R17DVNH5ZyQrOX7WQzcJnGGmc6L62FXYpdWaS0Yj10uG/J32D6yOA1xeF316QJRZ+iYeD8wQiOkHDfpK0DEUHujtj70TgAY3lvI2FQOpou4iZW59ddrQSeKRpHezAXv0qFS45wY3PwEXaEwx05KvKTwjLLcSAQqsjouwUq47hAl8fs8vxOpyyrBMpBw9Cz6nBN2vz6JXAKITTUJnjTsCStEABMgaz+/LPB8DWDneMRDwFn2BI1p7YT8uZBvdGUiP43dQOf/ZA11bH0CNiOftfXJvbfXTH5FtKLpDMBwDfw/UQhfNHYkGFPllxbzANxKfYpEmsV5sBFXpplsSyuRC50h/sS7oNUt3yIupAi2PJvNbGTxU+4jJ68wVjB97ihQ4RIjtq71K5y459A04Au4lMVgmhPgIHQ3O4i6G8lw2aV3TWNiULf3mWPZ4sb5cIKWZU82t2/lg3OhD6nyRcYJyWoVgg5bm1x7/MFl3iX0VLA459IIvL4p6baLHOutXH27BtrPtVV5bYjv5vjCo/Opscl23jA/CpKJ39KyK43TIJ9szZDmM7Dd8Nc2DLZ5tcqU/gOajL12X9DeB7/8ZNiHli0kaKsptEfupP+tjX1fX4HZHJINOhq/jVl+MZc+3mdzDt8B6c4Q8xkoeF0NYhXUOH7OTxOrZlfbJHBzD6v5YBnKpt68EBQPupH11lp1UIPkD6D3tt3PVINK0tVPjDOniWUmylvNuKgdp+LERpnw0zlHAg9HBLTjTpB3TNVS7jRscXuNSv+vAP/IKvbZJnDJRY+1phIwQMwIB1ryuuHIwrEtYohZQyc+tE1iFjjLVln1qM2B7VRw82AFV3dVMV/dJUSzxGqT1VNRXbnT3tx1bBoDPPguGXpQHQVVAYpV6AqZK/3QHnz4rpj7DKfDXAkHQiUv5JXk0LOD1hzDIyaHu7hmG3+zLlna+p2TMJ7c7d3yIUkSAigcrKYHEdMD8/xNV/Jr1cG3quHxNx2nshYpNR0An0qX07iI2x8osOkvvLcR61sBYUa0GaAatiqA3vZl+InGujMy8MdTRXbA5cb0IUQd0T446uSapsjyCZsDFgYSY4JLq54MqihDrHsPxXQXbmPjK5w2JOklU4X5alR3uXOv5kF1SnsbZJIlqxxbQw/KglrvZvvEmHrdryk6r0xUkKHCMRQJsyrS/pIuIF2ZYzO+xCo+MmtBaYJWUwn2j2hPq0P4zGJE866r3vsiwx1x/QLgC7cjo0is8H8UFsLsmzLzvtigbu0jWGOq6rL21Un5/B8ZJY//sajikRjlIPvHBV64AIbccdX3VRNeiNGBPk14eOOr5rwiea+nvE/uGTHv/D8ek6QD9lgmXD98zE1JHFbpcicgMP4EkxdR9P5TH/CJJP09bcqksHihmsK+xyRmX2y8xks7mMfwaqI1bEAkhENOyOl+H4W2S/ZRyUTfQJXlYl+t2IWOuQTlxra5aDp7YKCSFLaa2aG+wQ49xgKkTaC9A2n/AtI+4dpHz9eJjIkEpnyCwCnbMt2cyApJ5Dh+HQwU9q/oASbiQ+ukTDzNgw4oAnZVhor9ZEVHE4JciYaQknOnCiKtvOZ+cCFuISTMxRcnx9W8It/3vCTEjGLDAJfwAh8+BL3h83Su1UIG0YjhH39FbyNSo7GwsCstp2e9UlzsUGo1KVkJqTx5Il2Cq+nbdMRmk8ddQzvsm93W78YqfS4+NgOF1R6QAxvkUOA07nqSQOiQAR+pBpeQEzLfJlKyVQ8zUoZkCx8iihaTLCpyUvNz6IWGdKB8Bvtb8IKWEsBQN0zDhvYW9G2J3i6HCmPTmY2EOKat+VpL/yYB3PlDamXBM8KyOKm1wmPWYeF1rGJFBXgLYMu3Bie8EJs3+/iMQO4rQwtVDzL0h1X6grXdgTxKVU3n8kfMlfe5Z8jFXiaIniEvf5zRb8E1n8Mz0Od4xxdze2BZa2SmAEW9veyO/KADY+adFPt65S9j5JeNPV8mx8pWnj/WJdiIYcaIWBFO/le2azWY6AtZb3KgndUmUxf5CaNUqHQeTtvwyZMKfBfWpZF9PrxuxivPgkjlKkSZy7euG69EPKcOdgks2tT9k080/SnPqsj2lftTcfBoF3lfhYQjfxd6oo+iFZPqmxznziBN1nRCw2wBViaXACz4GXLSXYW9kMrBgIcSaF+dw917D174LCMmLfHybJNPgmUy12Mz4/2JcYfEVPQm2IgOT1qPZtvaP1xkNYxN0vWK6Xm+nEfp+na4lK4s5eludGSt0iq0N6QEH8JLuSxBG+OYOFAfns61mbPLIOV1+VYSfIbOACU3DWVU1pZk39EO0Ykdc2eVv0q0hGrVVCkkUQn6E1/0PiNDjn20txTTYYQtJ4pxkbOV8FSD1Gc749LGlSdiLPa2LiEIPmP02eq+XEZlLB90fpE/5ehv3zaQS+GEHJ9pAShUQlxhQyGZ96c1SBUgQj8KP48fKXhr3dikwTWFLsD1u4Batc0BXNcTg5nKn/TC8t41Mt4zLya2//sXFpBlSIPzBtjf8iN5m7B9Bl8A627+YuxZ44d0zpEQiWPZdz+UpSzlaNv+OhqzMR7nZqczsn2u2D1V3k/bGS/f0zBF5qRsvohB3VYBMr82QStraJxSjreg0lnj9zuZ6C0+u2kDxORFELO0md090QYLpjdBKAMBLC1uUituRyJRFaP2bEjNU/kD3eevGdxXukRioAuCCV32xQaMCEDQI/FfZstcMZyuT5V6MoHwxU3OQqbCLizmwMRZOnOn6dt3STa5/uh4GhGWO/glUhkhwSJoKBVKM3/jcrOwJyyi3cXSTPI9Tj9UT7p5i3gqu70L++kYTeluzTz3aNuXrKQMyiS9v8Vh4dnMnuhbeePxsr3rpt8iveD97ItU5bADTCWWX365+GBKyPJf8B5DVa2/qS15NV/4g38+i5gzyxAKi4IbIPFatQ2EfkAAAAASWv2IVJt1bcAAZ0hhSQAAMF/z3uxxGf7AgAAAAAEWVo="

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        # We don't want a KeyboardInterrupt throwing a
        # traceback into stdout.
        pass
