#!/usr/bin/env python3 """ Freeze the vasl-templates loader program. This script is called by the main freeze script. """ import sys import os import shutil import tempfile import getopt from PyInstaller.__main__ import run as run_pyinstaller from PIL import Image APP_ICON = os.path.join( os.path.abspath( os.path.dirname( __file__ ) ), "../vasl_templates/webapp/static/images/app.ico" ) # --------------------------------------------------------------------- def main( args ): """Main processing.""" # parse the command-line options output_fname = "./loader" work_dir = os.path.join( tempfile.gettempdir(), "freeze-loader" ) cleanup = True opts,args = getopt.getopt( args, "o:w:", ["output=","work=","no-clean"] ) for opt, val in opts: if opt in ["-o","--output"]: output_fname = val.strip() elif opt in ["-w","--work"]: work_dir = val.strip() elif opt in ["--no-clean"]: cleanup = False else: raise RuntimeError( "Unknown argument: {}".format( opt ) ) # freeze the loader program freeze_loader( output_fname, work_dir, cleanup ) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - def freeze_loader( output_fname, work_dir, cleanup ): """Freeze the loader program.""" with tempfile.TemporaryDirectory() as dist_dir: # initialize base_dir = os.path.abspath( os.path.dirname( __file__ ) ) assets_dir = os.path.join( base_dir, "assets" ) # convert the app icon to an image if not os.path.isdir( work_dir ): os.makedirs( work_dir ) app_icon_fname = os.path.join( work_dir, "app-icon.png" ) _convert_app_icon( app_icon_fname ) # initialize app_name = "loader" args = [ "--distpath", dist_dir, "--workpath", work_dir, "--specpath", work_dir, "--onefile", "--name", app_name, ] args.extend( [ "--add-data", app_icon_fname + os.pathsep + "assets/", "--add-data", os.path.join(assets_dir,"loading.gif") + os.pathsep + "assets/" ] ) if sys.platform == "win32": args.append( "--noconsole" ) args.extend( [ "--icon", APP_ICON ] ) args.append( os.path.join( base_dir, "main.py" ) ) # freeze the program run_pyinstaller( args ) # save the generated artifact fname = app_name+".exe" if sys.platform == "win32" else app_name shutil.move( os.path.join( dist_dir, fname ), output_fname ) # clean up if cleanup: shutil.rmtree( work_dir ) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - def _convert_app_icon( save_fname ): """Convert the app icon to an image.""" # NOTE: Tkinter's PhotoImage doesn't handle .ico files, so we convert the app icon # to an image, then insert it into the PyInstaller-generated executable (so that # we don't have to bundle Pillow into the release). img = Image.open( APP_ICON ) img = img.convert( "RGBA" ).resize( (48, 48) ) img.save( save_fname, "png" ) # --------------------------------------------------------------------- if __name__ == "__main__": main( sys.argv[1:] )