Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@
/dist/
/.idea/
/build/lib/exam_generator/
/packaging/windows/build/exam_generator/
31 changes: 31 additions & 0 deletions packaging/windows/build_windows_exe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
"""
Builds a Windows executable of exam_generator using PyInstaller
"""
import os
import shutil
from PyInstaller.__main__ import run as pyinstaller_run

# Specifications for PyInstaller
spec_file = "exam_generator.spec"

# Directories where to build into
script_dir = os.getcwd()
build_dir = os.path.join(script_dir, "build")
temp_dir = os.path.join(script_dir, "temp")

# Build the command string
cmd = ["--clean", f"--distpath={build_dir}", f"--workpath={temp_dir}", spec_file]

# Clean-up environment
for dir in [build_dir, temp_dir]:
if os.path.exists(dir):
shutil.rmtree(dir, ignore_errors=True)

# Call pyinstaller
print(f"Executing pyinstaller {' '.join(cmd)}")
pyinstaller_run(cmd)

# Remove temp data
if os.path.exists(temp_dir):
shutil.rmtree(temp_dir, ignore_errors=True)
58 changes: 58 additions & 0 deletions packaging/windows/exam_generator.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# -*- mode: python ; coding: utf-8 -*-
import sys
import os
import glob
from PyInstaller.utils.hooks import get_module_file_attribute

# Location of source and script files
repo_dir = os.path.realpath('../..')
module_dir = os.path.join(repo_dir, 'src/exam_generator')

# Templates and settings of exam_generator needs to be shipped as well
data_files = [(filename, './templates') for filename in glob.glob(os.path.join(module_dir, 'templates', '*.tex'))]
data_files += [(os.path.join(repo_dir, 'settings'), './settings')]

# It's open source, so we do not need to encrypt the python code
block_cipher = None

# Catch really every package loaded by exam_generator
sys.setrecursionlimit(sys.getrecursionlimit() * 5)

# Analyze what needs to be packaged
a = Analysis([os.path.join(repo_dir, 'run_exam_generator.py')],
pathex=[repo_dir, module_dir],
binaries=[],
datas=data_files,
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)

# Put everything together
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

# Specification for building the exe
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='exam_generator',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True)

# Collection of all information needed for building the exe
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='exam_generator')
2 changes: 2 additions & 0 deletions run_exam_generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import exam_generator as eg
eg.main()