Create attractive VASL scenarios, with loads of useful information embedded to assist with game play.
https://vasl-templates.org
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
6.8 KiB
154 lines
6.8 KiB
2 years ago
|
""" Manage information about the current user. """
|
||
|
|
||
|
import sys
|
||
|
import os
|
||
|
import shutil
|
||
|
import tempfile
|
||
|
import logging
|
||
|
|
||
|
import appdirs
|
||
|
|
||
|
_APP_NAME = "vasl-templates"
|
||
|
_APP_AUTHOR = "pacman-ghost"
|
||
|
|
||
|
_logger = logging.getLogger( "user_profile" )
|
||
|
|
||
|
# ---------------------------------------------------------------------
|
||
|
|
||
|
class UserProfile:
|
||
|
"""Manage information about the current user."""
|
||
|
|
||
|
def __init__( self, app_config ):
|
||
|
|
||
|
# initialize
|
||
|
is_desktop_app = os.environ.get( "IS_DESKTOP_APP" ) is not None
|
||
|
is_container = app_config.get( "IS_CONTAINER" ) is not None
|
||
|
|
||
|
# configure the location of the user's config files
|
||
|
if is_desktop_app:
|
||
|
self.config_dname = "/tmp" if is_container \
|
||
|
else self._check_dir( appdirs.user_config_dir( _APP_NAME, _APP_AUTHOR, roaming=True ) )
|
||
|
self.desktop_settings_fname = os.path.join( self.config_dname,
|
||
|
"settings.ini" if sys.platform == "win32" else "settings.conf"
|
||
|
)
|
||
|
|
||
|
# configure the location of the user's local data files
|
||
|
self.local_data_dname = "/tmp" if is_container \
|
||
|
else self._check_dir( appdirs.user_data_dir( _APP_NAME, _APP_AUTHOR, roaming=False ) )
|
||
|
self.flask_lock_fname = os.path.join( self.local_data_dname, "flask.lock" )
|
||
|
|
||
|
# configure the location of the log files
|
||
|
self.logs_dname = "/tmp" if is_container \
|
||
|
else self._check_dir( appdirs.user_log_dir( _APP_NAME, _APP_AUTHOR ) )
|
||
|
self.webdriver_log_fname = app_config.get( "WEBDRIVER_LOG",
|
||
|
os.path.join( self.logs_dname, "webdriver.log" )
|
||
|
)
|
||
|
|
||
|
# configure the location of the cached data files
|
||
|
self.cache_dname = "/tmp" if is_container \
|
||
|
else self._check_dir( appdirs.user_cache_dir( _APP_NAME, _APP_AUTHOR ) )
|
||
|
self.downloaded_files = {
|
||
|
"ASA": os.path.join( self.cache_dname, "asl-scenario-archive.json" ),
|
||
|
"ROAR": os.path.join( self.cache_dname, "roar-scenario-index.json" ),
|
||
|
}
|
||
|
self.vo_notes_image_cache_dname = self._check_dir( os.path.join( self.cache_dname, "vo-notes-image-cache" ) )
|
||
|
|
||
|
# log our settings
|
||
|
_logger.info( "UserProfile:" )
|
||
|
if is_desktop_app:
|
||
|
_logger.info( "- config = %s", self.config_dname )
|
||
|
_logger.debug( " - settings = %s", self.desktop_settings_fname )
|
||
|
_logger.info( "- local data = %s", self.local_data_dname )
|
||
|
_logger.debug( " - Flask lock file = %s", self.flask_lock_fname )
|
||
|
_logger.info( "- logs = %s", self.logs_dname )
|
||
|
_logger.debug( " - webdriver = %s", self.webdriver_log_fname )
|
||
|
_logger.info( "- cache = %s", self.cache_dname )
|
||
|
for key, val in self.downloaded_files.items():
|
||
|
_logger.debug( " - Downloaded file (%s) = %s", key, val )
|
||
|
_logger.debug( " - V/O note image cache = %s", self.vo_notes_image_cache_dname )
|
||
|
|
||
|
# fixup any legacy files
|
||
|
if not is_container:
|
||
|
self._fixup_legacy()
|
||
|
|
||
|
def _fixup_legacy( self ):
|
||
|
"""Fixup any legacy files and directories.
|
||
|
|
||
|
NOTE: Config and data files were moved to the standard locations in v1.10.beta3; this function
|
||
|
looks for them in the legacy locations and moves them to their new location.
|
||
|
"""
|
||
|
|
||
|
def move_file( caption, src_fname, dest_fname ):
|
||
|
if not os.path.isfile( src_fname ):
|
||
|
_logger.debug( "Legacy %s file not found: %s", caption, src_fname )
|
||
|
return
|
||
|
_logger.info( "Moving legacy %s file:\n- from: %s\n- to: %s",
|
||
|
caption, src_fname, dest_fname
|
||
|
)
|
||
|
try:
|
||
|
shutil.move( src_fname, dest_fname )
|
||
|
except Exception as ex: #pylint: disable=broad-except
|
||
|
# NOTE: It would be nice to report this as a startup error, but this happens
|
||
|
# so early in the startup process, nothing has been initialized yet :-/
|
||
|
logging.error( "Can't move legacy %s file: %s\n- %s", caption, src_fname, ex )
|
||
|
# NOTE: We try to keep going.
|
||
|
|
||
|
def remove_dir( caption, dname ):
|
||
|
if not os.path.isdir( dname ):
|
||
|
_logger.debug( "Legacy %s directory not found: %s", caption, dname )
|
||
|
return
|
||
|
_logger.info( "Deleting legacy %s directory: %s", caption, dname )
|
||
|
try:
|
||
|
shutil.rmtree( dname )
|
||
|
except Exception as ex: #pylint: disable=broad-except
|
||
|
logging.error( "Can't delete legacy %s directory: %s\n- %s", caption, dname, ex )
|
||
|
# NOTE: We try to keep going.
|
||
|
|
||
|
# fixup the desktop settings file
|
||
|
qdir_home_path = os.environ.get( "QDIR_HOME_PATH" )
|
||
|
if qdir_home_path:
|
||
|
fname = os.path.join( qdir_home_path,
|
||
|
"vasl-templates.ini" if sys.platform == "win32" else ".vasl-templates.conf"
|
||
|
)
|
||
|
move_file( "desktop settings", fname, self.desktop_settings_fname )
|
||
|
|
||
|
# fixup the ASA/ROAR downloaded files
|
||
|
# NOTE: We don't *need* to do this (since the files will just be downloaded again), and they're
|
||
|
# in the temp directory (so we don't *need* to remove them), but it'd be nice to have scenario search
|
||
|
# working straight away after startup.
|
||
|
move_file( "ASA scenarios",
|
||
|
os.path.join( tempfile.gettempdir(), "vasl-templates.asl-scenario-archive.json" ),
|
||
|
self.downloaded_files[ "ASA" ]
|
||
|
)
|
||
|
move_file( "ROAR scenarios",
|
||
|
os.path.join( tempfile.gettempdir(), "vasl-templates.roar-scenario-index.json" ),
|
||
|
self.downloaded_files[ "ROAR" ]
|
||
|
)
|
||
|
|
||
|
# NOTE: The Flask lock file and webdriver log file are temp files, so we don't move them.
|
||
|
|
||
|
# NOTE: The V/O notes image cache can either be:
|
||
|
# - disabled
|
||
|
# - manually configured (via VO_NOTES_IMAGE_CACHE_DIR)
|
||
|
# - default ($TEMP-DIR/vasl-templates/vo-notes-image-cache/)
|
||
|
# In the first 2 cases, we don't need to do anything, in the last case, we delete our temp directory.
|
||
|
# Note that while we could try to move it, it may well not be on the same file system (which makes it
|
||
|
# a non-trivial operation), and there have been CSS changes in the v1.10 release cycle, which normally
|
||
|
# won't cause an image to be re-generated, so it's not a bad idea to force this to happen.
|
||
|
remove_dir( "app temp",
|
||
|
os.path.join( tempfile.gettempdir(), "vasl-templates" )
|
||
|
)
|
||
|
|
||
|
@staticmethod
|
||
|
def _check_dir( dname ):
|
||
|
"""Check that a directory exists."""
|
||
|
try:
|
||
|
if not os.path.isdir( dname ):
|
||
|
os.makedirs( dname )
|
||
|
except Exception as ex: #pylint: disable=broad-except
|
||
|
logging.error( "Can't create UserProfile directory: %s\n- %s", dname, ex )
|
||
|
raise
|
||
|
if dname[-1] != os.sep:
|
||
|
dname += os.sep
|
||
|
return dname
|