mirror of
https://github.com/blw1138/Zordon.git
synced 2025-12-17 08:48:13 +00:00
Pyinstaller support (#93)
* Add main.spec * Fix issue where fetching supported extensions would crash with no default installation
This commit is contained in:
64
main.spec
Normal file
64
main.spec
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
# -*- mode: python ; coding: utf-8 -*-
|
||||||
|
from PyInstaller.utils.hooks import collect_all
|
||||||
|
|
||||||
|
# - get version from version file
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, os.path.abspath('.'))
|
||||||
|
from version import APP_NAME, APP_VERSION
|
||||||
|
|
||||||
|
datas = [('resources', 'resources'), ('src/engines/blender/scripts/', 'src/engines/blender/scripts')]
|
||||||
|
binaries = []
|
||||||
|
hiddenimports = ['zeroconf']
|
||||||
|
tmp_ret = collect_all('zeroconf')
|
||||||
|
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
|
||||||
|
|
||||||
|
|
||||||
|
a = Analysis(
|
||||||
|
['main.py'],
|
||||||
|
pathex=[],
|
||||||
|
binaries=binaries,
|
||||||
|
datas=datas,
|
||||||
|
hiddenimports=hiddenimports,
|
||||||
|
hookspath=[],
|
||||||
|
hooksconfig={},
|
||||||
|
runtime_hooks=[],
|
||||||
|
excludes=[],
|
||||||
|
noarchive=False,
|
||||||
|
optimize=0,
|
||||||
|
)
|
||||||
|
pyz = PYZ(a.pure)
|
||||||
|
|
||||||
|
exe = EXE(
|
||||||
|
pyz,
|
||||||
|
a.scripts,
|
||||||
|
[],
|
||||||
|
exclude_binaries=True,
|
||||||
|
name='main',
|
||||||
|
debug=False,
|
||||||
|
bootloader_ignore_signals=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
console=False,
|
||||||
|
disable_windowed_traceback=False,
|
||||||
|
argv_emulation=False,
|
||||||
|
target_arch=None,
|
||||||
|
codesign_identity=None,
|
||||||
|
entitlements_file=None,
|
||||||
|
)
|
||||||
|
coll = COLLECT(
|
||||||
|
exe,
|
||||||
|
a.binaries,
|
||||||
|
a.datas,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
upx_exclude=[],
|
||||||
|
name='main',
|
||||||
|
)
|
||||||
|
app = BUNDLE(
|
||||||
|
coll,
|
||||||
|
name=f'{APP_NAME}.app',
|
||||||
|
icon=None,
|
||||||
|
bundle_identifier=None,
|
||||||
|
version=APP_VERSION
|
||||||
|
)
|
||||||
22
setup.py
22
setup.py
@@ -1,22 +0,0 @@
|
|||||||
"""
|
|
||||||
This is a setup.py script generated by py2applet
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
python setup.py py2app
|
|
||||||
"""
|
|
||||||
import glob
|
|
||||||
|
|
||||||
from setuptools import setup
|
|
||||||
|
|
||||||
APP = ['main.py']
|
|
||||||
DATA_FILES = [('config', glob.glob('config/*.*')),
|
|
||||||
('resources', glob.glob('resources/*.*'))]
|
|
||||||
OPTIONS = {}
|
|
||||||
|
|
||||||
setup(
|
|
||||||
app=APP,
|
|
||||||
data_files=DATA_FILES,
|
|
||||||
options={'py2app': OPTIONS},
|
|
||||||
setup_requires=['py2app'],
|
|
||||||
name='Zordon'
|
|
||||||
)
|
|
||||||
@@ -22,12 +22,12 @@ class Blender(BaseRenderEngine):
|
|||||||
from src.engines.blender.blender_worker import BlenderRenderWorker
|
from src.engines.blender.blender_worker import BlenderRenderWorker
|
||||||
return BlenderRenderWorker
|
return BlenderRenderWorker
|
||||||
|
|
||||||
def ui_options(self):
|
|
||||||
from src.engines.blender.blender_ui import BlenderUI
|
|
||||||
return BlenderUI.get_options(self)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def supported_extensions():
|
def ui_options(system_info):
|
||||||
|
from src.engines.blender.blender_ui import BlenderUI
|
||||||
|
return BlenderUI.get_options(system_info)
|
||||||
|
|
||||||
|
def supported_extensions(self):
|
||||||
return ['blend']
|
return ['blend']
|
||||||
|
|
||||||
def version(self):
|
def version(self):
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
class BlenderUI:
|
class BlenderUI:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_options(instance):
|
def get_options(system_info):
|
||||||
options = [
|
options = [
|
||||||
{'name': 'engine', 'options': instance.supported_render_engines()},
|
{'name': 'engine', 'options': system_info.get('engines', [])},
|
||||||
{'name': 'render_device', 'options': ['Any', 'GPU', 'CPU']},
|
{'name': 'render_device', 'options': ['Any', 'GPU', 'CPU']},
|
||||||
]
|
]
|
||||||
return options
|
return options
|
||||||
|
|||||||
@@ -9,12 +9,11 @@ SUBPROCESS_TIMEOUT = 5
|
|||||||
class BaseRenderEngine(object):
|
class BaseRenderEngine(object):
|
||||||
|
|
||||||
install_paths = []
|
install_paths = []
|
||||||
supported_extensions = []
|
|
||||||
|
|
||||||
def __init__(self, custom_path=None):
|
def __init__(self, custom_path=None):
|
||||||
self.custom_renderer_path = custom_path
|
self.custom_renderer_path = custom_path
|
||||||
if not self.renderer_path() or not os.path.exists(self.renderer_path()):
|
if not self.renderer_path() or not os.path.exists(self.renderer_path()):
|
||||||
raise FileNotFoundError(f"Cannot find path to renderer for {self.name()} instance")
|
raise FileNotFoundError(f"Cannot find path to renderer for {self.name()} instance: {self.renderer_path()}")
|
||||||
|
|
||||||
if not os.access(self.renderer_path(), os.X_OK):
|
if not os.access(self.renderer_path(), os.X_OK):
|
||||||
logger.warning(f"Path is not executable. Setting permissions to 755 for {self.renderer_path()}")
|
logger.warning(f"Path is not executable. Setting permissions to 755 for {self.renderer_path()}")
|
||||||
@@ -43,6 +42,9 @@ class BaseRenderEngine(object):
|
|||||||
def version(self):
|
def version(self):
|
||||||
raise NotImplementedError("version not implemented")
|
raise NotImplementedError("version not implemented")
|
||||||
|
|
||||||
|
def supported_extensions(self):
|
||||||
|
return []
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def downloader(): # override when subclassing if using a downloader class
|
def downloader(): # override when subclassing if using a downloader class
|
||||||
return None
|
return None
|
||||||
@@ -51,7 +53,8 @@ class BaseRenderEngine(object):
|
|||||||
def worker_class(): # override when subclassing to link worker class
|
def worker_class(): # override when subclassing to link worker class
|
||||||
raise NotImplementedError("Worker class not implemented")
|
raise NotImplementedError("Worker class not implemented")
|
||||||
|
|
||||||
def ui_options(self): # override to return options for ui
|
@staticmethod
|
||||||
|
def ui_options(system_info): # override to return options for ui
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def get_help(self): # override if renderer uses different help flag
|
def get_help(self): # override if renderer uses different help flag
|
||||||
|
|||||||
@@ -266,9 +266,9 @@ class EngineManager:
|
|||||||
_, extension = os.path.splitext(path)
|
_, extension = os.path.splitext(path)
|
||||||
extension = extension.lower().strip('.')
|
extension = extension.lower().strip('.')
|
||||||
for engine in cls.supported_engines():
|
for engine in cls.supported_engines():
|
||||||
if extension in engine.supported_extensions():
|
if extension in engine().supported_extensions():
|
||||||
return engine
|
return engine
|
||||||
undefined_renderer_support = [x for x in cls.supported_engines() if not x.supported_extensions()]
|
undefined_renderer_support = [x for x in cls.supported_engines() if not x().supported_extensions()]
|
||||||
return undefined_renderer_support[0]
|
return undefined_renderer_support[0]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,9 +21,8 @@ class FFMPEG(BaseRenderEngine):
|
|||||||
from src.engines.ffmpeg.ffmpeg_ui import FFMPEGUI
|
from src.engines.ffmpeg.ffmpeg_ui import FFMPEGUI
|
||||||
return FFMPEGUI.get_options(self)
|
return FFMPEGUI.get_options(self)
|
||||||
|
|
||||||
@classmethod
|
def supported_extensions(self):
|
||||||
def supported_extensions(cls):
|
help_text = (subprocess.check_output([self.renderer_path(), '-h', 'full'], stderr=subprocess.STDOUT)
|
||||||
help_text = (subprocess.check_output([cls().renderer_path(), '-h', 'full'], stderr=subprocess.STDOUT)
|
|
||||||
.decode('utf-8'))
|
.decode('utf-8'))
|
||||||
found = re.findall(r'extensions that .* is allowed to access \(default "(.*)"', help_text)
|
found = re.findall(r'extensions that .* is allowed to access \(default "(.*)"', help_text)
|
||||||
found_extensions = set()
|
found_extensions = set()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
class FFMPEGUI:
|
class FFMPEGUI:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_options(instance):
|
def get_options(system_info):
|
||||||
options = []
|
options = []
|
||||||
return options
|
return options
|
||||||
|
|||||||
@@ -68,11 +68,12 @@ class NewRenderJobForm(QWidget):
|
|||||||
# Setup
|
# Setup
|
||||||
self.setWindowTitle("New Job")
|
self.setWindowTitle("New Job")
|
||||||
self.setup_ui()
|
self.setup_ui()
|
||||||
|
self.update_renderer_info()
|
||||||
self.setup_project()
|
self.setup_project()
|
||||||
|
|
||||||
# get renderer info in bg thread
|
# get renderer info in bg thread
|
||||||
t = threading.Thread(target=self.update_renderer_info)
|
# t = threading.Thread(target=self.update_renderer_info)
|
||||||
t.start()
|
# t.start()
|
||||||
|
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
@@ -348,7 +349,8 @@ class NewRenderJobForm(QWidget):
|
|||||||
# Dynamic Engine Options
|
# Dynamic Engine Options
|
||||||
clear_layout(self.renderer_options_layout) # clear old options
|
clear_layout(self.renderer_options_layout) # clear old options
|
||||||
# dynamically populate option list
|
# dynamically populate option list
|
||||||
self.current_engine_options = engine().ui_options()
|
system_info = self.renderer_info.get(engine.name(), {}).get('system_info', {})
|
||||||
|
self.current_engine_options = engine.ui_options(system_info=system_info)
|
||||||
for option in self.current_engine_options:
|
for option in self.current_engine_options:
|
||||||
h_layout = QHBoxLayout()
|
h_layout = QHBoxLayout()
|
||||||
label = QLabel(option['name'].replace('_', ' ').capitalize() + ':')
|
label = QLabel(option['name'].replace('_', ' ').capitalize() + ':')
|
||||||
|
|||||||
2
version.py
Normal file
2
version.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
APP_NAME = "Zordon"
|
||||||
|
APP_VERSION = "0.0.1"
|
||||||
Reference in New Issue
Block a user