diff --git a/vasl_templates/webapp/data/vehicles/landing-craft.json b/vasl_templates/webapp/data/vehicles/landing-craft.json new file mode 100644 index 0000000..5aab991 --- /dev/null +++ b/vasl_templates/webapp/data/vehicles/landing-craft.json @@ -0,0 +1,56 @@ +[ + +{ "name": "LCP(L)", + "CS#": 4, + "damage_points": 2, + "note_number": "1\u2020", + "notes": [ "A\u20201", "B\u20203", "C\u20202", "D" ] +}, +{ "name": "LCA", + "CS#": 6, + "damage_points": 3, + "note_number": "2\u2020" +}, +{ "name": "LCVP", + "CS#": 5, + "damage_points": 3, + "note_number": "3\u2020", + "notes": [ "B\u20202", "C\u20201" ] +}, +{ "name": "LCV", + "CS#": 5, + "damage_points": 3, + "note_number": "3\u2020" +}, +{ "name": "LCM(3)", + "CS#": 6, + "damage_points": 5, + "note_number": "4\u2020", + "notes": [ "B\u20202", "C\u20201" ] +}, +{ "name": "LCI(S)", + "CS#": 10, + "damage_points": 14, + "note_number": "5\u2020", + "notes": [ "C\u20203", "D", "E\u20202", "F\u20201", "G" ] +}, +{ "name": "LCT(4)", + "CS#": 9, + "damage_points": 10, + "note_number": "6\u2020", + "notes": [ "C\u20203", "E\u20202", "F\u20201", "G" ] +}, +{ "name": "Daihatsu", + "CS#": 4, + "damage_points": 3, + "note_number": "7\u2020", + "notes": [ "A\u20201" ] +}, +{ "name": "Shohatsu", + "CS#": 3, + "damage_points": 2, + "note_number": "8\u2020", + "notes": [ "A\u2020", "D" ] +} + +] diff --git a/vasl_templates/webapp/static/snippets.js b/vasl_templates/webapp/static/snippets.js index 5e74d3a..e58b8a1 100644 --- a/vasl_templates/webapp/static/snippets.js +++ b/vasl_templates/webapp/static/snippets.js @@ -356,6 +356,10 @@ function make_capabilities( entry, nat, scenario_theater, scenario_year, scenari capabilities.push( entry.capabilities_other[i] ) ; } + // include damage points (for Landing Craft) + if ( "damage_points" in entry ) + capabilities.push( "DP " + entry.damage_points ) ; + return capabilities.length > 0 ? capabilities : null ; } diff --git a/vasl_templates/webapp/templates/vo-report.html b/vasl_templates/webapp/templates/vo-report.html index c4349d8..ed981aa 100644 --- a/vasl_templates/webapp/templates/vo-report.html +++ b/vasl_templates/webapp/templates/vo-report.html @@ -24,10 +24,10 @@ td { padding: 0.2em 0.5em ; } $(document).ready( function () { // get the vehicle listings var url ; - if ( "{{VO_TYPE}}" == "vehicles" ) - url = "{{url_for( 'get_vehicle_listings', report=1 )}}" - else + if ( "{{VO_TYPE}}" == "ordnance" ) url = "{{url_for( 'get_ordnance_listings', report=1 )}}" ; + else + url = "{{url_for( 'get_vehicle_listings', report=1 )}}" ; // nb: includes landing craft if ( getUrlParam( "merge_common" ) === "1" ) url += "&merge_common=1" ; $.getJSON( url, function(data) { @@ -50,8 +50,10 @@ function load_vo_listings( objs ) vo_name = decodeURIComponent( vo_name ).toLowerCase() ; // check if there are any vehicles/ordnance for the specified nationality + if ( "{{VO_TYPE}}" === "landing-craft" ) + nat = "landing-craft" ; if ( ! (nat in objs ) ) { - $results.text( "No listings for nationality: " ) ; + nat + $results.text( "No listings for nationality: " + nat ).show() ; return ; } @@ -64,6 +66,10 @@ function load_vo_listings( objs ) buf.push( "IF" ) ; buf.push( "Crew survival" ) ; } + if ( "{{VO_TYPE}}" === "landing-craft" ) { + buf.push( "Damage points" ) ; + buf.push( "Crew survival" ) ; + } buf.push( "Capabilities", "Notes" ) ; for ( var i=0 ; i < objs[nat].length ; ++i ) { var obj = objs[nat][i] ; @@ -81,6 +87,10 @@ function load_vo_listings( objs ) buf.push( "", fmtval(has_if) ) ; buf.push( "", fmtval(make_crew_survival(obj)) ) ; } + if ( "{{VO_TYPE}}" === "landing-craft" ) { + buf.push( "", fmtval(obj.damage_points) ) ; + buf.push( "", fmtval(make_crew_survival(obj)) ) ; + } var capabilities = make_capabilities( obj, nat, theater, year, month, true, true ) ; buf.push( "", listval(capabilities) ) ; var capabilities = make_capabilities( obj, nat, theater, year, month, true, false ) ; diff --git a/vasl_templates/webapp/tests/fixtures/vo-reports/landing-craft.txt b/vasl_templates/webapp/tests/fixtures/vo-reports/landing-craft.txt new file mode 100644 index 0000000..7629da7 --- /dev/null +++ b/vasl_templates/webapp/tests/fixtures/vo-reports/landing-craft.txt @@ -0,0 +1,13 @@ +=== landing craft === + +Name Damage points Crew survival Capabilities (effective) # Notes +-------- --------------- --------------- -------------- ------------- --- ------------------------------------------------ +LCP(L) 2 CS 4 DP 2 DP 2 1† A†1 B†3 C†2 D +LCA 3 CS 6 DP 3 DP 3 2† n/a +LCVP 3 CS 5 DP 3 DP 3 3† B†2 C†1 +LCV 3 CS 5 DP 3 DP 3 3† n/a +LCM(3) 5 CS 6 DP 5 DP 5 4† B†2 C†1 +LCI(S) 14 CS 10 DP 14 DP 14 5† C†3 D E†2 F†1 G +LCT(4) 10 CS 9 DP 10 DP 10 6† C†3 E†2 F†1 G +Daihatsu 3 CS 4 DP 3 DP 3 7† A†1 +Shohatsu 2 CS 3 DP 2 DP 2 8† A† D diff --git a/vasl_templates/webapp/tests/test_vo_reports.py b/vasl_templates/webapp/tests/test_vo_reports.py index a7509a6..f075835 100644 --- a/vasl_templates/webapp/tests/test_vo_reports.py +++ b/vasl_templates/webapp/tests/test_vo_reports.py @@ -14,7 +14,7 @@ from vasl_templates.webapp.tests.utils import find_child, wait_for # --------------------------------------------------------------------- -def test_vo_reports( webapp, webdriver ): +def test_vo_reports( webapp, webdriver ): #pylint: disable=too-many-locals """Check the vehicle/ordnance reports.""" # initialize @@ -46,7 +46,6 @@ def test_vo_reports( webapp, webdriver ): for year in range(1940,1945+1): # get the next report - buf = io.StringIO() results = get_vo_report( webapp, webdriver, "ETO", nat, vo_type, year, 1 ) # FUDGE! The "capabilities" and "notes" columns span 2 columns each, @@ -61,7 +60,8 @@ def test_vo_reports( webapp, webdriver ): fixup_capabilities( -3, "(effective)" ) fixup_capabilities( -2, "#" ) - # output the report + # convert the report to plain-text + buf = io.StringIO() print( "=== {}/{}/{} ===".format( vo_type, nat, year ), file=buf ) print( "", file=buf ) print( @@ -82,6 +82,35 @@ def test_vo_reports( webapp, webdriver ): fname = os.path.join( check_dir, fname ) assert open(fname,"r",encoding="utf-8").read() == report + # get the landing craft report + url = webapp.url_for( "get_lc_report" ) + webdriver.get( url ) + wait_for( 2, lambda: find_child("#results").is_displayed() ) + results = _parse_report( webdriver.page_source ) + + # convert the report to plain-text + assert results[0][-1] == "Notes" + results[0].insert( len(results[0])-1, "#" ) + assert results[0][-3] == "Capabilities" + results[0].insert( len(results[0])-2, "(effective)" ) + buf = io.StringIO() + print( "=== landing craft ===", file=buf ) + print( "", file=buf ) + print( + tabulate.tabulate( results, headers="firstrow" ), + file = buf + ) + report = buf.getvalue() + + # check if we should save the report + if save_dir: + with open( os.path.join(save_dir,"landing-craft.txt"), "w" ) as fp: + fp.write( report ) + + # check the report + fname = os.path.join( check_dir, "landing-craft.txt" ) + assert open(fname,"r",encoding="utf-8").read() == report + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - def get_vo_report( webapp, webdriver, @@ -108,6 +137,14 @@ def get_vo_report( webapp, webdriver, webdriver.get( url ) wait_for( 2, lambda: find_child("#results").is_displayed() ) + # parse the report + results = _parse_report( webdriver.page_source ) + + return results + +def _parse_report( buf ): + """Parse a vehicle/ordnance report.""" + def tidy( cell ): """Tidy up a cell value.""" val = lxml.etree.tostring( cell ).decode( "utf-8" ) #pylint: disable=c-extension-no-member @@ -123,7 +160,7 @@ def get_vo_report( webapp, webdriver, # unload the results # NOTE: Getting each table cell via Selenium is insanely slow - we parse the HTML manually :-/ results = [] - doc = lxml.html.fromstring( webdriver.page_source ) + doc = lxml.html.fromstring( buf ) for row in doc.xpath( "//div[@id='results']//table//tr" ): tag = "td" if results else "th" cells = row.xpath( ".//{}".format( tag ) ) diff --git a/vasl_templates/webapp/vo.py b/vasl_templates/webapp/vo.py index e18f547..6f8bd8a 100644 --- a/vasl_templates/webapp/vo.py +++ b/vasl_templates/webapp/vo.py @@ -51,14 +51,23 @@ def _do_get_listings( listings_type ): #pylint: disable=too-many-branches with open( os.path.join(root,fname), "r" ) as fp: listings[nat] = json.load( fp ) - # merge the common entries into each Allied/Axis Minor listing + # merge common entries if request.args.get( "merge_common" ) == "1": + # merge common Allied/Axis Minor vehicles/ordnance for minor_type in ("allied-minor","axis-minor"): if minor_type+"-common" not in listings: continue for nat in minor_nats[minor_type]: listings[nat].extend( listings[minor_type+"-common"] ) del listings[ minor_type+"-common" ] + # merge landing craft + if listings_type == "vehicles": + for lc in listings.get("landing-craft",[]): + if lc["name"] in ("Daihatsu","Shohatsu"): + listings["japanese"].append( lc ) + else: + listings["american"].append( lc ) + listings["british"].append( lc ) return jsonify( listings ) @@ -80,3 +89,12 @@ def get_vo_report( theater, nat, vo_type, year, month ): YEAR = year, MONTH = month, ) + +@app.route( "/landing_craft" ) +def get_lc_report(): + """Get a landing craft ordnance report.""" + return render_template( "vo-report.html", + VO_TYPE = "landing-craft", + YEAR = "null", + MONTH = "null", + )