Last active
January 18, 2017 07:42
-
-
Save OlyDLG/8fa46739193b56305f6f86fd12b9d936 to your computer and use it in GitHub Desktop.
Function to write the contents, suitably encoded, of a text file, e.g., a Python source file, into an extended attribute of a target file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ArchiveSourceWithOutput.py | |
| # | |
| # Copyright 2017 by David Lawrence Goldsmith | |
| # License: BSD | |
| # Use at own risk; no warranty expressed or implied | |
| # | |
| # Two functions--encode_and_write and read_and_decode--to assist in, | |
| # among other potential uses, matching source code with output files, | |
| # (on platforms that support extended attributes via the xattr shell | |
| # command, e.g., Mac and some posix flavors): | |
| # | |
| # encode_and_write(source_file, target_file, xattr_name='source') | |
| # converts (the ascii content of) <source_file> (a valid path, as a | |
| # str) into a valid shell command line argument value, (i.e., a double- | |
| # quoted string free of other double-quotes, standard parentheses, and | |
| # newline characters), and "attaches" the result to <target_file> as | |
| # extended attribute <xattr_name> (default value 'source'). | |
| # | |
| # Example use-case: storage of the exact code that produces some output | |
| # file(s) as part of those output file(s), regardless of output format, | |
| # i.e., text source can be "pinned" to image files, pdf's, even directories | |
| # and sym. links, etc. | |
| # | |
| # read_and_decode(target_file, xattr_name='source') | |
| # encode_and_write's "inverse": reads in <target_file>'s extended attribute | |
| # <xattr_name> value, and converts it back into the original text file, | |
| # writing it out to a file with the same full path as the original, but with a '_' | |
| # preceding any '.' (TODO: add support for alternate output name in read_and_decode) | |
| # | |
| # Example usage: | |
| # | |
| # from ArchiveSourceWithOutput import * | |
| # : | |
| # msg = encode_and_write(__file__, targetfilepath) | |
| # if msg: print(msg) # msg is empty string unless something goes wrong | |
| # else: | |
| # msg = read_and_decode(targetfilepath) # Ditto | |
| # print(msg) | |
| from os import system, linesep | |
| from subprocess import getoutput | |
| def encode_and_write(source_file, target_file, xattr_name='source'): | |
| fail = getoutput('xattr') | |
| if fail: | |
| pass | |
| else: | |
| src = open(source_file) | |
| temp = src.readlines() | |
| src.close() | |
| cnts = source_file + ' _fn_ ' | |
| for line in temp: | |
| cnts += line[:-1] + ' _nl_ ' | |
| cnts = cnts.replace('(', '_lparen_') | |
| cnts = cnts.replace(')', '_rparen_') | |
| cnts = cnts.replace('"', '_dblquote_') | |
| fail = getoutput('chmod 660 ' + target_file) | |
| if fail: | |
| pass | |
| else: | |
| fail = getoutput('xattr -w ' + xattr_name + ' "' + cnts + '" ' + target_file) | |
| return fail | |
| def read_and_decode(target_file, xattr_name='source'): | |
| fail = system('xattr -p ' + xattr_name + ' ' + target_file) | |
| if fail: | |
| return fail | |
| else: | |
| fail = getoutput('xattr -p ' + xattr_name + ' ' + target_file) | |
| filename, fail = fail.split(' _fn_ ', 1) | |
| filename = filename.replace('.', '_.') | |
| fail = fail.replace('_dblquote_', '"') | |
| fail = fail.replace('_rparen_', ')') | |
| fail = fail.replace('_lparen_', '(') | |
| fail = fail.replace(' _nl_ ', linesep) | |
| fl = open(filename, 'w') | |
| fl.write(fail) | |
| fl.close() | |
| return '' | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment