diff --git a/docker/config/debug.cfg b/docker/config/debug.cfg index 42791a0..ff6ef35 100644 --- a/docker/config/debug.cfg +++ b/docker/config/debug.cfg @@ -1,4 +1,4 @@ [Debug] TEST_VASL_MODS = /test-data/vasl-vmods/ -TEST_VASL_EXTENSIONS_DIR = /test-data/vasl-extensions/ +TEST_VASL_EXTNS_DIR = /test-data/vasl-extensions/ diff --git a/docker/config/site.cfg b/docker/config/site.cfg index c01c6b7..b62c978 100644 --- a/docker/config/site.cfg +++ b/docker/config/site.cfg @@ -3,5 +3,5 @@ FLASK_HOST = 0.0.0.0 VASL_MOD = /data/vasl.vmod -VASL_EXTENSIONS = /data/vasl-extensions/ -CHAPTER_H_NOTES = /data/chapter-h-notes/ +VASL_EXTNS_DIR = /data/vasl-extensions/ +CHAPTER_H_NOTES_DIR = /data/chapter-h-notes/ diff --git a/vasl_templates/server_settings.py b/vasl_templates/server_settings.py index 1b9302a..9274277 100644 --- a/vasl_templates/server_settings.py +++ b/vasl_templates/server_settings.py @@ -3,7 +3,7 @@ import os from PyQt5 import uic -from PyQt5.QtWidgets import QDialog, QFileDialog +from PyQt5.QtWidgets import QDialog, QFileDialog, QGroupBox from PyQt5.QtGui import QIcon from vasl_templates.main import app_settings @@ -27,21 +27,36 @@ class ServerSettingsDialog( QDialog ): base_dir = os.path.split( __file__ )[0] dname = os.path.join( base_dir, "ui/server_settings.ui" ) uic.loadUi( dname, self ) - for btn in ["vassal_dir","vasl_mod","boards_dir","java","webdriver"]: + for btn in ["vassal_dir", "vasl_mod", "vasl_extns_dir", "boards_dir", + "java", "webdriver", + "chapter_h_notes_dir", "user_files_dir" + ]: getattr( self, "select_{}_button".format(btn) ).setIcon( QIcon( os.path.join( base_dir, "resources/file_browser.png" ) ) ) - self.setMinimumSize( self.size() ) + self.setFixedSize( self.size() ) + + # initialize the UI + for attr in dir(self): + attr = getattr( self, attr ) + if isinstance( attr, QGroupBox ): + attr.setStyleSheet("QGroupBox { font-weight: bold; } ") # initialize handlers self.select_vassal_dir_button.clicked.connect( self.on_select_vassal_dir ) self.select_vasl_mod_button.clicked.connect( self.on_select_vasl_mod ) + self.select_vasl_extns_dir_button.clicked.connect( self.on_select_vasl_extns_dir ) self.select_boards_dir_button.clicked.connect( self.on_select_boards_dir ) self.select_java_button.clicked.connect( self.on_select_java ) self.select_webdriver_button.clicked.connect( self.on_select_webdriver ) + self.select_chapter_h_notes_dir_button.clicked.connect( self.on_select_chapter_h_notes_dir ) + self.select_user_files_dir_button.clicked.connect( self.on_select_user_files_dir ) self.ok_button.clicked.connect( self.on_ok ) self.cancel_button.clicked.connect( self.on_cancel ) + # initialize handlers + self.chapter_h_notes_dir.textChanged.connect( self.on_chapter_h_notes_dir_changed ) + # load the current server settings self.vassal_dir.setText( app_settings.value( "ServerSettings/vassal-dir" ) ) self.vassal_dir.setToolTip( @@ -51,10 +66,16 @@ class ServerSettingsDialog( QDialog ): self.vasl_mod.setToolTip( "Supported versions: {}".format( SUPPORTED_VASL_MOD_VERSIONS_DISPLAY ) ) + self.vasl_extns_dir.setText( app_settings.value( "ServerSettings/vasl-extns-dir" ) ) self.boards_dir.setText( app_settings.value( "ServerSettings/boards-dir" ) ) self.java_path.setText( app_settings.value( "ServerSettings/java-path" ) ) self.webdriver_path.setText( app_settings.value( "ServerSettings/webdriver-path" ) ) self.webdriver_path.setToolTip( "Configure either geckodriver or chromedriver here." ) + self.chapter_h_notes_dir.setText( app_settings.value( "ServerSettings/chapter-h-notes-dir" ) ) + scaling = app_settings.value( "ServerSettings/chapter-h-image-scaling" ) + if scaling: + self.chapter_h_image_scaling.setText( str( scaling ) ) + self.user_files_dir.setText( app_settings.value( "ServerSettings/user-files-dir" ) ) def on_select_vassal_dir( self ): """Let the user locate the VASSAL installation directory.""" @@ -76,6 +97,16 @@ class ServerSettingsDialog( QDialog ): if fname: self.vasl_mod.setText( fname ) + def on_select_vasl_extns_dir( self ): + """Let the user locate the VASL extensions directory.""" + dname = QFileDialog.getExistingDirectory( + self, "Select VASL extensions directory", + self.vasl_extns_dir.text(), + QFileDialog.ShowDirsOnly + ) + if dname: + self.vasl_extns_dir.setText( dname ) + def on_select_boards_dir( self ): """Let the user locate the VASL boards directory.""" dname = QFileDialog.getExistingDirectory( @@ -99,24 +130,58 @@ class ServerSettingsDialog( QDialog ): def on_select_webdriver( self ): """Let the user locate the webdriver executable.""" fname = QFileDialog.getOpenFileName( - self, "Select webdriver", + self, "Select webdriver executable", self.webdriver_path.text(), _make_exe_filter_string() )[0] if fname: self.webdriver_path.setText( fname ) + def on_select_chapter_h_notes_dir( self ): + """Let the user locate their Chapter H notes directory.""" + dname = QFileDialog.getExistingDirectory( + self, "Select Chapter H notes directory", + self.chapter_h_notes_dir.text(), + QFileDialog.ShowDirsOnly + ) + if dname: + self.chapter_h_notes_dir.setText( dname ) + + def on_select_user_files_dir( self ): + """Let the user locate their user files directory.""" + dname = QFileDialog.getExistingDirectory( + self, "Select user files directory", + self.user_files_dir.text(), + QFileDialog.ShowDirsOnly + ) + if dname: + self.user_files_dir.setText( dname ) + def on_ok( self ): """Accept the new server settings.""" + # unload the dialog + try: + chapter_h_image_scaling = self.chapter_h_image_scaling.text().strip() + if chapter_h_image_scaling: + chapter_h_image_scaling = int( self.chapter_h_image_scaling.text() ) + except ValueError: + MainWindow.showErrorMsg( "Image scaling must be a numeric percentage value." ) + self.chapter_h_image_scaling.setFocus() + return + # save the new settings app_settings.setValue( "ServerSettings/vassal-dir", self.vassal_dir.text() ) fname = self.vasl_mod.text().strip() vasl_mod_changed = fname != app_settings.value( "ServerSettings/vasl-mod", "" ) app_settings.setValue( "ServerSettings/vasl-mod", fname ) + app_settings.setValue( "ServerSettings/vasl-extns-dir", self.vasl_extns_dir.text() ) app_settings.setValue( "ServerSettings/boards-dir", self.boards_dir.text() ) app_settings.setValue( "ServerSettings/java-path", self.java_path.text() ) app_settings.setValue( "ServerSettings/webdriver-path", self.webdriver_path.text() ) + app_settings.setValue( "ServerSettings/chapter-h-notes-dir", self.chapter_h_notes_dir.text() ) + app_settings.setValue( "ServerSettings/chapter-h-image-scaling", chapter_h_image_scaling ) + app_settings.setValue( "ServerSettings/user-files-dir", self.user_files_dir.text() ) # install the new settings # NOTE: We should really do this before saving the new settings, but that's more trouble @@ -138,6 +203,17 @@ class ServerSettingsDialog( QDialog ): """Cancel the dialog.""" self.close() + def update_ui( self ): + """Update the UI.""" + rc = self.chapter_h_notes_dir.text().strip() != "" + self.chapter_h_image_scaling_label.setEnabled( rc ) + self.chapter_h_image_scaling_label2.setEnabled( rc ) + self.chapter_h_image_scaling.setEnabled( rc ) + + def on_chapter_h_notes_dir_changed( self, val ): #pylint: disable=unused-argument + """Called when the Chapter H notes directory is changed.""" + self.update_ui() + def _make_exe_filter_string(): """Make a file filter string for executables.""" buf = [] @@ -153,11 +229,15 @@ def install_server_settings( is_startup ): # install the server settings from vasl_templates.webapp import app as app - app.config["VASSAL_DIR"] = app_settings.value( "ServerSettings/vassal-dir" ) - app.config["VASL_MOD"] = app_settings.value( "ServerSettings/vasl-mod" ) - app.config["BOARDS_DIR"] = app_settings.value( "ServerSettings/boards-dir" ) - app.config["JAVA_PATH"] = app_settings.value( "ServerSettings/java-path" ) - app.config["WEBDRIVER_PATH"] = app_settings.value( "ServerSettings/webdriver-path" ) + app.config[ "VASSAL_DIR" ] = app_settings.value( "ServerSettings/vassal-dir" ) + app.config[ "VASL_MOD" ] = app_settings.value( "ServerSettings/vasl-mod" ) + app.config[ "VASL_EXTNS_DIR" ] = app_settings.value( "ServerSettings/vasl-extns-dir" ) + app.config[ "BOARDS_DIR" ] = app_settings.value( "ServerSettings/boards-dir" ) + app.config[ "JAVA_PATH" ] = app_settings.value( "ServerSettings/java-path" ) + app.config[ "WEBDRIVER_PATH" ] = app_settings.value( "ServerSettings/webdriver-path" ) + app.config[ "CHAPTER_H_NOTES_DIR" ] = app_settings.value( "ServerSettings/chapter-h-notes-dir" ) + app.config[ "CHAPTER_H_IMAGE_SCALING" ] = app_settings.value( "ServerSettings/chapter-h-image-scaling" ) + app.config[ "USER_FILES_DIR" ] = app_settings.value( "ServerSettings/user-files-dir" ) # initialize if is_startup: diff --git a/vasl_templates/ui/server_settings.ui b/vasl_templates/ui/server_settings.ui index 025b9ed..8dbea45 100644 --- a/vasl_templates/ui/server_settings.ui +++ b/vasl_templates/ui/server_settings.ui @@ -9,8 +9,8 @@ 0 0 - 500 - 199 + 831 + 271 @@ -19,8 +19,142 @@ true - - + + + + 10 + 170 + 401 + 91 + + + + Support programs + + + + + 10 + 30 + 381 + 51 + + + + + 2 + + + 2 + + + + + &Java: + + + java_path + + + + + + + 2 + + + + + + + + + 0 + 0 + + + + + 22 + 22 + + + + + 22 + 22 + + + + + + + + + + + + + &Web driver: + + + webdriver_path + + + + + + + 2 + + + + + + + + + 22 + 22 + + + + + 22 + 22 + + + + + + + + + + + + + + + + 10 + 10 + 401 + 151 + + + + VASSAL/VASL + + + + + 10 + 30 + 381 + 111 + + 2 @@ -113,25 +247,25 @@ - + - VASL &boards: + VASL e&xtensions: - boards_dir + vasl_extns_dir - + 2 - + - + 0 @@ -158,25 +292,25 @@ - + - &Java: + VASL &boards: - java_path + boards_dir - + 2 - + - + 0 @@ -202,26 +336,90 @@ - - + + + + + + + 420 + 10 + 401 + 121 + + + + User data + + + + + 10 + 30 + 381 + 81 + + + + + 2 + + + 2 + + + - &Web driver: + Chapter &H notes: - webdriver_path + chapter_h_notes_dir - - - - 2 + + + + + + + + + + 22 + 22 + + + + + 22 + 22 + + + + + + + + + + + + + User &files: + + + user_files_dir + + + + - + - + 22 @@ -241,98 +439,148 @@ + + + + 2 + + + + + + 0 + 0 + + + + + DejaVu Sans + 8 + + + + Image s&caling: + + + chapter_h_image_scaling + + + + + + + + 0 + 0 + + + + + 30 + 0 + + + + + 30 + 16777215 + + + + + DejaVu Sans + 8 + + + + + + + + + + + % + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - - - - - - 0 - 0 - - - - - 0 - 30 - - - - - 16777215 - 30 - - - - - 5 + + + + + + 650 + 230 + 164 + 31 + + + + + 2 + + + + + + 0 + 0 + - - 0 + + OK - - 0 + + true - - 0 + + + + + + + 0 + 0 + - - 0 + + Cancel - - - - Qt::Horizontal - - - - 309 - 20 - - - - - - - - - 0 - 0 - - - - OK - - - true - - - - - - - - 0 - 0 - - - - Cancel - - - - - - - + + + + vassal_dir select_vassal_dir_button vasl_mod select_vasl_mod_button + vasl_extns_dir + select_vasl_extns_dir_button boards_dir select_boards_dir_button + chapter_h_notes_dir + select_chapter_h_notes_dir_button + chapter_h_image_scaling + user_files_dir + select_user_files_dir_button java_path select_java_button webdriver_path diff --git a/vasl_templates/webapp/config/site.cfg.example b/vasl_templates/webapp/config/site.cfg.example index f17cc08..a7233fb 100644 --- a/vasl_templates/webapp/config/site.cfg.example +++ b/vasl_templates/webapp/config/site.cfg.example @@ -1,12 +1,16 @@ [Site Config] -; Enable VASL counter images in the UI by configuring a VASL .vmod file here. -VASL_MOD = ...configure the VASL module (e.g. vasl-6.4.3.vmod)... - -; Configure VASSAL to be able to automatically update labels in a VASL scenario. +; configure VASSAL and VASL VASSAL_DIR = ...configure the VASSAL installation directory... +VASL_MOD = ...configure the VASL module (e.g. vasl-6.4.3.vmod)... +VASL_EXTNS_DIR = ...configured the VASL extensions directory... BOARDS_DIR = ...configure the VASL boards directory... -WEBDRIVER_PATH = ...configure either geckodriver or chromedriver here... + +; configure support prorams ; JAVA_PATH = ...configure the Java executable here (optional, must be in the PATH otherwise)... +WEBDRIVER_PATH = ...configure either geckodriver or chromedriver here... -CHAPTER_H_NOTES = ...configure your Chapter H vehicle/ordnance images and multi-applicable notes... +; configure your user data +CHAPTER_H_NOTES_DIR = ...configure your Chapter H vehicle/ordnance images and multi-applicable notes... +; CHAPTER_H_IMAGE_SCALING = ...optional scaling percentage for Chapter H images... +USER_FILES_DIR = ...configure your user files directory... diff --git a/vasl_templates/webapp/file_server/vasl_mod.py b/vasl_templates/webapp/file_server/vasl_mod.py index 2deee9f..6d0427a 100644 --- a/vasl_templates/webapp/file_server/vasl_mod.py +++ b/vasl_templates/webapp/file_server/vasl_mod.py @@ -53,7 +53,7 @@ def set_vasl_mod( vmod_fname, msg_store ): with _vasl_mod_lock: global _vasl_mod if vmod_fname: - extns_dir = app.config.get( "VASL_EXTENSIONS_DIR" ) + extns_dir = app.config.get( "VASL_EXTNS_DIR" ) extns = _load_vasl_extns( extns_dir ) _vasl_mod = VaslMod( vmod_fname, DATA_DIR, extns ) if _vasl_mod.vasl_version not in SUPPORTED_VASL_MOD_VERSIONS: diff --git a/vasl_templates/webapp/tests/remote.py b/vasl_templates/webapp/tests/remote.py index f7eca88..71f4f41 100644 --- a/vasl_templates/webapp/tests/remote.py +++ b/vasl_templates/webapp/tests/remote.py @@ -28,7 +28,7 @@ from vasl_templates.webapp.file_server import vasl_mod as vasl_mod_module _logger = logging.getLogger( "control_tests" ) -_ORIG_CHAPTER_H_NOTES = app.config.get( "CHAPTER_H_NOTES" ) +_ORIG_CHAPTER_H_NOTES_DIR = app.config.get( "CHAPTER_H_NOTES_DIR" ) # --------------------------------------------------------------------- @@ -146,16 +146,16 @@ class ControlTests: try: dname = pytest.config.option.vasl_extensions #pylint: disable=no-member except AttributeError: - dname = app.config[ "TEST_VASL_EXTENSIONS_DIR" ] + dname = app.config[ "TEST_VASL_EXTNS_DIR" ] elif extns_dtype == "test": dname = self._vasl_extns_temp_dir.name else: assert False, "Unknown extensions directory type: "+extns_dtype _logger.info( "Enabling VASL extensions: %s", dname ) - app.config[ "VASL_EXTENSIONS_DIR" ] = dname + app.config[ "VASL_EXTNS_DIR" ] = dname else: _logger.info( "Disabling VASL extensions." ) - app.config.pop( "VASL_EXTENSIONS_DIR", None ) + app.config.pop( "VASL_EXTNS_DIR", None ) # configure the VASL module if vmod: @@ -241,14 +241,14 @@ class ControlTests: def _set_vo_notes_dir( self, dtype=None ): """Set the vehicle/ordnance notes directory.""" if dtype == "real": - dname = _ORIG_CHAPTER_H_NOTES + dname = _ORIG_CHAPTER_H_NOTES_DIR elif dtype == "test": dname = os.path.join( os.path.split(__file__)[0], "fixtures/vo-notes" ) else: assert dtype is None dname = None _logger.info( "Setting vehicle/ordnance notes: %s", dname ) - app.config["CHAPTER_H_NOTES"] = dname + app.config["CHAPTER_H_NOTES_DIR"] = dname with webapp_vo_notes._vo_notes_lock: #pylint: disable=protected-access webapp_vo_notes._cached_vo_notes = None #pylint: disable=protected-access webapp_vo_notes._vo_notes_file_server = None #pylint: disable=protected-access diff --git a/vasl_templates/webapp/vo_notes.py b/vasl_templates/webapp/vo_notes.py index 4b4a894..f75e6d2 100644 --- a/vasl_templates/webapp/vo_notes.py +++ b/vasl_templates/webapp/vo_notes.py @@ -42,7 +42,7 @@ def _do_get_vo_notes( vo_type ): #pylint: disable=too-many-locals,too-many-branc return _cached_vo_notes[ vo_type ] # locate the data directory - dname = app.config.get( "CHAPTER_H_NOTES" ) + dname = app.config.get( "CHAPTER_H_NOTES_DIR" ) if not dname: return {} dname = os.path.abspath( dname ) @@ -125,7 +125,7 @@ def get_vo_note( vo_type, nat, key ): fname = vo_notes.get( nat, {} ).get( key ) resp = _vo_notes_file_server.serve_file( fname ) - default_scaling = app.config.get( "CHAPTER_H_NOTE_SCALING", 100 ) + default_scaling = app.config.get( "CHAPTER_H_IMAGE_SCALING", 100 ) return resize_image_response( resp, default_scaling=default_scaling ) # ---------------------------------------------------------------------