diff --git a/chapter-h/chapter-h-placeholders.zip b/chapter-h/chapter-h-placeholders.zip index c4b5034..9fc92b9 100644 Binary files a/chapter-h/chapter-h-placeholders.zip and b/chapter-h/chapter-h-placeholders.zip differ diff --git a/vasl_templates/tools/make_chapter_h_placeholders.py b/vasl_templates/tools/make_chapter_h_placeholders.py index 2ab53fb..01d678b 100755 --- a/vasl_templates/tools/make_chapter_h_placeholders.py +++ b/vasl_templates/tools/make_chapter_h_placeholders.py @@ -5,9 +5,12 @@ import os import zipfile import json import re +import glob import click +nationalities = None + # --------------------------------------------------------------------- @click.command() @@ -21,7 +24,8 @@ def main( output_fname ): # pylint: disable=too-many-locals,too-many-branches # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -def make_chapter_h_placeholders( output_fname, log=None ): #pylint: disable=too-many-locals,too-many-branches +def make_chapter_h_placeholders( output_fname, log=None \ + ): #pylint: disable=too-many-locals,too-many-statements,too-many-branches """Create a ZIP file with placeholder files for each Chapter H note and multi-applicable note.""" # initialize @@ -33,6 +37,11 @@ def make_chapter_h_placeholders( output_fname, log=None ): #pylint: disable=too- log = log_nothing results = {} + # load the nationalities + fname = os.path.join( os.path.split(__file__)[0], "../webapp/data/default-template-pack/nationalities.json" ) + global nationalities + nationalities = json.load( open( fname, "r" ) ) + # load the vehicle/ordnance data files base_dir = os.path.join( os.path.split(__file__)[0], "../webapp/data/" ) for vo_type in ("vehicles","ordnance"): @@ -48,7 +57,7 @@ def make_chapter_h_placeholders( output_fname, log=None ): #pylint: disable=too- nat = os.path.split( dname2 )[1] if nat in ("british-commonwealth-forces-korea","cvpa","kpa","us-rok-ounc","un-forces"): continue - notes, ma_notes = load_vo_data( fname ) + notes, ma_notes = load_vo_data( fname, nat ) if nat not in results: results[ nat ] = {} if nat == "landing-craft": @@ -56,6 +65,21 @@ def make_chapter_h_placeholders( output_fname, log=None ): #pylint: disable=too- else: results[ nat ][ vo_type ] = { "notes": notes, "ma_notes": ma_notes } + # load the extensions + base_dir = os.path.join( os.path.split(__file__)[0], "../webapp/data/extensions" ) + for fname in glob.glob( os.path.join( base_dir, "*.json" ) ): + extn_data = load_vo_data_from_extension( fname ) + for nat in extn_data: + for vo_type in extn_data[nat]: + for key in extn_data[nat][vo_type]: + if nat not in results: + results[nat] = {} + if vo_type not in results[nat]: + results[nat][vo_type] = {} + if key not in results[nat][vo_type]: + results[nat][vo_type][key] = [] + results[nat][vo_type][key].extend( extn_data[nat][vo_type].get( key, [] ) ) + # generate the placeholder files with zipfile.ZipFile( output_fname, "w" ) as zip_file: nats = sorted( results.keys() ) @@ -76,7 +100,7 @@ def make_chapter_h_placeholders( output_fname, log=None ): #pylint: disable=too- if isinstance(val, str): # NOTE: Filenames are always lower-case, unless the note ID itself is lower-case, # in which case we indicate this with a trailing underscore - if re.search( r"^[A-Z][A-Za-z]?$", val ): + if re.search( r"^([a-z]+:)?[A-Z][A-Za-z]?$", val ): val = val.lower() elif re.search( r"^[a-z]{1,2}?$", val ): val += "_" @@ -86,22 +110,13 @@ def make_chapter_h_placeholders( output_fname, log=None ): #pylint: disable=too- fname = "{}/{}/{}.{}".format( nat, vo_type, val, "png" if note_type == "notes" else "html" ) # add the placeholder file to the ZIP + fname = fname.replace( ":", "/" ) zip_file.writestr( fname, b"" ) log( "" ) # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -MA_NOTE_REGEXES = [ - re.compile( r"^([A-Z]{1,2})$" ), - re.compile( r"^([A-Z]{1,2})\u2020" ), - re.compile( r"^([a-z])$" ), - re.compile( r"^([a-z])\u2020" ), - re.compile( r"^([A-Z][a-z])$" ), - re.compile( r"^([A-Za-z])" ), - re.compile( r"^([A-Za-z])$" ), -] - -def load_vo_data( fname ): +def load_vo_data( fname, nat ): """Load a vehicle/ordnance data file.""" # initialize @@ -110,19 +125,94 @@ def load_vo_data( fname ): # load the file vo_data = json.load( open( fname, "r" ) ) for vo_entry in vo_data: + if "note_number" in vo_entry: + notes.add( + _extract_note_number( vo_entry["note_number"] ) + ) + if "notes" in vo_entry and not _ignore_ma_notes(nat): + ma_notes.update( + _extract_ma_note_ids( vo_entry["notes"] ) + ) - # load the vehicle/ordnance's note number - mo = re.search( r"^\d+", vo_entry["note_number"] ) - notes.add( int( mo.group() ) ) + return sorted(notes), sorted(ma_notes) - # load the multi-applicable note ID's - for ma_note in vo_entry.get("notes",[]): - matches = [ regex.search(ma_note) for regex in MA_NOTE_REGEXES ] - matches = [ mo.group(1) for mo in matches if mo ] - assert len(matches) == 1 - ma_notes.add( matches[0] ) +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - return sorted(notes), sorted(ma_notes) +def load_vo_data_from_extension( fname ): + """Load a vehicle/ordnance extension data file.""" + + # initialize + results = {} + + # get the extension ID + data = json.load( open( fname, "r" ) ) + extn_id = data["extensionId"] + + # load the file + for nat in data: + + if not isinstance( data[nat], dict ): + continue + + results[nat] = {} + for vo_type in ("vehicles","ordnance"): + notes, ma_notes = set(), set() + for vo_entry in data[nat].get(vo_type,[]): + # load the vehicle/ordnance's note number + if "note_number" in vo_entry: + notes.add( + _extract_note_number( vo_entry["note_number"] ) + ) + if "notes" in vo_entry and not _ignore_ma_notes(nat,extn_id): + ma_notes.update( + _extract_ma_note_ids( vo_entry["notes"] ) + ) + results[ nat ][ vo_type ] = { + "notes": [ "{}:{}".format( extn_id, n ) for n in sorted(notes) ], + "ma_notes": [ "{}:{}".format( extn_id, n ) for n in sorted(ma_notes) ] + } + + return results + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +MA_NOTE_REGEXES = [ + re.compile( r"^([A-Z]{1,2})$" ), + re.compile( r"^([A-Z]{1,2})\u2020" ), + re.compile( r"^([a-z])$" ), + re.compile( r"^([a-z])\u2020" ), + re.compile( r"^([A-Z][a-z])$" ), + re.compile( r"^([A-Za-z])" ), + re.compile( r"^([A-Za-z])$" ), +] + +REDIRECTED_MA_NOTE_REGEX = re.compile( + r"^((Ge|Ru|US|Br|Fr|Jp|Ch|Gr|AllM|AxM) ([A-Z]{1,2}|[0-9]{1,2}|Note \d+|P))\u2020?(\d)?$" +) + +def _extract_note_number( val ): + """Extract a vehicle/ordnance's note number.""" + mo = re.search( r"^\d+", val ) + return int( mo.group() ) + +def _extract_ma_note_ids( val ): + """Extract a vehicle/ordnance's multi-applicable note ID's.""" + ma_note_ids = [] + for ma_note in val: + if REDIRECTED_MA_NOTE_REGEX.search( ma_note ): + continue + matches = [ regex.search(ma_note) for regex in MA_NOTE_REGEXES ] + matches = [ mo.group(1) for mo in matches if mo ] + assert len(matches) == 1 + ma_note_ids.append( matches[0] ) + return ma_note_ids + +def _ignore_ma_notes( nat, extn_id=None ): + if extn_id == "adf" and nat == "american": + return True + if extn_id is None and nationalities.get( nat, {} ).get( "type" ) in ("allied-minor","axis-minor"): + return True + return False # --------------------------------------------------------------------- diff --git a/vasl_templates/tools/tests/fixtures/chapter-h-placeholders.txt b/vasl_templates/tools/tests/fixtures/chapter-h-placeholders.txt index 7ef6611..db73a66 100644 --- a/vasl_templates/tools/tests/fixtures/chapter-h-placeholders.txt +++ b/vasl_templates/tools/tests/fixtures/chapter-h-placeholders.txt @@ -63,6 +63,7 @@ american/ordnance/7.png american/ordnance/8.png american/ordnance/9.png american/ordnance/a.html +american/ordnance/adf/1.png american/ordnance/b.html american/ordnance/c.html american/ordnance/d.html @@ -130,10 +131,34 @@ american/vehicles/8.png american/vehicles/9.png american/vehicles/a.html american/vehicles/aa.html +american/vehicles/adf/1.png +american/vehicles/adf/10.png +american/vehicles/adf/11.png +american/vehicles/adf/2.png +american/vehicles/adf/3.png +american/vehicles/adf/4.png +american/vehicles/adf/5.png +american/vehicles/adf/6.png +american/vehicles/adf/7.png +american/vehicles/adf/8.png +american/vehicles/adf/9.png american/vehicles/b.html american/vehicles/bb.html american/vehicles/c.html american/vehicles/cc.html +american/vehicles/cobra/12.png +american/vehicles/cobra/13.png +american/vehicles/cobra/15.png +american/vehicles/cobra/16.png +american/vehicles/cobra/17.png +american/vehicles/cobra/23.png +american/vehicles/cobra/43.png +american/vehicles/cobra/5.png +american/vehicles/cobra/8.png +american/vehicles/cobra/9.png +american/vehicles/cobra/a.html +american/vehicles/cobra/b.html +american/vehicles/cobra/c.html american/vehicles/d.html american/vehicles/e.html american/vehicles/f.html @@ -156,6 +181,10 @@ american/vehicles/w.html american/vehicles/x.html american/vehicles/y.html american/vehicles/z.html +anzac/vehicles/adf/1.png +anzac/vehicles/adf/2.png +anzac/vehicles/adf/3.png +anzac/vehicles/adf/4.png axis-minor/ordnance/44.png axis-minor/ordnance/45.png axis-minor/ordnance/46.png @@ -246,16 +275,11 @@ belgian/ordnance/6.png belgian/ordnance/7.png belgian/ordnance/8.png belgian/ordnance/9.png -belgian/ordnance/a.html -belgian/ordnance/b.html -belgian/ordnance/d.html belgian/vehicles/14.png belgian/vehicles/15.png belgian/vehicles/16.png belgian/vehicles/17.png belgian/vehicles/18.png -belgian/vehicles/a.html -belgian/vehicles/q.html british/ordnance/1.png british/ordnance/10.png british/ordnance/11.png @@ -407,9 +431,6 @@ bulgarian/ordnance/40.png bulgarian/ordnance/41.png bulgarian/ordnance/42.png bulgarian/ordnance/43.png -bulgarian/ordnance/a.html -bulgarian/ordnance/g.html -bulgarian/ordnance/t.html bulgarian/vehicles/28.png chinese/ordnance/1.png chinese/ordnance/10.png @@ -452,6 +473,19 @@ chinese/vehicles/7.png chinese/vehicles/8.png chinese/vehicles/9.png chinese/vehicles/a.html +chinese/vehicles/adf/1.png +chinese/vehicles/adf/2.png +chinese/vehicles/adf/3.png +chinese/vehicles/adf/4.png +chinese/vehicles/adf/5.png +chinese/vehicles/adf/6.png +chinese/vehicles/adf/7.png +chinese/vehicles/adf/8.png +chinese/vehicles/adf/9.png +chinese/vehicles/adf/a.html +chinese/vehicles/adf/b.html +chinese/vehicles/adf/c.html +chinese/vehicles/adf/d.html chinese/vehicles/b.html chinese/vehicles/c.html chinese/vehicles/d.html @@ -461,28 +495,31 @@ chinese/vehicles/g.html chinese/vehicles/h.html croatian/ordnance/35.png croatian/ordnance/36.png -croatian/ordnance/a.html croatian/vehicles/24.png croatian/vehicles/25.png croatian/vehicles/26.png croatian/vehicles/27.png -croatian/vehicles/f.html -croatian/vehicles/o.html danish/ordnance/19.png -danish/ordnance/de.html -danish/ordnance/t.html danish/vehicles/24.png dutch/ordnance/15.png -dutch/ordnance/a.html -dutch/ordnance/ne.html +dutch/ordnance/adf/1.png +dutch/ordnance/adf/2.png +dutch/ordnance/adf/3.png +dutch/ordnance/adf/4.png +dutch/ordnance/adf/6.png dutch/vehicles/25.png dutch/vehicles/26.png dutch/vehicles/27.png dutch/vehicles/28.png dutch/vehicles/29.png dutch/vehicles/30.png -dutch/vehicles/a.html -dutch/vehicles/v.html +dutch/vehicles/adf/1.png +dutch/vehicles/adf/2.png +dutch/vehicles/adf/3.png +dutch/vehicles/adf/4.png +dutch/vehicles/adf/5.png +dutch/vehicles/adf/6.png +dutch/vehicles/adf/a.html finnish/ordnance/1.png finnish/ordnance/10.png finnish/ordnance/11.png @@ -680,6 +717,10 @@ german/ordnance/c.html german/ordnance/n.html german/ordnance/o.html german/ordnance/p.html +german/ordnance/pif/1.png +german/ordnance/pif/2.png +german/ordnance/pif/3.png +german/ordnance/pif/4.png german/vehicles/1.png german/vehicles/10.png german/vehicles/11.png @@ -801,20 +842,26 @@ german/vehicles/m.html german/vehicles/n.html german/vehicles/o.html german/vehicles/p.html +german/vehicles/pif/1.png +german/vehicles/pif/2.png +german/vehicles/pif/3.png +german/vehicles/pif/4.png +german/vehicles/pif/5.png +german/vehicles/pif/6.png +german/vehicles/pif/7.png +german/vehicles/pif/a.html +german/vehicles/pif/b.html german/vehicles/q.html german/vehicles/r.html german/vehicles/s.html greek/ordnance/16.png greek/ordnance/17.png greek/ordnance/18.png -greek/ordnance/gr.html hungarian/ordnance/23.png hungarian/ordnance/24.png hungarian/ordnance/25.png hungarian/ordnance/26.png hungarian/ordnance/27.png -hungarian/ordnance/a.html -hungarian/ordnance/g.html hungarian/vehicles/10.png hungarian/vehicles/11.png hungarian/vehicles/12.png @@ -825,11 +872,29 @@ hungarian/vehicles/16.png hungarian/vehicles/7.png hungarian/vehicles/8.png hungarian/vehicles/9.png -hungarian/vehicles/a.html -hungarian/vehicles/e.html -hungarian/vehicles/n.html -hungarian/vehicles/p.html -hungarian/vehicles/q.html +indonesian/ordnance/adf/1.png +indonesian/ordnance/adf/2.png +indonesian/ordnance/adf/3.png +indonesian/ordnance/adf/4.png +indonesian/ordnance/adf/5.png +indonesian/ordnance/adf/6.png +indonesian/vehicles/adf/1.png +indonesian/vehicles/adf/10.png +indonesian/vehicles/adf/11.png +indonesian/vehicles/adf/12.png +indonesian/vehicles/adf/13.png +indonesian/vehicles/adf/2.png +indonesian/vehicles/adf/3.png +indonesian/vehicles/adf/4.png +indonesian/vehicles/adf/5.png +indonesian/vehicles/adf/6.png +indonesian/vehicles/adf/7.png +indonesian/vehicles/adf/8.png +indonesian/vehicles/adf/9.png +indonesian/vehicles/adf/b.html +indonesian/vehicles/adf/c.html +indonesian/vehicles/adf/d.html +indonesian/vehicles/adf/e.html italian/ordnance/1.png italian/ordnance/10.png italian/ordnance/11.png @@ -926,6 +991,10 @@ japanese/ordnance/7.png japanese/ordnance/8.png japanese/ordnance/9.png japanese/ordnance/a.html +japanese/ordnance/adf/1.png +japanese/ordnance/adf/2.png +japanese/ordnance/adf/3.png +japanese/ordnance/adf/4.png japanese/ordnance/b.html japanese/ordnance/c.html japanese/ordnance/d.html @@ -950,6 +1019,34 @@ japanese/vehicles/7.png japanese/vehicles/8.png japanese/vehicles/9.png japanese/vehicles/a.html +japanese/vehicles/adf/1.png +japanese/vehicles/adf/10.png +japanese/vehicles/adf/11.png +japanese/vehicles/adf/12.png +japanese/vehicles/adf/13.png +japanese/vehicles/adf/14.png +japanese/vehicles/adf/15.png +japanese/vehicles/adf/16.png +japanese/vehicles/adf/17.png +japanese/vehicles/adf/18.png +japanese/vehicles/adf/19.png +japanese/vehicles/adf/2.png +japanese/vehicles/adf/20.png +japanese/vehicles/adf/21.png +japanese/vehicles/adf/22.png +japanese/vehicles/adf/23.png +japanese/vehicles/adf/24.png +japanese/vehicles/adf/25.png +japanese/vehicles/adf/3.png +japanese/vehicles/adf/4.png +japanese/vehicles/adf/5.png +japanese/vehicles/adf/6.png +japanese/vehicles/adf/7.png +japanese/vehicles/adf/8.png +japanese/vehicles/adf/9.png +japanese/vehicles/adf/a.html +japanese/vehicles/adf/b.html +japanese/vehicles/adf/c.html japanese/vehicles/b.html japanese/vehicles/c.html landing-craft/1.png @@ -972,8 +1069,18 @@ polish/ordnance/2.png polish/ordnance/3.png polish/ordnance/4.png polish/ordnance/5.png -polish/ordnance/a.html -polish/ordnance/p.html +polish/ordnance/pif/1.png +polish/ordnance/pif/10.png +polish/ordnance/pif/2.png +polish/ordnance/pif/3.png +polish/ordnance/pif/4.png +polish/ordnance/pif/5.png +polish/ordnance/pif/6.png +polish/ordnance/pif/7.png +polish/ordnance/pif/8.png +polish/ordnance/pif/9.png +polish/ordnance/pif/a.html +polish/ordnance/pif/b.html polish/vehicles/1.png polish/vehicles/10.png polish/vehicles/11.png @@ -987,14 +1094,22 @@ polish/vehicles/6.png polish/vehicles/7.png polish/vehicles/8.png polish/vehicles/9.png -polish/vehicles/a.html -polish/vehicles/aa.html -polish/vehicles/d.html -polish/vehicles/e.html -polish/vehicles/f.html -polish/vehicles/g.html -polish/vehicles/k.html -polish/vehicles/q.html +polish/vehicles/pif/1.png +polish/vehicles/pif/10.png +polish/vehicles/pif/11.png +polish/vehicles/pif/12.png +polish/vehicles/pif/2.png +polish/vehicles/pif/3.png +polish/vehicles/pif/4.png +polish/vehicles/pif/5.png +polish/vehicles/pif/6.png +polish/vehicles/pif/7.png +polish/vehicles/pif/8.png +polish/vehicles/pif/9.png +polish/vehicles/pif/a.html +polish/vehicles/pif/b.html +polish/vehicles/pif/c.html +polish/vehicles/pif/d.html romanian/ordnance/1.png romanian/ordnance/10.png romanian/ordnance/11.png @@ -1017,21 +1132,12 @@ romanian/ordnance/6.png romanian/ordnance/7.png romanian/ordnance/8.png romanian/ordnance/9.png -romanian/ordnance/a.html -romanian/ordnance/e.html -romanian/ordnance/k.html romanian/vehicles/1.png romanian/vehicles/2.png romanian/vehicles/3.png romanian/vehicles/4.png romanian/vehicles/5.png romanian/vehicles/6.png -romanian/vehicles/d.html -romanian/vehicles/e.html -romanian/vehicles/f.html -romanian/vehicles/i.html -romanian/vehicles/j.html -romanian/vehicles/n.html russian/ordnance/1.png russian/ordnance/10.png russian/ordnance/11.png @@ -1060,6 +1166,11 @@ russian/ordnance/7.png russian/ordnance/8.png russian/ordnance/9.png russian/ordnance/a.html +russian/ordnance/pif/1.png +russian/ordnance/pif/2.png +russian/ordnance/pif/3.png +russian/ordnance/pif/a.html +russian/ordnance/pif/b.html russian/vehicles/1.png russian/vehicles/10.png russian/vehicles/11.png @@ -1132,6 +1243,26 @@ russian/vehicles/m.html russian/vehicles/n.html russian/vehicles/o.html russian/vehicles/p.html +russian/vehicles/pif/1.png +russian/vehicles/pif/10.png +russian/vehicles/pif/11.png +russian/vehicles/pif/12.png +russian/vehicles/pif/13.png +russian/vehicles/pif/14.png +russian/vehicles/pif/15.png +russian/vehicles/pif/16.png +russian/vehicles/pif/17.png +russian/vehicles/pif/18.png +russian/vehicles/pif/2.png +russian/vehicles/pif/3.png +russian/vehicles/pif/4.png +russian/vehicles/pif/5.png +russian/vehicles/pif/6.png +russian/vehicles/pif/7.png +russian/vehicles/pif/8.png +russian/vehicles/pif/9.png +russian/vehicles/pif/b.html +russian/vehicles/pif/c.html russian/vehicles/q.html russian/vehicles/r.html russian/vehicles/s.html @@ -1143,8 +1274,6 @@ slovakian/ordnance/31.png slovakian/ordnance/32.png slovakian/ordnance/33.png slovakian/ordnance/34.png -slovakian/ordnance/a.html -slovakian/ordnance/e.html slovakian/vehicles/17.png slovakian/vehicles/18.png slovakian/vehicles/19.png @@ -1152,26 +1281,23 @@ slovakian/vehicles/20.png slovakian/vehicles/21.png slovakian/vehicles/22.png slovakian/vehicles/23.png -slovakian/vehicles/e.html -slovakian/vehicles/f.html -slovakian/vehicles/g.html -slovakian/vehicles/i.html -slovakian/vehicles/k.html -slovakian/vehicles/l.html +thai/ordnance/adf/4.png +thai/ordnance/adf/5.png +thai/ordnance/adf/8.png +thai/ordnance/adf/9.png +thai/vehicles/adf/1.png +thai/vehicles/adf/2.png +thai/vehicles/adf/3.png +thai/vehicles/adf/4.png +thai/vehicles/adf/5.png +thai/vehicles/adf/6.png +thai/vehicles/adf/a.html +thai/vehicles/adf/e.html yugoslavian/ordnance/20.png yugoslavian/ordnance/21.png yugoslavian/ordnance/22.png -yugoslavian/ordnance/y.html yugoslavian/vehicles/19.png yugoslavian/vehicles/20.png yugoslavian/vehicles/21.png yugoslavian/vehicles/22.png yugoslavian/vehicles/23.png -yugoslavian/vehicles/a.html -yugoslavian/vehicles/aa.html -yugoslavian/vehicles/b.html -yugoslavian/vehicles/c.html -yugoslavian/vehicles/d.html -yugoslavian/vehicles/g.html -yugoslavian/vehicles/h.html -yugoslavian/vehicles/l.html