%PDF- %PDF-
Direktori : /usr/lib/cups/driver/ |
Current File : //usr/lib/cups/driver/ptouch |
#!/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 import json from io import BytesIO from os.path import basename from errno import EPIPE import lzma def load(): ppds_compressed = base64.b64decode(ppds_compressed_b64) ppds_decompressed = decompress(ppds_compressed) ppds = json.loads(ppds_decompressed.decode(encoding='ASCII')) 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:] # Object for streaming decompression decompressor = lzma.LZMADecompressor() # size for one decompression i.e. ~20MB size = 20000000 ppds = load() ppds['ARCHIVE'] = base64.b64decode(ppds['ARCHIVE'].encode('ASCII')) ppdtext=bytearray() if ppd in ppds: start = ppds[ppd][0] length = ppds[ppd][1] text = BytesIO(decompressor.decompress(ppds['ARCHIVE'],size)) for i in range(int(start/size)): text = BytesIO(decompressor.decompress(ppds['ARCHIVE'],size)) text.seek(start%size) if((size-(start%size)) < length): ppdtext.extend(text.read()) length = length - (size-(start%size)) text = BytesIO(decompressor.decompress(ppds['ARCHIVE'],size)) while(size < length): ppdtext.extend(text.read()) length = length - size text = BytesIO(decompressor.decompress(ppds['ARCHIVE'],size)) ppdtext.extend(text.read(length)) else: ppdtext.extend(text.read(length)) return ppdtext def main(): usage = "usage: %prog list\n" \ " %prog cat URI" version = "%prog 1.1.0\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"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" if __name__ == "__main__": try: main() except KeyboardInterrupt: # We don't want a KeyboardInterrupt throwing a # traceback into stdout. pass