Skip to content

Instantly share code, notes, and snippets.

@nueh
Last active November 12, 2017 21:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nueh/97d90f980d408067e4d06f467a565dc5 to your computer and use it in GitHub Desktop.
Save nueh/97d90f980d408067e4d06f467a565dc5 to your computer and use it in GitHub Desktop.
Package a [Pythonista](http://omz-software.com/pythonista/) UI script and its corresponding .pyui file into a single self-extracting file
# PackUI by dgelessus
# https://github.com/dgelessus/pythonista-scripts/blob/master/UI/PackUI.py
#
# Package a UI script and its corresponding .pyui file into a single
# self-extracting file. When run, the generated script will unpack both files,
# allowing both running and further editing without limitations.
#
# The PackUI script itself can be given a py/pyui pair to package either using
# the (very basic) UI by running it directly, via sys.argv, or by importing it
# and using the PackUI.pack() function. All paths are considered relative to
# the current working directory.
import os.path
import base64
import bz2
def script_text(name, pyfile, pyuifile):
return '''\
# This is a self-extracting archive. Run this script once
# to extract the packaged application.
#
# The files will be extracted to '{name}.py' and '{name}.pyui'.
# Make sure that these files do not exist yet.
# To update from an older version, move or delete the old files first.
#
# This file was generated using PackUI
# (https://gist.github.com/nueh/97d90f980d408067e4d06f467a565dc5)
import console
import os.path
import base64
import bz2
NAME = "{name}"
PYFILE = """
{pyfile}
"""
PYUIFILE = """
{pyuifile}
"""
def main():
if os.path.exists(NAME + ".py"):
console.alert("Failed to Extract", NAME + ".py already exists.")
return
if os.path.exists(NAME + ".pyui"):
console.alert("Failed to Extract", NAME + ".pyui already exists.")
return
with open(NAME + ".py", 'wb') as f:
f.write(bz2.decompress(base64.b85decode(PYFILE.replace('\\n', ''))))
with open(NAME + ".pyui", 'wb') as f:
f.write(bz2.decompress(base64.b85decode(PYUIFILE.replace('\\n', ''))))
msg = NAME + ".py and " + NAME + ".pyui were successfully extracted!"
console.alert("Extraction Successful", msg, "OK", hide_cancel_button=True)
if __name__ == '__main__':
main()
'''.format(name=name, pyfile=pyfile, pyuifile=pyuifile)
def pack(path):
if not os.path.exists(path + ".py"):
raise IOError(path + ".py does not exist")
elif not os.path.isfile(path + ".py"):
raise IOError(path + ".py is not a file")
elif not os.path.exists(path + ".pyui"):
raise IOError(path + ".pyui does not exist")
elif not os.path.isfile(path + ".pyui"):
raise IOError(path + ".pyui is not a file")
elif os.path.exists(path + ".uipack.py"):
raise IOError(path + ".uipack.py already exists")
name = os.path.split(path)[1]
with open(path + ".py", 'rb') as f:
pyfile = base64.b85encode(bz2.compress(f.read()))
pyfile = '\n'.join(pyfile.decode('utf8')[pos:pos+76] for pos in range(0, len(str(pyfile)), 76))
with open(path + ".pyui", 'rb') as f:
pyuifile = base64.b85encode(bz2.compress(f.read()))
pyuifile = '\n'.join(pyuifile.decode('utf8')[pos:pos+76] for pos in range(0, len(str(pyuifile)), 76))
out = script_text(name, pyfile, pyuifile)
with open(path + ".uipack.py", 'w') as f:
f.write(out)
return out
def main():
import sys
if len(sys.argv) > 1: # pack files specified via argv
arg = ' '.join(sys.argv[1:])
try:
pack(arg)
except IOError as err:
print("Failed to pack program: " + err.message)
else: # display prompt for file
import console
msg = "Enter path (relative to current directory) of the application to be packaged, without .py or .pyui suffixes."
arg = console.input_alert("Package UI Application", msg)
try:
pack(arg)
except IOError as err:
console.alert("Failed to pack", err.message)
return
msg = "Application was successfully packaged into {}.uipack.py!".format(arg)
console.alert("Packaging Successful", msg, "OK", hide_cancel_button=True)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment