-
Notifications
You must be signed in to change notification settings - Fork 0
/
compile.py
executable file
·138 lines (107 loc) · 4.13 KB
/
compile.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env python
import ctypes
import os
import shlex
import sys
from os.path import basename, expanduser, isdir
from os.path import join as joinpath
from os.path import splitext
from posixpath import abspath
from subprocess import run as run_proc
SCRIPT_PATH = 'app.py'
ICON_PATH = 'icon.ico'
WINDOW_ICON_PATH = 'icon.png'
APP_NAME = 'Form Filler'
ENSURE_PACKAGES = (
'docxtpl', 'pyinstaller', 'pandas', 'openpyxl', 'PyPdf2'
)
# Commands
PIP_CMD = '"{}" -m pip --no-input'.format(sys.executable)
CHECK_PACKAGE_CMD = PIP_CMD + ' show {0}'
INSTALL_PACKAGE_CMD = PIP_CMD + ' install {0}'
PYINSTALLER_CMD = (
' --noconfirm'
' --clean'
' --noconsole'
' --icon={icon_path}'
' --add-data "{window_icon_path}{sep}."'
' -n "{app_name}"'
' "{python_file}"'
)
def main():
# Make sure python dependencies are installed
for pkg_name in ENSURE_PACKAGES:
ensure_package(pkg_name)
compile_script(SCRIPT_PATH, APP_NAME, ICON_PATH, WINDOW_ICON_PATH)
print('Executable should be found under ./dist folder')
# create_desktop_shortcut(get_compiled_script_path(APP_NAME))
def run(cmd, **kwargs):
cmd_args = shlex.split(cmd)
print('Running: {}'.format(cmd_args))
return run_proc(cmd_args, **kwargs)
def ensure_package(package_name):
cmd = run(CHECK_PACKAGE_CMD.format(package_name))
if cmd.returncode != 0:
install_package(package_name)
def install_package(package_name):
print("Installing package {}".format(package_name))
cmd = run(INSTALL_PACKAGE_CMD.format(package_name))
assert cmd.returncode == 0, "Package installation failed"
def compile_script(script_path, app_name, icon_path, window_icon):
from PyInstaller.__main__ import run as run_pyinstaller
cmd = PYINSTALLER_CMD.format(
python_file=script_path,
icon_path=icon_path,
window_icon_path=window_icon,
app_name=app_name,
sep=';' if os.name == 'nt' else ':'
)
print('Running pyinstaller with args: {}'.format(cmd))
run_pyinstaller(shlex.split(cmd))
def get_compiled_script_path(app_name, output_dir='./dist'):
if os.name == 'nt':
return joinpath(output_dir, '{}.exe'.format(app_name))
elif sys.platform == 'darwin':
return joinpath(output_dir, '{}.app'.format(app_name))
elif os.name == 'posix':
return joinpath(output_dir, '{}'.format(app_name))
def create_desktop_shortcut(target_path, shortcut_name=None):
"""
Creates a desktop shortcut to the specified file or directory.
:param target_path: The path to the file or directory to create a shortcut
to. Can be relative or absolute.
:param shortcut_name: The name of the shortcut file that will be placed in
the desktop, if None will be generated automatically.
"""
target_path = abspath(target_path)
shortcut_name = shortcut_name or splitext(basename(target_path))[0]
desktop_path = pathutil.get_desktop_path()
if desktop_path and isdir(desktop_path):
shortcut_path = joinpath(desktop_path, shortcut_name)
print('Creating shortcut "{}" to "{}"'.format(shortcut_path, target_path))
pathutil.create_shortcut(target_path, shortcut_path)
else:
print('Desktop folder not found, skipping shortcut creation')
class WindowsPathUtil(object):
@classmethod
def get_desktop_path(cls):
return ctypes.windll.shell32.SHGetFolderPathW(0, 0, 0, 0)
@classmethod
def create_shortcut(cls, file_path, shortcut_path, is_dir=False,
extention='.lnk'):
shortcut_path += extention
kdll = ctypes.windll.LoadLibrary('kernel32.dll')
kdll.CreateSymbolicLinkW(shortcut_path, file_path, int(is_dir))
class PosixPathUtil(object):
@classmethod
def get_desktop_path(cls):
path = expanduser('~/Desktop')
return path if isdir(path) else None
@classmethod
def create_shortcut(cls, file_path, shortcut_path, is_dir=False,
extention=''):
shortcut_path += extention
run('ln -s "{}" "{}"'.format(file_path, shortcut_path))
pathutil = WindowsPathUtil if os.name == 'nt' else PosixPathUtil
if __name__ == '__main__':
main()