You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
331 lines
14 KiB
Python
331 lines
14 KiB
Python
"""
|
|
Copyright (c) Contributors to the Open 3D Engine Project
|
|
|
|
SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
"""
|
|
# -------------------------------------------------------------------------
|
|
|
|
"""Extend the .env using dynaconf (dynamic configuration and settings)
|
|
This config.py module assumes a minimal enviornment is defined in the .env
|
|
To do: ensure that we can stack/layer the dynamic env to work with O3DE projects
|
|
"""
|
|
|
|
# built in's
|
|
import os
|
|
import sys
|
|
import site
|
|
import re
|
|
|
|
# 3rdParty (possibly) py3 ships with pathlib, 2.7 does not
|
|
# import pathlib
|
|
# our framework for dcc tools need to run in apps like Maya that may still be
|
|
# on py27 so we need to import and use after some boostrapping
|
|
|
|
# -------------------------------------------------------------------+------
|
|
#os.environ['PYTHONINSPECT'] = 'True'
|
|
_MODULE_PATH = os.path.abspath(__file__)
|
|
|
|
# we don't have access yet to the DCCsi Lib\site-packages
|
|
# (1) this will give us import access to azpy (always?)
|
|
_DCCSIG_PATH = os.getenv('DCCSIG_PATH',
|
|
os.path.abspath(os.path.dirname(_MODULE_PATH)))
|
|
# ^ we assume this config is in the root of the DCCsi
|
|
# if it's not, be sure to set envar 'DCCSIG_PATH' to ensure it
|
|
site.addsitedir(_DCCSIG_PATH) # PYTHONPATH
|
|
|
|
# now we have azpy api access
|
|
import azpy
|
|
from azpy.env_bool import env_bool
|
|
from azpy.constants import ENVAR_DCCSI_GDEBUG
|
|
from azpy.constants import ENVAR_DCCSI_DEV_MODE
|
|
|
|
# set up global space, logging etc.
|
|
# set these true if you want them set globally for debugging
|
|
_DCCSI_GDEBUG = env_bool(ENVAR_DCCSI_GDEBUG, False)
|
|
_DCCSI_DEV_MODE = env_bool(ENVAR_DCCSI_DEV_MODE, False)
|
|
|
|
_PACKAGENAME = 'DCCsi.config'
|
|
|
|
_LOG_LEVEL = int(20)
|
|
if _DCCSI_GDEBUG:
|
|
_LOG_LEVEL = int(10)
|
|
_LOGGER = azpy.initialize_logger(_PACKAGENAME,
|
|
log_to_file=False,
|
|
default_log_level=_LOG_LEVEL)
|
|
_LOGGER.info('Starting up: {}.'.format({_PACKAGENAME}))
|
|
_LOGGER.info('site.addsitedir({})'.format(_DCCSIG_PATH))
|
|
_LOGGER.debug('_DCCSI_GDEBUG: {}'.format(_DCCSI_GDEBUG))
|
|
_LOGGER.debug('_DCCSI_DEV_MODE: {}'.format(_DCCSI_DEV_MODE))
|
|
|
|
# early attach WingIDE debugger (can refactor to include other IDEs later)
|
|
if _DCCSI_DEV_MODE:
|
|
from azpy.test.entry_test import connect_wing
|
|
foo = connect_wing()
|
|
# to do: ^ this should be replaced with full featured azpy.dev.util
|
|
# that supports additional debuggers (pycharm, vscode, etc.)
|
|
# -------------------------------------------------------------------------
|
|
|
|
|
|
# -------------------------------------------------------------------------
|
|
# (2) this will give us import access to modules we provide
|
|
_DCCSI_PYTHON_LIB_PATH = azpy.config_utils.bootstrap_dccsi_py_libs(_DCCSIG_PATH)
|
|
|
|
# Now we should be able to just carry on with pth lib and dynaconf
|
|
from dynaconf import Dynaconf
|
|
try:
|
|
import pathlib
|
|
except:
|
|
import pathlib2 as pathlib
|
|
from pathlib import Path
|
|
|
|
_DCCSIG_PATH = Path(_DCCSIG_PATH).resolve()
|
|
_DCCSI_PYTHON_LIB_PATH = Path(_DCCSI_PYTHON_LIB_PATH).resolve()
|
|
# -------------------------------------------------------------------------
|
|
|
|
|
|
# -------------------------------------------------------------------------
|
|
def init_ly_pyside(LY_DEV=None):
|
|
"""sets access to lumberyards Qt dlls and PySide"""
|
|
|
|
LY_DEV = Path(LY_DEV).resolve()
|
|
if not LY_DEV.exists():
|
|
raise Exception('LY_DEV does NOT exist: {0}'.format(LY_DEV))
|
|
else:
|
|
# to do: 'windows_vs2019' might change or be different locally
|
|
# 'windows_vs2019' is defined as a str tag in constants
|
|
# we may not yet have access to azpy.constants :(
|
|
from azpy.constants import TAG_DIR_LY_BUILD
|
|
from azpy.constants import PATH_LY_BUILD_PATH
|
|
from azpy.constants import PATH_LY_BIN_PATH
|
|
# to do: pull some of these str and tags from constants
|
|
LY_BUILD_PATH = Path.joinpath(LY_DEV,
|
|
TAG_DIR_LY_BUILD).resolve()
|
|
LY_BIN_PATH = Path.joinpath(LY_BUILD_PATH,
|
|
'bin',
|
|
'profile').resolve()
|
|
|
|
# # allows to retreive from settings.QTFORPYTHON_PATH
|
|
# from azpy.constants import STR_QTFORPYTHON_PATH # a path string constructor
|
|
# QTFORPYTHON_PATH = Path(STR_QTFORPYTHON_PATH.format(LY_DEV)).resolve()
|
|
# os.environ["DYNACONF_QTFORPYTHON_PATH"] = str(QTFORPYTHON_PATH)
|
|
# site.addsitedir(str(QTFORPYTHON_PATH)) # PYTHONPATH
|
|
|
|
QT_PLUGIN_PATH = Path.joinpath(LY_BIN_PATH,
|
|
'EditorPlugins').resolve()
|
|
os.environ["DYNACONF_QT_PLUGIN_PATH"] = str(QT_PLUGIN_PATH)
|
|
os.environ['PATH'] = QT_PLUGIN_PATH.as_posix() + os.pathsep + os.environ['PATH']
|
|
|
|
QT_QPA_PLATFORM_PLUGIN_PATH = Path.joinpath(QT_PLUGIN_PATH,
|
|
'platforms').resolve()
|
|
os.environ["DYNACONF_QT_QPA_PLATFORM_PLUGIN_PATH"] = str(QT_QPA_PLATFORM_PLUGIN_PATH)
|
|
# if the line below is removed external standalone apps can't load PySide2
|
|
os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = str(QT_QPA_PLATFORM_PLUGIN_PATH)
|
|
# ^^ bypass trying to set only with DYNACONF environment
|
|
os.environ['PATH'] = QT_QPA_PLATFORM_PLUGIN_PATH.as_posix() + os.pathsep + os.environ['PATH']
|
|
# ^^ this particular env only works correctly if put on the PATH in this manner
|
|
|
|
# add Qt binaries to the Windows path to handle findings DLL file dependencies
|
|
if sys.platform.startswith('win'):
|
|
# path = os.environ['PATH']
|
|
# newPath = ''
|
|
# newPath += str(LY_BIN_PATH) + os.pathsep
|
|
# newPath += str(Path.joinpath(QTFORPYTHON_PATH,
|
|
# 'shiboken2').resolve()) + os.pathsep
|
|
# newPath += str(Path.joinpath(QTFORPYTHON_PATH,
|
|
# 'PySide2').resolve()) + os.pathsep
|
|
# newPath += path
|
|
# os.environ['PATH']=newPath
|
|
_LOGGER.debug('PySide2 bootstrapped PATH for Windows.')
|
|
|
|
try:
|
|
import PySide2
|
|
_LOGGER.debug('DCCsi, config.py: SUCCESS: import PySide2')
|
|
_LOGGER.debug(PySide2)
|
|
status = True
|
|
except ImportError as e:
|
|
_LOGGER.debug('DCCsi, config.py: FAILURE: import PySide2')
|
|
status = False
|
|
raise(e)
|
|
|
|
try:
|
|
import shiboken2
|
|
_LOGGER.debug('DCCsi, config.py: SUCCESS: import shiboken2')
|
|
_LOGGER.debug(shiboken2)
|
|
status = True
|
|
except ImportError as e:
|
|
_LOGGER.debug('DCCsi, config.py: FAILURE: import shiboken2')
|
|
status = False
|
|
raise(e)
|
|
|
|
# set up the pyside2-tools (pyside2uic)
|
|
# to do: move path construction string to constants and build off of SDK
|
|
# have not done that yet as I really want to get legal approval and
|
|
# add this to the QtForPython Gem
|
|
# please pass this on the current code review
|
|
DCCSI_PYSIDE2_TOOLS = Path.joinpath(LY_DEV,
|
|
'Gems',
|
|
'AtomLyIntegration',
|
|
'TechnicalArt',
|
|
'DccScriptingInterface',
|
|
'.dev',
|
|
'QtForPython',
|
|
'pyside2-tools-dev')
|
|
os.environ["DYNACONF_DCCSI_PYSIDE2_TOOLS"] = str(DCCSI_PYSIDE2_TOOLS.resolve())
|
|
os.environ['PATH'] = DCCSI_PYSIDE2_TOOLS.as_posix() + os.pathsep + os.environ['PATH']
|
|
|
|
return status
|
|
# -------------------------------------------------------------------------
|
|
|
|
|
|
# -------------------------------------------------------------------------
|
|
def test_pyside2():
|
|
"""Convenience method to test Qt / PySide2 access"""
|
|
# now test
|
|
_LOGGER.info('Testing Qt / PySide2')
|
|
try:
|
|
from PySide2.QtWidgets import QApplication, QPushButton
|
|
app = QApplication(sys.argv)
|
|
hello = QPushButton("Hello world!")
|
|
hello.resize(200, 60)
|
|
hello.show()
|
|
except Exception as e:
|
|
_LOGGER.error('FAILURE: Qt / PySide2')
|
|
status = False
|
|
raise(e)
|
|
|
|
_LOGGER.info('SUCCESS: .test_pyside2()')
|
|
sys.exit(app.exec_())
|
|
# -------------------------------------------------------------------------
|
|
|
|
|
|
# -------------------------------------------------------------------------
|
|
# `envvar_prefix` = export envvars with `export DYNACONF_FOO=bar`.
|
|
# `settings_files` = Load this files in the order.
|
|
# here we are modifying or adding to the dynamic config settings on import
|
|
settings = Dynaconf(
|
|
envvar_prefix="DYNACONF",
|
|
settings_files=['settings.json', '.secrets.json'],
|
|
)
|
|
|
|
from azpy.constants import PATH_LY_BUILD_PATH
|
|
from azpy.constants import PATH_LY_BIN_PATH
|
|
|
|
# global settings
|
|
os.environ["DYNACONF_DCCSI_GDEBUG"] = str(_DCCSI_GDEBUG)
|
|
os.environ["DYNACONF_DCCSI_DEV_MODE"] = str(_DCCSI_DEV_MODE)
|
|
|
|
# search up to get \dev
|
|
_LY_DEV = azpy.config_utils.get_stub_check_path(in_path=_DCCSIG_PATH,
|
|
check_stub='engine.json')
|
|
os.environ["DYNACONF_LY_DEV"] = str(_LY_DEV.resolve())
|
|
_LY_PROJECT = azpy.config_utils.get_current_project()
|
|
os.environ["DYNACONF_LY_PROJECT"] = str(_LY_PROJECT.resolve())
|
|
_LY_PROJECT_PATH = Path(_LY_DEV, _LY_PROJECT)
|
|
os.environ["DYNACONF_LY_PROJECT_PATH"] = str(_LY_PROJECT_PATH)
|
|
os.environ["DYNACONF_DCCSIG_PATH"] = str(_DCCSIG_PATH)
|
|
_DCCSI_CONFIG_PATH = Path(_MODULE_PATH).resolve()
|
|
os.environ["DYNACONF_DCCSI_CONFIG_PATH"] = str(_DCCSI_CONFIG_PATH)
|
|
_DCCSIG_SDK_PATH = Path.joinpath(_DCCSIG_PATH, 'SDK').resolve()
|
|
os.environ["DYNACONF_DCCSIG_SDK_PATH"] = str(_DCCSIG_SDK_PATH)
|
|
os.environ["DYNACONF_DCCSI_PYTHON_LIB_PATH"] = str(_DCCSI_PYTHON_LIB_PATH)
|
|
os.environ["DYNACONF_OS_FOLDER"] = azpy.config_utils.get_os()
|
|
|
|
# we need to set up the Ly dev build \bin\path (for Qt dll access)
|
|
_LY_BUILD_PATH = Path(PATH_LY_BUILD_PATH).resolve()
|
|
os.environ["DYNACONF_LY_BUILD_PATH"] = str(_LY_BUILD_PATH)
|
|
_LY_BIN_PATH = Path(PATH_LY_BIN_PATH).resolve()
|
|
os.environ["DYNACONF_LY_BIN_PATH"] = str(_LY_BIN_PATH)
|
|
|
|
# project cache log dir path
|
|
from azpy.constants import ENVAR_DCCSI_LOG_PATH
|
|
from azpy.constants import PATH_DCCSI_LOG_PATH
|
|
_DCCSI_LOG_PATH = Path(os.getenv(ENVAR_DCCSI_LOG_PATH,
|
|
Path(PATH_DCCSI_LOG_PATH.format(LY_DEV=_LY_DEV,
|
|
LY_PROJECT=_LY_PROJECT))))
|
|
os.environ["DYNACONF_DCCSI_LOG_PATH"] = str(_DCCSI_LOG_PATH)
|
|
|
|
# hard checks
|
|
if not _LY_BIN_PATH.exists():
|
|
raise Exception('LY_BIN_PATH does NOT exist: {0}'.format(_LY_BIN_PATH))
|
|
else:
|
|
# adding to sys.path apparently doesn't work for .dll locations like Qt
|
|
os.environ['PATH'] = _LY_BIN_PATH.as_posix() + os.pathsep + os.environ['PATH']
|
|
|
|
_LOGGER.info('Dynaconf config.py ... DONE')
|
|
# -------------------------------------------------------------------------
|
|
|
|
|
|
# -------------------------------------------------------------------------
|
|
# settings.setenv() # doing this will add the additional DYNACONF_ envars
|
|
def get_config_settings(setup_ly_pyside=False):
|
|
"""Convenience method to set and retreive settings directly from module."""
|
|
from dynaconf import settings
|
|
|
|
if setup_ly_pyside:
|
|
init_ly_pyside(settings.LY_DEV)
|
|
|
|
settings.setenv()
|
|
return settings
|
|
# --- END -----------------------------------------------------------------
|
|
|
|
|
|
###########################################################################
|
|
# Main Code Block, runs this script as main (testing)
|
|
# -------------------------------------------------------------------------
|
|
if __name__ == '__main__':
|
|
"""Run this file as main"""
|
|
|
|
_LOG_LEVEL = int(10) # same as _logging.DEBUG
|
|
|
|
_LOGGER = azpy.initialize_logger(_PACKAGENAME,
|
|
log_to_file=True,
|
|
default_log_level=_LOG_LEVEL)
|
|
|
|
from dynaconf import settings
|
|
|
|
# not using fstrings in this module because it might run in py2.7 (maya)
|
|
_LOGGER.info('DCCSI_GDEBUG: {}'.format(settings.DCCSI_GDEBUG))
|
|
_LOGGER.info('DCCSI_DEV_MODE: {}'.format(settings.DCCSI_DEV_MODE))
|
|
_LOGGER.info('DCCSI_LOGLEVEL: {}'.format(settings.DCCSI_LOGLEVEL))
|
|
|
|
_LOGGER.info('OS_FOLDER: {}'.format(settings.OS_FOLDER))
|
|
_LOGGER.info('LY_PROJECT: {}'.format(settings.LY_PROJECT))
|
|
_LOGGER.info('LY_PROJECT_PATH: {}'.format(settings.LY_PROJECT_PATH))
|
|
_LOGGER.info('LY_DEV: {}'.format(settings.LY_DEV))
|
|
_LOGGER.info('LY_BUILD_PATH: {}'.format(settings.LY_BUILD_PATH))
|
|
_LOGGER.info('LY_BIN_PATH: {}'.format(settings.LY_BIN_PATH))
|
|
|
|
_LOGGER.info('DCCSI_LOG_PATH: {}'.format(settings.DCCSI_LOG_PATH))
|
|
|
|
_LOGGER.info('DCCSI_CONFIG_PATH: {}'.format(settings.DCCSI_CONFIG_PATH))
|
|
_LOGGER.info('DCCSIG_PATH: {}'.format(settings.DCCSIG_PATH))
|
|
_LOGGER.info('DCCSI_PYTHON_LIB_PATH: {}'.format(settings.DCCSI_PYTHON_LIB_PATH))
|
|
_LOGGER.info('DDCCSI_PY_BASE: {}'.format(settings.DDCCSI_PY_BASE))
|
|
|
|
# To Do: These should ONLY be set for Lumberyard and non-DCC environments
|
|
# They will most likely cause Qt/PySide DCC apps to fail
|
|
# or hopefully they can be overridden for DCC envionments
|
|
# that provide their own Qt dlls and Pyside2
|
|
#_LOGGER.info('QTFORPYTHON_PATH: {}'.format(settings.QTFORPYTHON_PATH))
|
|
#_LOGGER.info('QT_PLUGIN_PATH: {}'.format(settings.QT_PLUGIN_PATH))
|
|
|
|
init_ly_pyside(settings.LY_DEV) # init lumberyard Qt/PySide2
|
|
# from dynaconf import settings # <-- no need to reimport
|
|
|
|
settings.setenv() # doing this will add/set the additional DYNACONF_ envars
|
|
|
|
#_LOGGER.info('QTFORPYTHON_PATH: {}'.format(settings.QTFORPYTHON_PATH))
|
|
_LOGGER.info('LY_BIN_PATH: {}'.format(settings.LY_BIN_PATH))
|
|
_LOGGER.info('QT_PLUGIN_PATH: {}'.format(settings.QT_PLUGIN_PATH))
|
|
_LOGGER.info('QT_QPA_PLATFORM_PLUGIN_PATH: {}'.format(settings.QT_QPA_PLATFORM_PLUGIN_PATH))
|
|
_LOGGER.info('DCCSI_PYSIDE2_TOOLS: {}'.format(settings.DCCSI_PYSIDE2_TOOLS))
|
|
|
|
test_pyside2() # test PySide2 access with a pop-up button
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|