From 92ccfdccf91f9af32649dbd713965290371a2e47 Mon Sep 17 00:00:00 2001 From: Taka Date: Sun, 15 Nov 2020 11:34:51 +1100 Subject: [PATCH] Fixed reading template packs from a ZIP file. --- vasl_templates/webapp/snippets.py | 94 +++++++++++-------- vasl_templates/webapp/static/snippets.js | 3 +- vasl_templates/webapp/testing.py | 2 +- .../template-packs/full/ob_ma_notes.j2 | 1 + .../template-packs/full/ob_ordnance.j2 | 1 - .../full/ob_ordnance_ma_notes.j2 | 1 - .../template-packs/full/ob_ordnance_note.j2 | 1 - .../template-packs/full/ob_vehicle_note.j2 | 1 - .../template-packs/full/ob_vehicles.j2 | 1 - .../full/ob_vehicles_ma_notes.j2 | 1 - .../fixtures/template-packs/full/ob_vo.j2 | 1 + .../template-packs/full/ob_vo_note.j2 | 1 + .../template-packs/new-default/ob_ma_notes.j2 | 1 + .../template-packs/new-default/ob_ordnance.j2 | 1 - .../new-default/ob_ordnance_ma_notes.j2 | 1 - .../new-default/ob_ordnance_note.j2 | 1 - .../new-default/ob_vehicle_note.j2 | 1 - .../template-packs/new-default/ob_vehicles.j2 | 1 - .../new-default/ob_vehicles_ma_notes.j2 | 1 - .../template-packs/new-default/ob_vo.j2 | 1 + .../template-packs/new-default/ob_vo_note.j2 | 1 + vasl_templates/webapp/tests/remote.py | 19 ++-- .../webapp/tests/test_template_packs.py | 24 ++++- 23 files changed, 99 insertions(+), 61 deletions(-) create mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ma_notes.j2 delete mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ordnance.j2 delete mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ordnance_ma_notes.j2 delete mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ordnance_note.j2 delete mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vehicle_note.j2 delete mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vehicles.j2 delete mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vehicles_ma_notes.j2 create mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vo.j2 create mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vo_note.j2 create mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ma_notes.j2 delete mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ordnance.j2 delete mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ordnance_ma_notes.j2 delete mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ordnance_note.j2 delete mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vehicle_note.j2 delete mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vehicles.j2 delete mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vehicles_ma_notes.j2 create mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vo.j2 create mode 100644 vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vo_note.j2 diff --git a/vasl_templates/webapp/snippets.py b/vasl_templates/webapp/snippets.py index b707700..2637dda 100644 --- a/vasl_templates/webapp/snippets.py +++ b/vasl_templates/webapp/snippets.py @@ -72,27 +72,30 @@ def load_default_template_pack(): #pylint: disable=too-many-locals if os.path.isdir( dname ): # yup - return the files in it nat, templates, css, includes =_do_get_template_pack( dname ) - data["nationalities"].update( nat ) - data["templates"] = templates - data["css"] = css - data["includes"] = includes else: # extract the template pack files from the specified ZIP file - if not os.path.isfile( dname ): - raise RuntimeError( "Can't find template pack: {}".format( dname ) ) - data["templates"] = {} - with zipfile.ZipFile( dname, "r" ) as zip_file: - for fname in zip_file.namelist(): - if fname.endswith( "/" ): - continue - fdata = zip_file.read( fname ).decode( "utf-8" ) - fname2 = os.path.split(fname)[1] - if fname2.lower() == "nationalities.json": - data["nationalities"].update( json.loads( fdata ) ) - continue - if fname.startswith( "extras" + os.sep ): - fname2 = "extras/" + fname2 - data["templates"][ fname2 ] = fdata + nat, templates, css, includes =_do_get_template_pack_from_zip( dname ) + data["nationalities"].update( nat ) + data["templates"] = templates + data["css"] = css + data["includes"] = includes + + # FUDGE! In early versions of this program, the vehicles and ordnance templates were different + # (e.g. because only vehicles can be radioless, only ordnance can be QSU), but once everything + # was handled via generic capabilities, they became the same. We would therefore like to have + # a single template file handle both vehicles and ordnance, but the program had been architected + # in such a way that vehicles and ordnance snippets are generated from their own templates, + # so rather than re-architect the program, we maintain separate templates, that just happen + # to be read from the same file. This causes a bit of stuffing around when the code needs to know + # what file a template comes from (e.g. loading a template pack), but it's mostly transparent... + templates = data.get( "templates" ) + if templates: + if "ob_vo" in templates: + templates["ob_vehicles"] = templates["ob_ordnance"] = templates.pop( "ob_vo" ) + if "ob_vo_note" in templates: + templates["ob_vehicle_note"] = templates["ob_ordnance_note"] = templates.pop( "ob_vo_note" ) + if "ob_ma_notes" in templates: + templates["ob_vehicles_ma_notes"] = templates["ob_ordnance_ma_notes"] = templates.pop( "ob_ma_notes" ) globvars.template_pack = data @@ -104,7 +107,7 @@ def _do_get_template_pack( dname ): if not os.path.isdir( dname ): abort( 404 ) nationalities, templates, css, includes = {}, {}, {}, {} - for root,_,fnames in os.walk(dname): + for root,_,fnames in os.walk( dname ): for fname in fnames: # add the next file to the results fname_stem, extn = os.path.splitext( fname ) @@ -117,26 +120,41 @@ def _do_get_template_pack( dname ): relpath = os.path.relpath( os.path.abspath(fname), dname ) if relpath.startswith( "extras" + os.sep ): fname_stem = "extras/" + fname_stem - # FUDGE! In early versions of this program, the vehicles and ordnance templates were different - # (e.g. because only vehicles can be radioless, only ordnance can be QSU), but once everything - # was handled via generic capabilities, they became the same. We would therefore like to have - # a single template file handle both vehicles and ordnance, but the program had been architected - # in such a way that vehicles and ordnance snippets are generated from their own templates, - # so rather than re-architect the program, we maintain separate templates, that just happen - # to be read from the same file. This causes a bit of stuffing around when the code needs to know - # what file a template comes from (e.g. loading a template pack), but it's mostly transparent... - if fname_stem == "ob_vo": - templates["ob_vehicles"] = templates["ob_ordnance"] = fp.read() - elif fname_stem == "ob_vo_note": - templates["ob_vehicle_note"] = templates["ob_ordnance_note"] = fp.read() - elif fname_stem == "ob_ma_notes": - templates["ob_vehicles_ma_notes"] = templates["ob_ordnance_ma_notes"] = fp.read() - else: - templates[fname_stem] = fp.read() + templates[ fname_stem ] = fp.read() elif extn == ".css": - css[fname_stem] = fp.read() + css[ fname_stem ] = fp.read() elif extn == ".include": - includes[fname_stem] = fp.read() + includes[ fname_stem ] = fp.read() + return nationalities, templates, css, includes + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +def _do_get_template_pack_from_zip( fname ): + """Get the specified template pack.""" + fname = os.path.abspath( fname ) + if not os.path.isfile( fname ): + abort( 404 ) + nationalities, templates, css, includes = {}, {}, {}, {} + with zipfile.ZipFile( fname, "r" ) as zip_file: + for zip_fname in zip_file.namelist(): + if zip_fname.endswith( "/" ): + continue + # extract the next file + fdata = zip_file.read( zip_fname ).decode( "utf-8" ) + fname2 = os.path.split( zip_fname )[1] + # add the file to the results + if fname2.lower() == "nationalities.json": + nationalities = json.loads( fdata ) + continue + fname2, extn = os.path.splitext( fname2 ) + if zip_fname.startswith( "extras" + os.sep ): + fname2 = "extras/" + fname2 + if extn == ".css": + css[ fname2 ] = fdata + elif extn == ".include": + includes[ fname2 ] = fdata + else: + templates[ fname2 ] = fdata return nationalities, templates, css, includes # --------------------------------------------------------------------- diff --git a/vasl_templates/webapp/static/snippets.js b/vasl_templates/webapp/static/snippets.js index 2714862..b97efff 100644 --- a/vasl_templates/webapp/static/snippets.js +++ b/vasl_templates/webapp/static/snippets.js @@ -169,7 +169,7 @@ function make_snippet( $btn, params, extra_params, show_date_warnings ) params.SNIPPET_ID = player_nat + "/" + params.SNIPPET_ID ; // set the vehicle/ordnance labels - if ( template_id.indexOf( "_vehicles_" ) !== -1 ) { + if ( template_id.indexOf( "_vehicle_" ) !== -1 || template_id.indexOf( "_vehicles_" ) !== -1 ) { params.VO_TYPE = "Vehicle" ; params.VO_TYPES = "Vehicles" ; } else if ( template_id.indexOf( "_ordnance_" ) !== -1 ) { @@ -459,6 +459,7 @@ function make_snippet( $btn, params, extra_params, show_date_warnings ) filters: { join: function( vals, sep ) { return vals ? vals.join(sep) : "" ; }, nbsp: function( val ) { return strReplaceAll( val, " ", " " ) ; }, + upper: function( val ) { return val ? val.toUpperCase() : "" ; }, } , } ) ; snippet = snippet.trim() ; diff --git a/vasl_templates/webapp/testing.py b/vasl_templates/webapp/testing.py index 6fc72ba..6c51992 100644 --- a/vasl_templates/webapp/testing.py +++ b/vasl_templates/webapp/testing.py @@ -31,7 +31,7 @@ def control_tests( action ): for param in sig.parameters.values(): if param.name in ("vengine","vmod","gpids","key","val","dtype","fname","dname","extns_dtype","bin_data"): kwargs[ param.name ] = request.args.get( param.name, param.default ) - if param.name == "bin_data": + if param.name == "bin_data" and kwargs["bin_data"]: kwargs["bin_data"] = base64.b64decode( kwargs["bin_data"] ) # execute the command diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ma_notes.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ma_notes.j2 new file mode 100644 index 0000000..e20237e --- /dev/null +++ b/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ma_notes.j2 @@ -0,0 +1 @@ +Customized OB_{{VO_TYPES|upper}}_MA_NOTES. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ordnance.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ordnance.j2 deleted file mode 100644 index 58360cc..0000000 --- a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ordnance.j2 +++ /dev/null @@ -1 +0,0 @@ -Customized OB_ORDNANCE. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ordnance_ma_notes.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ordnance_ma_notes.j2 deleted file mode 100644 index c791608..0000000 --- a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ordnance_ma_notes.j2 +++ /dev/null @@ -1 +0,0 @@ -Customized OB_ORDNANCE_MA_NOTES. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ordnance_note.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ordnance_note.j2 deleted file mode 100644 index 065dda6..0000000 --- a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_ordnance_note.j2 +++ /dev/null @@ -1 +0,0 @@ -Customized OB_ORDNANCE_NOTE. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vehicle_note.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vehicle_note.j2 deleted file mode 100644 index 0441c26..0000000 --- a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vehicle_note.j2 +++ /dev/null @@ -1 +0,0 @@ -Customized OB_VEHICLE_NOTE. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vehicles.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vehicles.j2 deleted file mode 100644 index 2f1fe1f..0000000 --- a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vehicles.j2 +++ /dev/null @@ -1 +0,0 @@ -Customized OB_VEHICLES. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vehicles_ma_notes.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vehicles_ma_notes.j2 deleted file mode 100644 index 52d4521..0000000 --- a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vehicles_ma_notes.j2 +++ /dev/null @@ -1 +0,0 @@ -Customized OB_VEHICLES_MA_NOTES. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vo.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vo.j2 new file mode 100644 index 0000000..6ba1ca2 --- /dev/null +++ b/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vo.j2 @@ -0,0 +1 @@ +Customized OB_{{VO_TYPES|upper}}. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vo_note.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vo_note.j2 new file mode 100644 index 0000000..7aacb78 --- /dev/null +++ b/vasl_templates/webapp/tests/fixtures/template-packs/full/ob_vo_note.j2 @@ -0,0 +1 @@ +Customized OB_{{VO_TYPE|upper}}_NOTE. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ma_notes.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ma_notes.j2 new file mode 100644 index 0000000..8e05866 --- /dev/null +++ b/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ma_notes.j2 @@ -0,0 +1 @@ +New default OB_{{VO_TYPES|upper}}_MA_NOTES. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ordnance.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ordnance.j2 deleted file mode 100644 index 072cce6..0000000 --- a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ordnance.j2 +++ /dev/null @@ -1 +0,0 @@ -New default OB_ORDNANCE. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ordnance_ma_notes.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ordnance_ma_notes.j2 deleted file mode 100644 index 8040afa..0000000 --- a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ordnance_ma_notes.j2 +++ /dev/null @@ -1 +0,0 @@ -New default OB_ORDNANCE_MA_NOTES. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ordnance_note.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ordnance_note.j2 deleted file mode 100644 index a2477b1..0000000 --- a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_ordnance_note.j2 +++ /dev/null @@ -1 +0,0 @@ -New default OB_ORDNANCE_NOTE. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vehicle_note.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vehicle_note.j2 deleted file mode 100644 index 6a0eb72..0000000 --- a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vehicle_note.j2 +++ /dev/null @@ -1 +0,0 @@ -New default OB_VEHICLE_NOTE. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vehicles.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vehicles.j2 deleted file mode 100644 index 86b10b5..0000000 --- a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vehicles.j2 +++ /dev/null @@ -1 +0,0 @@ -New default OB_VEHICLES. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vehicles_ma_notes.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vehicles_ma_notes.j2 deleted file mode 100644 index b436607..0000000 --- a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vehicles_ma_notes.j2 +++ /dev/null @@ -1 +0,0 @@ -New default OB_VEHICLES_MA_NOTES. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vo.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vo.j2 new file mode 100644 index 0000000..ec940b1 --- /dev/null +++ b/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vo.j2 @@ -0,0 +1 @@ +New default OB_{{VO_TYPES|upper}}. diff --git a/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vo_note.j2 b/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vo_note.j2 new file mode 100644 index 0000000..f4e2a92 --- /dev/null +++ b/vasl_templates/webapp/tests/fixtures/template-packs/new-default/ob_vo_note.j2 @@ -0,0 +1 @@ +New default OB_{{VO_TYPE|upper}}_NOTE. diff --git a/vasl_templates/webapp/tests/remote.py b/vasl_templates/webapp/tests/remote.py index 64cc8be..7007d01 100644 --- a/vasl_templates/webapp/tests/remote.py +++ b/vasl_templates/webapp/tests/remote.py @@ -43,11 +43,11 @@ class ControlTests: self.server_url = pytest.config.option.server_url #pylint: disable=no-member except AttributeError: self.server_url = None - # set up a temp directory for our test VASL extensions - self._vasl_extns_temp_dir = tempfile.TemporaryDirectory() + # set up a directory for our temp files + self._temp_dir = tempfile.TemporaryDirectory() def __del__( self ): - self._vasl_extns_temp_dir.cleanup() + self._temp_dir.cleanup() def __getattr__( self, name ): """Generic entry point for handling control requests.""" @@ -116,9 +116,14 @@ class ControlTests: webapp_main.default_scenario = fname return self - def _set_default_template_pack( self, dname=None ): + def _set_default_template_pack( self, dname=None, bin_data=None ): """Set the default template pack.""" - if dname == "real": + if bin_data: + fname = os.path.join( self._temp_dir.name, "default-template-pack.zip" ) + with open( fname, "wb" ) as fp: + fp.write( bin_data ) + dname = fname + elif dname == "real": dname = os.path.join( os.path.split(__file__)[0], "../data/default-template-pack" ) elif dname: dname2 = os.path.join( os.path.split(__file__)[0], "fixtures" ) @@ -168,7 +173,7 @@ class ControlTests: except AttributeError: dname = app.config[ "TEST_VASL_EXTNS_DIR" ] elif extns_dtype == "test": - dname = self._vasl_extns_temp_dir.name + dname = self._temp_dir.name else: assert False, "Unknown extensions directory type: "+extns_dtype _logger.info( "Enabling VASL extensions: %s", dname ) @@ -211,7 +216,7 @@ class ControlTests: def _set_test_vasl_extn( self, fname=None, bin_data=None ): """Set the test VASL extension.""" - fname = os.path.join( self._vasl_extns_temp_dir.name, fname ) + fname = os.path.join( self._temp_dir.name, fname ) with open( fname, "wb" ) as fp: fp.write( bin_data ) return self diff --git a/vasl_templates/webapp/tests/test_template_packs.py b/vasl_templates/webapp/tests/test_template_packs.py index e1202ee..9a53bd2 100644 --- a/vasl_templates/webapp/tests/test_template_packs.py +++ b/vasl_templates/webapp/tests/test_template_packs.py @@ -92,10 +92,30 @@ def test_new_default_template_pack( webapp, webdriver ): ct.set_default_template_pack( dname="template-packs/new-default/" ) \ .set_vo_notes_dir( dtype="test" ) ) - set_player( 1, "german" ) - set_player( 2, "russian" ) # check that the new templates are being used + _do_test_default_template_pack( webdriver ) + +def test_new_default_template_pack_zip( webapp, webdriver ): + """Test changing the default template pack.""" + + # create a new template pack as a ZIP file + zip_data = make_zip_from_files( "new-default" ) + + # initialize + init_webapp( webapp, webdriver, + reset = lambda ct: + ct.set_default_template_pack( bin_data=zip_data ) \ + .set_vo_notes_dir( dtype="test" ) + ) + + # check that the new templates are being used + _do_test_default_template_pack( webdriver ) + +def _do_test_default_template_pack( webdriver ): + """Check that the default template pack is being used.""" + set_player( 1, "german" ) + set_player( 2, "russian" ) _check_snippets( webdriver, lambda tid: "New default {}.".format( tid.upper() ) ) # ---------------------------------------------------------------------