[kupfer] Add execfile.py for saving executable kupfer commands to file



commit 3093c3d0720252171be0d8663cd7cf696adb0877
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Wed Feb 10 03:57:44 2010 +0100

    Add execfile.py for saving executable kupfer commands to file
    
    We use the oldest pickle protocol, the ASCII protocol, to pickle the
    files, so that we get pure text files (but they are not
    user-editable).

 kupfer/execfile.py |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)
---
diff --git a/kupfer/execfile.py b/kupfer/execfile.py
new file mode 100644
index 0000000..ace546e
--- /dev/null
+++ b/kupfer/execfile.py
@@ -0,0 +1,47 @@
+import pickle
+import os
+
+from kupfer import pretty
+from kupfer import puid
+from kupfer import conspickle
+
+KUPFER_COMMAND_SHEBANG="#!/usr/bin/env kupfer-exec\n"
+
+def execute_file(filepath):
+	"""Execute serialized command inside @filepath
+
+	The file must be executable (comparable to a shell script)
+	>>> execute_file(__file__)  # doctest: +ELLIPSIS
+	Traceback (most recent call last):
+	    ...
+	OSError: ... is not executable
+	"""
+	if not os.path.exists(filepath):
+		raise IOError("%s does not exist" % (filepath, ))
+	if not os.access(filepath, os.X_OK):
+		raise OSError("%s is not executable" % (filepath, ))
+	data = open(filepath).read()
+	# strip shebang away
+	if data.startswith("#!") and "\n" in data:
+		shebang, data = data.split("\n", 1)
+
+	try:
+		id_ = conspickle.BasicUnpickler.loads(data)
+		command_object = puid.resolve_unique_id(id_)
+	except pickle.UnpicklingError, err:
+		pretty.print_error(__name__, "Could not read", filepath, err)
+		return
+	command_object.run()
+
+def save_to_file(command_leaf, filename):
+	fd = os.open(filename, os.O_CREAT | os.O_EXCL | os.O_WRONLY, 0o777)
+	wfile = os.fdopen(fd, "wb")
+	try:
+		wfile.write(KUPFER_COMMAND_SHEBANG)
+		pickle.dump(puid.get_unique_id(command_leaf), wfile, 0)
+	finally:
+		wfile.close()
+
+if __name__ == '__main__':
+	import doctest
+	doctest.testmod()



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]