pyloid 0.19.1__tar.gz → 0.20.0__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyloid
3
- Version: 0.19.1
3
+ Version: 0.20.0
4
4
  Summary:
5
5
  Author: aesthetics-of-record
6
6
  Author-email: 111675679+aesthetics-of-record@users.noreply.github.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pyloid"
3
- version = "0.19.1"
3
+ version = "0.20.0"
4
4
  description = ""
5
5
  authors = ["aesthetics-of-record <111675679+aesthetics-of-record@users.noreply.github.com>"]
6
6
  readme = "README.md"
@@ -3,6 +3,6 @@ from .api import PyloidAPI, Bridge
3
3
  from .utils import get_production_path, is_production
4
4
  from .tray import TrayEvent
5
5
  from .timer import PyloidTimer
6
- from .builder import build_from_spec, cleanup_after_build, create_spec_from_json
6
+ from .builder import build_from_spec, cleanup_before_build, create_spec_from_json, get_site_packages
7
7
 
8
- __all__ = ['Pyloid', 'PyloidAPI', 'Bridge', 'get_production_path', 'is_production', 'TrayEvent', 'PyloidTimer', 'build_from_spec', 'cleanup_after_build', 'create_spec_from_json']
8
+ __all__ = ['Pyloid', 'PyloidAPI', 'Bridge', 'get_production_path', 'is_production', 'TrayEvent', 'PyloidTimer', 'build_from_spec', 'cleanup_before_build', 'create_spec_from_json', 'get_site_packages']
@@ -0,0 +1,80 @@
1
+ import json
2
+ from pathlib import Path
3
+ from PyInstaller.__main__ import run as pyinstaller_run
4
+ import shutil
5
+ import site
6
+ from pyloid.builder.spec import create_spec_from_json
7
+
8
+ __all__ = ['create_spec_from_json', 'cleanup_before_build', 'build_from_spec', 'get_site_packages']
9
+
10
+ def cleanup_before_build(json_path):
11
+ """Function to clean up unnecessary files before build"""
12
+ try:
13
+ with open(json_path, 'r', encoding='utf-8') as f:
14
+ config = json.load(f)
15
+
16
+ cleanup_patterns = config.get('before_build', {}).get('cleanup_patterns', [])
17
+ if not cleanup_patterns:
18
+ return Exception("Cannot find cleanup patterns.")
19
+
20
+ site_packages = get_site_packages()
21
+ if not site_packages:
22
+ raise Exception("Cannot find site-packages directory.")
23
+
24
+ dist_dir = Path(f'{site_packages}')
25
+ if not dist_dir.exists():
26
+ raise Exception(f"Cannot find directory to clean: {dist_dir}")
27
+
28
+ if not cleanup_patterns:
29
+ print("\033[1;33mNo cleanup patterns found. Files may have already been removed.\033[0m")
30
+ else:
31
+ print("\033[1;34mCleaning up unnecessary files...\033[0m")
32
+ for pattern in cleanup_patterns:
33
+ matching_files = list(dist_dir.glob(pattern))
34
+ if not matching_files:
35
+ print(f"\033[1;33mAleady removed: {pattern}\033[0m")
36
+ for file_path in matching_files:
37
+ print(f"\033[33mRemoving: {file_path}\033[0m")
38
+ if file_path.is_dir():
39
+ shutil.rmtree(file_path)
40
+ else:
41
+ file_path.unlink()
42
+ print(f"\033[32mRemoved: {file_path}\033[0m")
43
+
44
+ print("\033[1;32mFile cleanup completed.\033[0m")
45
+
46
+ except Exception as e:
47
+ raise Exception(f"\033[1;31mError occurred during file cleanup: {e}\033[0m")
48
+
49
+ def build_from_spec(spec_path):
50
+ try:
51
+ pyinstaller_run([
52
+ '--clean', # Clean temporary files
53
+ spec_path # Spec file path
54
+ ])
55
+ print("Build completed.")
56
+
57
+ except Exception as e:
58
+ raise Exception(f"Error occurred during build: {e}")
59
+
60
+ def get_site_packages():
61
+ """
62
+ Returns the path to the site-packages directory.
63
+ Raises an exception if the directory is not found.
64
+ """
65
+ for path in site.getsitepackages():
66
+ if 'site-packages' in path:
67
+ return path
68
+ raise Exception("Site-packages directory not found.")
69
+
70
+ def main():
71
+ spec_path = create_spec_from_json('build_config.json')
72
+
73
+ cleanup_before_build('build_config.json')
74
+
75
+ # build_from_spec(spec_path)
76
+
77
+
78
+
79
+ if __name__ == "__main__":
80
+ main()
@@ -0,0 +1,73 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "required": ["before_build", "name", "main_script", "datas", "excludes", "icon", "bundle"],
5
+ "properties": {
6
+ "before_build": {
7
+ "type": "object",
8
+ "properties": {
9
+ "cleanup_patterns": {
10
+ "type": "array",
11
+ "items": {
12
+ "type": "string"
13
+ },
14
+ "description": "List of file patterns to clean up in the library folder before building (used to remove files that cannot be excluded through pyinstaller) - default path is site-packages"
15
+ }
16
+ }
17
+ },
18
+ "name": {
19
+ "type": "string",
20
+ "description": "Application name"
21
+ },
22
+ "main_script": {
23
+ "type": "string",
24
+ "description": "Path to the main Python script"
25
+ },
26
+ "datas": {
27
+ "type": "array",
28
+ "items": {
29
+ "type": "array",
30
+ "minItems": 2,
31
+ "maxItems": 2,
32
+ "items": [
33
+ { "type": "string" },
34
+ { "type": "string" }
35
+ ]
36
+ },
37
+ "description": "List of data files to include [source path, destination path]"
38
+ },
39
+ "excludes": {
40
+ "type": "array",
41
+ "items": {
42
+ "type": "string"
43
+ },
44
+ "description": "List of modules to exclude during build with pyinstaller"
45
+ },
46
+ "icon": {
47
+ "type": "string",
48
+ "description": "Path to the application icon file"
49
+ },
50
+ "bundle": {
51
+ "type": "object",
52
+ "properties": {
53
+ "windows": {
54
+ "type": "string",
55
+ "enum": ["onefile", "directory"],
56
+ "description": "Windows build type"
57
+ },
58
+ "macos": {
59
+ "type": "string",
60
+ "enum": ["app"],
61
+ "description": "macOS build type"
62
+ },
63
+ "linux": {
64
+ "type": "string",
65
+ "enum": ["onefile", "directory"],
66
+ "description": "Linux build type"
67
+ }
68
+ },
69
+ "required": ["windows", "macos", "linux"],
70
+ "description": "Build settings for each OS"
71
+ }
72
+ }
73
+ }
@@ -1,20 +1,13 @@
1
+ from pyloid.utils import get_platform
1
2
  import json
2
- import os
3
- import subprocess
4
3
  from pathlib import Path
5
- from pyloid.utils import get_platform
6
- from PyInstaller.__main__ import run as pyinstaller_run
7
- import shutil
8
-
9
4
 
10
5
  def create_spec_from_json(json_path):
11
6
  with open(json_path, 'r', encoding='utf-8') as f:
12
7
  config = json.load(f)
13
8
 
14
- # Create spec file for each OS
15
9
  os_type = get_platform()
16
10
 
17
- # Select template for each OS
18
11
  if os_type == 'macos':
19
12
  spec_content = _create_macos_spec(config)
20
13
  elif os_type == 'linux':
@@ -22,14 +15,15 @@ def create_spec_from_json(json_path):
22
15
  else: # windows
23
16
  spec_content = _create_windows_spec(config)
24
17
 
25
- # Save spec file
26
18
  spec_path = Path(f"build-{os_type}.spec")
27
19
  spec_path.write_text(spec_content, encoding='utf-8')
28
20
 
29
21
  return str(spec_path)
30
22
 
31
23
  def _create_windows_spec(config):
32
- return f"""# -*- mode: python ; coding: utf-8 -*-
24
+ bundle_type = config.get('bundle', {}).get('windows', 'directory')
25
+
26
+ base_spec = f"""# -*- mode: python ; coding: utf-8 -*-
33
27
 
34
28
  block_cipher = None
35
29
 
@@ -51,7 +45,35 @@ a = Analysis(
51
45
 
52
46
  pyz = PYZ(a.pure, a.zipped_data,
53
47
  cipher=block_cipher)
48
+ """
54
49
 
50
+ if bundle_type == 'onefile':
51
+ return base_spec + f"""
52
+ exe = EXE(
53
+ pyz,
54
+ a.scripts,
55
+ a.binaries,
56
+ a.zipfiles,
57
+ a.datas,
58
+ [],
59
+ name='{config.get("name", "pyloid-app")}',
60
+ debug=False,
61
+ bootloader_ignore_signals=False,
62
+ strip=False,
63
+ upx=True,
64
+ upx_exclude=[],
65
+ runtime_tmpdir=None,
66
+ console=False,
67
+ disable_windowed_traceback=False,
68
+ argv_emulation=False,
69
+ target_arch=None,
70
+ codesign_identity=None,
71
+ entitlements_file=None,
72
+ icon='{config.get('icon', 'src-pyloid/icons/icon.ico')}'
73
+ )
74
+ """
75
+ else:
76
+ return base_spec + f"""
55
77
  exe = EXE(
56
78
  pyz,
57
79
  a.scripts,
@@ -140,7 +162,9 @@ app = BUNDLE(
140
162
  """
141
163
 
142
164
  def _create_linux_spec(config):
143
- return f"""# -*- mode: python ; coding: utf-8 -*-
165
+ bundle_type = config.get('bundle', {}).get('linux', 'directory')
166
+
167
+ base_spec = f"""# -*- mode: python ; coding: utf-8 -*-
144
168
 
145
169
  block_cipher = None
146
170
 
@@ -162,7 +186,35 @@ a = Analysis(
162
186
 
163
187
  pyz = PYZ(a.pure, a.zipped_data,
164
188
  cipher=block_cipher)
189
+ """
165
190
 
191
+ if bundle_type == 'onefile':
192
+ return base_spec + f"""
193
+ exe = EXE(
194
+ pyz,
195
+ a.scripts,
196
+ a.binaries,
197
+ a.zipfiles,
198
+ a.datas,
199
+ [],
200
+ name='{config.get("name", "pyloid-app")}',
201
+ debug=False,
202
+ bootloader_ignore_signals=False,
203
+ strip=False,
204
+ upx=True,
205
+ upx_exclude=[],
206
+ runtime_tmpdir=None,
207
+ console=False,
208
+ disable_windowed_traceback=False,
209
+ argv_emulation=False,
210
+ target_arch=None,
211
+ codesign_identity=None,
212
+ entitlements_file=None,
213
+ icon={config.get('icon', 'src-pyloid/icons/icon.png')}
214
+ )
215
+ """
216
+ else:
217
+ return base_spec + f"""
166
218
  exe = EXE(
167
219
  pyz,
168
220
  a.scripts,
@@ -192,58 +244,4 @@ coll = COLLECT(
192
244
  upx_exclude=[],
193
245
  name='{config.get("name", "pyloid-app")}'
194
246
  )
195
- """
196
-
197
- def cleanup_after_build(json_path):
198
- """Function to clean up unnecessary files after build"""
199
- try:
200
- with open(json_path, 'r', encoding='utf-8') as f:
201
- config = json.load(f)
202
-
203
- cleanup_patterns = config.get('cleanup_patterns', [])
204
- if not cleanup_patterns:
205
- return True
206
-
207
- dist_dir = Path(f'dist/{config.get("name", "pyloid-app")}')
208
- if not dist_dir.exists():
209
- print(f"Cannot find directory to clean: {dist_dir}")
210
- return False
211
-
212
- print("Cleaning up unnecessary files...")
213
- for pattern in cleanup_patterns:
214
- for file_path in dist_dir.glob(pattern):
215
- if file_path.is_dir():
216
- shutil.rmtree(file_path)
217
- else:
218
- file_path.unlink()
219
- print(f"Removed: {file_path}")
220
-
221
- print("File cleanup completed.")
222
- return True
223
-
224
- except Exception as e:
225
- print(f"Error occurred during file cleanup: {e}")
226
- return False
227
-
228
- def build_from_spec(spec_path):
229
- try:
230
- pyinstaller_run([
231
- '--clean', # Clean temporary files
232
- spec_path # Spec file path
233
- ])
234
- print("Build completed.")
235
-
236
- return True
237
- except Exception as e:
238
- print(f"Error occurred during build: {e}")
239
- return False
240
-
241
- def main():
242
- spec_path = create_spec_from_json('build_config.json')
243
-
244
- build_from_spec(spec_path)
245
-
246
- cleanup_after_build('build_config.json')
247
-
248
- if __name__ == "__main__":
249
- main()
247
+ """
@@ -1,27 +0,0 @@
1
- {
2
- "name": "pyloid-app",
3
- "datas": [
4
- ["src-pyloid/icons/", "src-pyloid/icons/"],
5
- ["build-front/", "build-front/"]
6
- ],
7
- "excludes": [
8
- "PySide6.QtQml",
9
- "PySide6.QtTest",
10
- "PySide6.Qt3D",
11
- "PySide6.QtSensors",
12
- "PySide6.QtCharts",
13
- "PySide6.QtGraphs",
14
- "PySide6.QtDataVisualization",
15
- "PySide6.QtQuick",
16
- "PySide6.QtDesigner",
17
- "PySide6.QtUiTools",
18
- "PySide6.QtHelp"
19
- ],
20
- "icon": "src-pyloid/icons/icon.ico",
21
- "after_build": {
22
- "cleanup_patterns": [
23
- "_internal/PySide*/opengl32sw.dll",
24
- "_internal/PySide*/translations"
25
- ]
26
- }
27
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes