Changed how startup initialization is done.

master
Pacman Ghost 5 years ago
parent 31d2dcece1
commit 3a39a4e57c
  1. 3
      vasl_templates/server_settings.py
  2. 42
      vasl_templates/webapp/__init__.py
  3. 13
      vasl_templates/webapp/files.py
  4. 21
      vasl_templates/webapp/globvars.py
  5. 17
      vasl_templates/webapp/tests/remote.py
  6. 3
      vasl_templates/webapp/tests/test_vasl_extensions.py
  7. 45
      vasl_templates/webapp/tests/test_vassal.py
  8. 51
      vasl_templates/webapp/vasl_mod.py
  9. 7
      vasl_templates/webapp/vassal.py
  10. 41
      vasl_templates/webapp/vo.py
  11. 68
      vasl_templates/webapp/vo_notes.py
  12. 4
      vasl_templates/webapp/webdriver.py

@ -260,8 +260,7 @@ def install_server_settings( is_startup ):
# initialize
if is_startup:
# nb: we let the web page show startup messages
msg_store = None
msg_store = None # nb: we let the web page show startup messages
else:
msg_store = MsgStore()

@ -10,7 +10,27 @@ import logging.config
from flask import Flask
import yaml
from vasl_templates.webapp.config.constants import APP_NAME, APP_VERSION, BASE_DIR
from vasl_templates.webapp.config.constants import BASE_DIR
# ---------------------------------------------------------------------
def _on_startup():
"""Do startup initialization."""
# configure the VASL module
fname = app.config.get( "VASL_MOD" )
if fname:
from vasl_templates.webapp.vasl_mod import set_vasl_mod #pylint: disable=cyclic-import
from vasl_templates.webapp.main import startup_msg_store #pylint: disable=cyclic-import
set_vasl_mod( fname, startup_msg_store )
# load the vehicle/ordnance listings
from vasl_templates.webapp.vo import load_vo_listings #pylint: disable=cyclic-import
load_vo_listings()
# load the vehicle/ordnance notes
from vasl_templates.webapp.vo_notes import load_vo_notes #pylint: disable=cyclic-import
load_vo_notes()
# ---------------------------------------------------------------------
@ -29,11 +49,10 @@ def load_debug_config( fname ):
# ---------------------------------------------------------------------
cleanup_handlers = []
def on_sigint( signum, stack ): #pylint: disable=unused-argument
def _on_sigint( signum, stack ): #pylint: disable=unused-argument
"""Clean up after a SIGINT."""
for handler in cleanup_handlers:
from vasl_templates.webapp import globvars #pylint: disable=cyclic-import
for handler in globvars.cleanup_handlers:
handler()
raise SystemExit()
@ -77,14 +96,7 @@ if app.config.get( "ENABLE_REMOTE_TEST_CONTROL" ):
import vasl_templates.webapp.testing #pylint: disable=cyclic-import
# install our signal handler (must be done in the main thread)
signal.signal( signal.SIGINT, on_sigint )
# ---------------------------------------------------------------------
signal.signal( signal.SIGINT, _on_sigint )
@app.context_processor
def inject_template_params():
"""Inject template parameters into Jinja2."""
return {
"APP_NAME": APP_NAME,
"APP_VERSION": APP_VERSION,
}
# register startup initialization
app.before_first_request( _on_startup )

@ -8,8 +8,7 @@ import mimetypes
from flask import send_file, send_from_directory, jsonify, redirect, url_for, abort
from vasl_templates.webapp import app
from vasl_templates.webapp.vasl_mod import get_vasl_mod
from vasl_templates.webapp import app, globvars
from vasl_templates.webapp.utils import resize_image_response, is_empty_file
# ---------------------------------------------------------------------
@ -74,12 +73,11 @@ def get_counter_image( gpid, side, index ):
"""Get a counter image."""
# check if a VASL module has been configured
vasl_mod = get_vasl_mod()
if not vasl_mod:
if not globvars.vasl_mod:
return redirect( url_for( "static", filename="images/missing-image.png" ), code=302 )
# return the specified counter image
image_path, image_data = vasl_mod.get_piece_image( gpid, side, int(index) )
image_path, image_data = globvars.vasl_mod.get_piece_image( gpid, side, int(index) )
if not image_data:
abort( 404 )
return send_file(
@ -94,9 +92,8 @@ def get_vasl_piece_info():
"""Get information about the VASL pieces."""
# check if a VASL module has been configured
vasl_mod = get_vasl_mod()
if not vasl_mod:
if not globvars.vasl_mod:
return jsonify( {} )
# return the VASL piece info
return jsonify( vasl_mod.get_piece_info() )
return jsonify( globvars.vasl_mod.get_piece_info() )

@ -0,0 +1,21 @@
""" Global variables. """
from vasl_templates.webapp import app
from vasl_templates.webapp.config.constants import APP_NAME, APP_VERSION
vasl_mod = None
vo_listings = None
vo_notes = None
vo_notes_file_server = None
cleanup_handlers = []
# ---------------------------------------------------------------------
@app.context_processor
def inject_template_params():
"""Inject template parameters into Jinja2."""
return {
"APP_NAME": APP_NAME,
"APP_VERSION": APP_VERSION,
}

@ -17,12 +17,11 @@ import random
import pytest
from vasl_templates.webapp import app
from vasl_templates.webapp import app, globvars
from vasl_templates.webapp.config.constants import DATA_DIR
from vasl_templates.webapp.vasl_mod import set_vasl_mod
from vasl_templates.webapp import main as webapp_main
from vasl_templates.webapp import snippets as webapp_snippets
from vasl_templates.webapp import vo_notes as webapp_vo_notes
from vasl_templates.webapp.vasl_mod import set_vasl_mod
from vasl_templates.webapp import vasl_mod as vasl_mod_module
_logger = logging.getLogger( "control_tests" )
@ -89,6 +88,8 @@ class ControlTests:
raise RuntimeError( "Unknown data dir type: {}".format( dtype ) )
_logger.info( "Setting data dir: %s", dname )
self.webapp.config[ "DATA_DIR" ] = dname
from vasl_templates.webapp.vo import load_vo_listings
load_vo_listings()
return self
def _set_default_scenario( self, fname=None ):
@ -175,13 +176,14 @@ class ControlTests:
startup_msg_store.reset()
vasl_mod_module.warnings = []
set_vasl_mod( vmod, startup_msg_store )
from vasl_templates.webapp.vo import load_vo_listings
load_vo_listings()
return self
def _get_vasl_extns( self ): #pylint: disable=no-self-use
"""Return the loaded VASL extensions."""
from vasl_templates.webapp.vasl_mod import get_vasl_mod
extns = get_vasl_mod().get_extns()
extns = globvars.vasl_mod.get_extns()
_logger.debug( "Returning VASL extensions:\n%s",
"\n".join( "- {}".format( e ) for e in extns )
)
@ -251,9 +253,8 @@ class ControlTests:
dname = None
_logger.info( "Setting vehicle/ordnance notes: %s", 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
from vasl_templates.webapp.vo_notes import load_vo_notes
load_vo_notes()
return self
def _set_user_files_dir( self, dtype=None ):

@ -30,7 +30,6 @@ def test_load_vasl_extensions( webapp, webdriver ):
# reload the webapp
control_tests.set_vasl_mod( vmod="random", extns_dtype="test" )
webdriver.refresh()
_check_warning_msgs( control_tests, expected )
# try loading an extension that has no buildFile
@ -52,7 +51,6 @@ def test_load_vasl_extensions( webapp, webdriver ):
# try loading something that's not a ZIP file
control_tests.set_test_vasl_extn( fname="test.zip", bin_data=b"This is not a ZIP file." ) \
.set_vasl_mod( vmod="random", extns_dtype="test" )
webdriver.refresh()
_check_warning_msgs( control_tests, "Can't check VASL extension (not a ZIP file):" )
# ---------------------------------------------------------------------
@ -70,7 +68,6 @@ def test_vasl_extension_info( webapp, webdriver ):
def do_test( dtype, expected ): #pylint: disable=missing-docstring
control_tests.set_vasl_extn_info_dir( dtype=dtype ) \
.set_vasl_mod( vmod="random", extns_dtype="test" )
webdriver.refresh()
_check_warning_msgs( control_tests, expected )
# try loading the VASL extension, with no matching extension info

@ -11,6 +11,7 @@ import pytest
from vasl_templates.webapp.vassal import VassalShim
from vasl_templates.webapp.utils import TempFile, change_extn
from vasl_templates.webapp import globvars
from vasl_templates.webapp.tests.utils import \
init_webapp, select_menu_option, get_stored_msg, set_stored_msg, set_stored_msg_marker, wait_for
from vasl_templates.webapp.tests.test_scenario_persistence import load_scenario, load_scenario_params, \
@ -18,6 +19,13 @@ from vasl_templates.webapp.tests.test_scenario_persistence import load_scenario,
# ---------------------------------------------------------------------
class DummyVaslMod:
"""Dummy VaslMod class that lets us run the VASSAL shim locally (to dump scenarios)."""
def __init__( self, fname ):
self.filename = fname
# ---------------------------------------------------------------------
@pytest.mark.skipif( not pytest.config.option.vasl_mods, reason="--vasl-mods not specified" ) #pylint: disable=no-member
@pytest.mark.skipif( not pytest.config.option.vassal, reason="--vassal not specified" ) #pylint: disable=no-member
@pytest.mark.skipif( pytest.config.option.short_tests, reason="--short-tests specified" ) #pylint: disable=no-member
@ -97,8 +105,7 @@ def test_full_update( webapp, webdriver ):
# NOTE: We could arguably only do this once, but updating scenarios is the key functionality of the VASSAL shim,
# and so it's worth checking that every VASSAL+VASL combination understands its input correctly.
fname = os.path.join( os.path.split(__file__)[0], "fixtures/update-vsav/full.vsav" )
vassal_shim = VassalShim()
vsav_dump = vassal_shim.dump_scenario( fname )
vsav_dump = _dump_vsav( fname )
_check_vsav_dump( vsav_dump, {
"scenario": "Somewhere",
"players": re.compile( r"American:.*Belgian:" ),
@ -123,7 +130,7 @@ def test_full_update( webapp, webdriver ):
# check the results
temp_file.write( updated_vsav_data )
temp_file.close()
updated_vsav_dump = vassal_shim.dump_scenario( temp_file.name )
updated_vsav_dump = _dump_vsav( temp_file.name )
expected = {
"scenario": "Modified scenario name (<>{}\"'\\)",
"players": re.compile( r"Russian:.*German:" ),
@ -190,8 +197,7 @@ def test_latw_autocreate( webapp, webdriver ):
# check the VASL scenario
fname = os.path.join( os.path.split(__file__)[0], "fixtures/update-vsav/empty.vsav" )
vassal_shim = VassalShim()
vsav_dump = vassal_shim.dump_scenario( fname )
vsav_dump = _dump_vsav( fname )
_check_vsav_dump( vsav_dump, {}, ignore_labels )
# update the scenario (German/Russian, no date)
@ -261,8 +267,7 @@ def test_latw_update( webapp, webdriver ):
# check the VASL scenario
fname = os.path.join( os.path.split(__file__)[0], "fixtures/update-vsav/latw.vsav" )
vassal_shim = VassalShim()
vsav_dump = vassal_shim.dump_scenario( fname )
vsav_dump = _dump_vsav( fname )
_check_vsav_dump( vsav_dump, {
"psk": "Panzerschrek", "atmm": "ATMM check:", # nb: the PF label has no snippet ID
"mol-p": "TH#", # nb: the MOL label has no snippet ID
@ -311,8 +316,7 @@ def test_dump_vsav( webapp, webdriver ):
# dump the VASL scenario
fname = os.path.join( os.path.split(__file__)[0], "fixtures/dump-vsav/labels.vsav" )
vassal_shim = VassalShim()
vsav_dump = vassal_shim.dump_scenario( fname )
vsav_dump = _dump_vsav( fname )
# check the result
fname = change_extn( fname, ".txt" )
@ -344,8 +348,7 @@ def test_legacy_labels( webapp, webdriver ):
# dump the VASL scenario
# NOTE: We implemented snippet ID's in v0.5, this scenario is the "Hill 621" example from v0.4.
fname = os.path.join( os.path.split(__file__)[0], "fixtures/update-vsav/hill621-legacy.vsav" )
vassal_shim = VassalShim()
vsav_dump = vassal_shim.dump_scenario( fname )
vsav_dump = _dump_vsav( fname )
labels = _get_vsav_labels( vsav_dump )
assert len( [ lbl for lbl in labels if "vasl-templates:id" not in lbl ] ) == 20
assert len( [ lbl for lbl in labels if "vasl-templates:id" in lbl ] ) == 0 #pylint: disable=len-as-condition
@ -426,8 +429,7 @@ def test_legacy_latw_labels( webapp, webdriver ):
# dump the VASL scenario
# NOTE: This scenario contains LATW labels created using v0.4 i.e. they have no snippet ID's.
fname = os.path.join( os.path.split(__file__)[0], "fixtures/update-vsav/latw-legacy.vsav" )
vassal_shim = VassalShim()
vsav_dump = vassal_shim.dump_scenario( fname )
vsav_dump = _dump_vsav( fname )
labels = _get_vsav_labels( vsav_dump )
assert len( [ lbl for lbl in labels if "vasl-templates:id" not in lbl ] ) == 8
assert len( [ lbl for lbl in labels if "vasl-templates:id" in lbl ] ) == 0 #pylint: disable=len-as-condition
@ -505,6 +507,13 @@ def _run_tests( control_tests, func, test_all ):
vasl_mods = [ random.choice( vasl_mods ) ]
vassal_engines = [ random.choice( vassal_engines ) ]
# FUDGE! If we are running the tests against a remote server, we still need to be able to run
# the VASSAL shim locally (to dump VASSAL save files), so we need to set up things up enough
# for this to work.
if control_tests.server_url:
vasl_mods_local = control_tests._do_get_vasl_mods() #pylint: disable=protected-access
globvars.vasl_mod = DummyVaslMod( random.choice( vasl_mods_local ) )
# run the test for each VASSAL+VASL
for vassal_engine in vassal_engines:
control_tests.set_vassal_engine( vengine=vassal_engine )
@ -559,12 +568,16 @@ def _update_vsav_and_dump( fname, expected ):
with TempFile() as temp_file:
temp_file.write( updated_vsav_data )
temp_file.close()
vassal_shim = VassalShim()
updated_vsav_dump = vassal_shim.dump_scenario( temp_file.name )
return updated_vsav_dump
return _dump_vsav( temp_file.name )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def _dump_vsav( fname ):
"""Dump a VASL scenario file."""
# NOTE: This is run locally, even if we're running the tests against a remote server.
vassal_shim = VassalShim()
return vassal_shim.dump_scenario( fname )
def _check_vsav_dump( vsav_dump, expected, ignore=None ):
""""Check that a VASL scenario dump contains what we expect."""

@ -1,7 +1,6 @@
""" Wrapper around a VASL module file and extensions. """
import os
import threading
import json
import glob
import zipfile
@ -11,7 +10,7 @@ import xml.etree.ElementTree
import logging
_logger = logging.getLogger( "vasl_mod" )
from vasl_templates.webapp import app
from vasl_templates.webapp import app, globvars
from vasl_templates.webapp.config.constants import DATA_DIR
SUPPORTED_VASL_MOD_VERSIONS = [ "6.4.0", "6.4.1", "6.4.2", "6.4.3" ]
@ -21,48 +20,24 @@ warnings = [] # nb: for the test suite
# ---------------------------------------------------------------------
# NOTE: The lock only controls access to the _vasl_mod variable, not the VaslMod object it points to.
# In practice this doesn't really matter, since it will be loaded once at startup, then never changes;
# it's only the tests that are constantly changing the underlying object.
_vasl_mod_lock = threading.RLock()
_vasl_mod = None
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def get_vasl_mod():
"""Return the global VaslMod object."""
with _vasl_mod_lock:
global _vasl_mod
if _vasl_mod is None:
# check if a VASL module has been configured
# NOTE: We will be doing this check every time someone wants the global VaslMod object,
# even if one hasn't been configured, but in all likelihood, everyone will have it configured,
# in which case, the check will only be done once, and the global _vasl_mod variable set.
fname = app.config.get( "VASL_MOD" )
if fname:
# yup - load it
from vasl_templates.webapp.main import startup_msg_store #pylint: disable=cyclic-import
set_vasl_mod( fname, startup_msg_store )
return _vasl_mod
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def set_vasl_mod( vmod_fname, msg_store ):
"""Install a new global VaslMod object."""
with _vasl_mod_lock:
global _vasl_mod
if vmod_fname:
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:
if vmod_fname:
# load and install the specified VASL module
extns_dir = app.config.get( "VASL_EXTNS_DIR" )
extns = _load_vasl_extns( extns_dir )
globvars.vasl_mod = VaslMod( vmod_fname, DATA_DIR, extns )
# make sure the VASL version is one we support
if globvars.vasl_mod.vasl_version not in SUPPORTED_VASL_MOD_VERSIONS:
if msg_store:
msg_store.warning(
"VASL {} is unsupported.<p>Things might work, but they might not...".format(
_vasl_mod.vasl_version
globvars.vasl_mod.vasl_version
)
)
else:
_vasl_mod = None
else:
# no VASL module has been specified
globvars.vasl_mod = None
def _load_vasl_extns( extn_dir ): #pylint: disable=too-many-locals,too-many-statements,too-many-branches
"""Locate VASL extensions and their corresponding vehicle/ordnance info files."""

@ -14,9 +14,8 @@ import xml.etree.cElementTree as ET
from flask import request
from vasl_templates.webapp import app
from vasl_templates.webapp import app, globvars
from vasl_templates.webapp.config.constants import BASE_DIR, IS_FROZEN
from vasl_templates.webapp.vasl_mod import get_vasl_mod
from vasl_templates.webapp.utils import TempFile, SimpleError
from vasl_templates.webapp.webdriver import WebDriver
@ -257,7 +256,7 @@ class VassalShim:
raise SimpleError( "Can't find the VASL boards: {}".format( self.boards_dir ) )
# locate the VASL module
if not get_vasl_mod():
if not globvars.vasl_mod:
raise SimpleError( "The VASL module has not been configured." )
return self._run_vassal_shim(
@ -284,7 +283,7 @@ class VassalShim:
args[0]
]
if args[0] in ("dump","update"):
args2.append( get_vasl_mod().filename )
args2.append( globvars.vasl_mod.filename )
args2.extend( args[1:] )
# figure out how long to the let the VASSAL shim run

@ -6,35 +6,53 @@ import logging
from flask import request, render_template, jsonify, abort
from vasl_templates.webapp import app
from vasl_templates.webapp import app, globvars
from vasl_templates.webapp.config.constants import DATA_DIR
from vasl_templates.webapp.vasl_mod import get_vasl_mod
# ---------------------------------------------------------------------
@app.route( "/vehicles" )
def get_vehicle_listings():
"""Return the vehicle listings."""
return _do_get_listings( "vehicles" )
return jsonify( _do_get_listings( "vehicles" ) )
@app.route( "/ordnance" )
def get_ordnance_listings():
"""Return the ordnance listings."""
return _do_get_listings( "ordnance" )
return jsonify( _do_get_listings( "ordnance" ) )
def _do_get_listings( vo_type ):
"""Return the vehicle/ordnance listings."""
if request.args.get("merge_common") == "1" and request.args.get("report") != "1":
# nb: this is the normal case
return globvars.vo_listings[ vo_type ]
else:
# nb: we should only get here during tests
return _do_load_vo_listings(
vo_type,
request.args.get("merge_common") == "1", request.args.get("report") == "1"
)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def _do_get_listings( vo_type ): #pylint: disable=too-many-locals,too-many-branches
def load_vo_listings():
"""Load the vehicle/ordnance listings."""
globvars.vo_listings = {
"vehicles": _do_load_vo_listings( "vehicles", True, False ),
"ordnance": _do_load_vo_listings( "ordnance", True, False )
}
def _do_load_vo_listings( vo_type, merge_common, report ): #pylint: disable=too-many-locals,too-many-branches
"""Load the vehicle/ordnance listings."""
# locate the data directory
if request.args.get( "report" ):
if report:
dname = DATA_DIR # nb: always use the real data for reports, not the test fixtures
else:
dname = app.config.get( "DATA_DIR", DATA_DIR )
dname = os.path.join( dname, vo_type )
if not os.path.isdir( dname ):
abort( 404 )
raise RuntimeError( "Missing vehicles/ordnance directory: {}".format( dname ) )
# load the listings
listings = {}
@ -54,7 +72,7 @@ def _do_get_listings( vo_type ): #pylint: disable=too-many-locals,too-many-branc
listings[nat] = json.load( fp )
# merge common entries
if request.args.get( "merge_common" ) == "1":
if merge_common:
# merge common Allied/Axis Minor vehicles/ordnance
for minor_type in ("allied-minor","axis-minor"):
if minor_type+"-common" not in listings:
@ -74,15 +92,14 @@ def _do_get_listings( vo_type ): #pylint: disable=too-many-locals,too-many-branc
# apply any changes for VASL extensions
# NOTE: We do this here, rather than in VaslMod, because VaslMod is a wrapper around a VASL module, and so
# only knows about GPID's and counter images, rather than Chapter H pieces and piece ID's (e.g. "ge/v:001").
vasl_mod = get_vasl_mod()
if vasl_mod:
if globvars.vasl_mod:
# build an index of the pieces
piece_index = {}
for nat,pieces in listings.items():
for piece in pieces:
piece_index[ piece["id"] ] = piece
# process each VASL extension
for extn in vasl_mod.get_extns():
for extn in globvars.vasl_mod.get_extns():
_apply_extn_info( listings, extn[0], extn[1], piece_index, vo_type )
# update nationality variants with the listings from their base nationality
@ -92,7 +109,7 @@ def _do_get_listings( vo_type ): #pylint: disable=too-many-locals,too-many-branc
base_nat = nat.split( "~" )[0]
listings[nat] = listings[base_nat] + listings[nat]
return jsonify( listings )
return listings
def _apply_extn_info( listings, extn_fname, extn_info, piece_index, vo_type ):
"""Update the vehicle/ordnance listings for the specified VASL extension."""

@ -2,62 +2,47 @@
# Pokhara, Nepal (DEC/18).
import os
import threading
import logging
from collections import defaultdict
from flask import render_template, jsonify, abort
from vasl_templates.webapp import app
from vasl_templates.webapp.vasl_mod import get_vasl_mod
from vasl_templates.webapp import app, globvars
from vasl_templates.webapp.files import FileServer
from vasl_templates.webapp.utils import resize_image_response, is_image_file, is_empty_file
_vo_notes_lock = threading.RLock() # nb: this controls the cached V/O notes and the FileServer
_cached_vo_notes = None
_vo_notes_file_server = None
# ---------------------------------------------------------------------
@app.route( "/vehicles/notes" )
def get_vehicle_notes():
"""Return the Chapter H vehicle notes."""
vo_notes = _do_get_vo_notes( "vehicles" )
return jsonify( vo_notes )
return jsonify( globvars.vo_notes[ "vehicles" ] )
@app.route( "/ordnance/notes" )
def get_ordnance_notes():
"""Return the Chapter H ordnance notes."""
vo_notes = _do_get_vo_notes( "ordnance" )
return jsonify( vo_notes )
return jsonify( globvars.vo_notes[ "ordnance" ] )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def _do_get_vo_notes( vo_type ): #pylint: disable=too-many-statements,too-many-locals,too-many-branches
"""Load the Chapter H notes."""
# check if we already have the vehicle/ordnance notes
with _vo_notes_lock:
global _cached_vo_notes
if _cached_vo_notes:
return _cached_vo_notes[ vo_type ]
def load_vo_notes(): #pylint: disable=too-many-statements,too-many-locals,too-many-branches
"""Load the Chapter H vehicle/ordnance notes."""
# locate the data directory
dname = app.config.get( "CHAPTER_H_NOTES_DIR" )
if not dname:
return {}
globvars.vo_notes = { "vehicles": {}, "ordnance": {} }
globvars.file_server = None
return
dname = os.path.abspath( dname )
if not os.path.isdir( dname ):
abort( 404 )
with _vo_notes_lock:
global _vo_notes_file_server
_vo_notes_file_server = FileServer( dname )
raise RuntimeError( "Missing Chapter H directory: {}".format( dname ) )
file_server = FileServer( dname )
# generate a list of extension ID's
extn_ids = {}
vasl_mod = get_vasl_mod()
if vasl_mod:
extns = vasl_mod.get_extns()
if globvars.vasl_mod:
extns = globvars.vasl_mod.get_extns()
extn_ids = set( e[1]["extensionId"] for e in extns )
def get_ma_note_key( nat, fname ):
@ -144,11 +129,9 @@ def _do_get_vo_notes( vo_type ): #pylint: disable=too-many-statements,too-many-l
if "chinese" in vo_notes[vo_type2]:
vo_notes[vo_type2]["chinese~gmd"] = vo_notes[vo_type2]["chinese"]
with _vo_notes_lock:
# install the new vehicle/ordnance notes
_cached_vo_notes = { k: dict(v) for k,v in vo_notes.items() }
return _cached_vo_notes[ vo_type ]
# install the vehicle/ordnance notes
globvars.vo_notes = { k: dict(v) for k,v in vo_notes.items() }
globvars.file_server = file_server
# ---------------------------------------------------------------------
@ -157,18 +140,15 @@ def get_vo_note( vo_type, nat, key ):
"""Return a Chapter H vehicle/ordnance note."""
# locate the file
with _vo_notes_lock:
# NOTE: We assume that the client has already loaded the vehicle/ordnance notes.
if not _vo_notes_file_server:
abort( 404 )
vo_notes = _do_get_vo_notes( vo_type )
fname = vo_notes.get( nat, {} ).get( key )
if not fname:
abort( 404 )
# nb: we ignore placeholder files (return 404 for empty files)
resp = _vo_notes_file_server.serve_file( fname, ignore_empty=True )
if not resp:
abort( 404 )
vo_notes = globvars.vo_notes[ vo_type ]
fname = vo_notes.get( nat, {} ).get( key )
if not fname:
abort( 404 )
if not globvars.file_server:
abort( 404 )
resp = globvars.file_server.serve_file( fname, ignore_empty=True )
if not resp:
abort( 404 )
default_scaling = app.config.get( "CHAPTER_H_IMAGE_SCALING", 100 )
return resize_image_response( resp, default_scaling=default_scaling )

@ -9,7 +9,7 @@ import logging
from PIL import Image, ImageChops
from selenium import webdriver
from vasl_templates.webapp import app, cleanup_handlers
from vasl_templates.webapp import app, globvars
from vasl_templates.webapp.utils import TempFile, SimpleError
_logger = logging.getLogger( "webdriver" )
@ -200,7 +200,7 @@ class WebDriver:
_logger.info( "Cleaning up shared WebDriver: %x", id(wdriver) )
wdriver._do_stop() #pylint: disable=protected-access
atexit.register( cleanup )
cleanup_handlers.append( cleanup )
globvars.cleanup_handlers.append( cleanup )
return wdriver

Loading…
Cancel
Save