Added asl-rulebook2 integration.

master
Pacman Ghost 3 years ago
parent 1d3af963df
commit f3ae34878c
  1. 3
      vasl_templates/main_window.py
  2. 8
      vasl_templates/webapp/__init__.py
  3. 1
      vasl_templates/webapp/static/css/sortable.css
  4. 2
      vasl_templates/webapp/static/css/tabs-ob.css
  5. BIN
      vasl_templates/webapp/static/images/aslrb2.png
  6. 13
      vasl_templates/webapp/static/main.js
  7. 4
      vasl_templates/webapp/static/utils.js
  8. 52
      vasl_templates/webapp/static/vo.js
  9. 2
      vasl_templates/webapp/templates/index.html
  10. 1
      vasl_templates/webapp/tests/control_tests_servicer.py
  11. 60
      vasl_templates/webapp/tests/fixtures/asl-rulebook2/vo-note-targets.json
  12. 4
      vasl_templates/webapp/tests/fixtures/data/default-template-pack/nationalities.json
  13. 1
      vasl_templates/webapp/tests/fixtures/data/ordnance/british.json
  14. 1
      vasl_templates/webapp/tests/fixtures/data/ordnance/kfw-cpva.json
  15. 8
      vasl_templates/webapp/tests/fixtures/data/ordnance/kfw/bcfk.json
  16. 8
      vasl_templates/webapp/tests/fixtures/data/ordnance/kfw/cpva.json
  17. 8
      vasl_templates/webapp/tests/fixtures/data/ordnance/kfw/un-common.json
  18. 1
      vasl_templates/webapp/tests/fixtures/data/vehicles/kfw-kpa.json
  19. 8
      vasl_templates/webapp/tests/fixtures/data/vehicles/kfw/kpa.json
  20. 8
      vasl_templates/webapp/tests/fixtures/data/vehicles/kfw/un-common.json
  21. 8
      vasl_templates/webapp/tests/fixtures/data/vehicles/kfw/us-rok-ounc.json
  22. 1
      vasl_templates/webapp/tests/fixtures/data/vehicles/landing-craft.json
  23. 117
      vasl_templates/webapp/tests/test_aslrb2.py
  24. 48
      vasl_templates/webapp/vo_notes.py

@ -28,7 +28,8 @@ class AppWebPage( QWebEnginePage ):
def acceptNavigationRequest( self, url, nav_type, is_mainframe ): #pylint: disable=no-self-use,unused-argument def acceptNavigationRequest( self, url, nav_type, is_mainframe ): #pylint: disable=no-self-use,unused-argument
"""Called when a link is clicked.""" """Called when a link is clicked."""
if url.host() in ("localhost","127.0.0.1"): if url.host() in ("localhost","127.0.0.1"):
return True if "/asl-rulebook2/" not in url.url(): # nb: asl-rulebook2 links are routed through our webapp
return True
if not is_mainframe: if not is_mainframe:
# NOTE: We get here if we're in a child frame (e.g. Google Maps). However, we can't just ignore # NOTE: We get here if we're in a child frame (e.g. Google Maps). However, we can't just ignore
# these requests, because the help is also in a frame, and we want links to open in an external browser. # these requests, because the help is also in a frame, and we want links to open in an external browser.

@ -52,6 +52,9 @@ def _init_webapp():
# NOTE: While this is generally called only once (before the first request), the test suite # NOTE: While this is generally called only once (before the first request), the test suite
# can force it be done again, since it wants to reconfigure the server to test different cases. # can force it be done again, since it wants to reconfigure the server to test different cases.
# initialize
from vasl_templates.webapp.main import startup_msg_store #pylint: disable=cyclic-import
# start downloading files # start downloading files
# NOTE: We used to do this in the mainline code of __init__, so that we didn't have to wait # NOTE: We used to do this in the mainline code of __init__, so that we didn't have to wait
# for the first request before starting the download (useful if we are running as a standalone server). # for the first request before starting the download (useful if we are running as a standalone server).
@ -71,7 +74,6 @@ def _init_webapp():
# configure the VASL module # configure the VASL module
fname = app.config.get( "VASL_MOD" ) fname = app.config.get( "VASL_MOD" )
from vasl_templates.webapp.vasl_mod import set_vasl_mod #pylint: disable=cyclic-import 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 ) set_vasl_mod( fname, startup_msg_store )
# load the vehicle/ordnance listings # load the vehicle/ordnance listings
@ -82,6 +84,10 @@ def _init_webapp():
from vasl_templates.webapp.vo_notes import load_vo_notes #pylint: disable=cyclic-import from vasl_templates.webapp.vo_notes import load_vo_notes #pylint: disable=cyclic-import
load_vo_notes( startup_msg_store ) load_vo_notes( startup_msg_store )
# load integration data from asl-rulebook2
from vasl_templates.webapp.vo_notes import load_asl_rulebook2_vo_note_targets #pylint: disable=cyclic-import
load_asl_rulebook2_vo_note_targets( startup_msg_store )
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
def _load_config( fname, section ): def _load_config( fname, section ):

@ -9,6 +9,7 @@ img.sortable-reset { vertical-align: middle ; height: 15px ; margin-right: 0.25e
.sortable li:hover { cursor: pointer ; } .sortable li:hover { cursor: pointer ; }
.sortable li.ui-sortable-helper { opacity: 0.8 ; } .sortable li.ui-sortable-helper { opacity: 0.8 ; }
.sortable li img.snippet { height: 1.25em ; margin: -2px -2px ; padding-left: 1em ; float: right ; } .sortable li img.snippet { height: 1.25em ; margin: -2px -2px ; padding-left: 1em ; float: right ; }
.sortable li img.aslrb2 { height: 1.25em ; position: absolute ; bottom: -2px ; right: -2px ; opacity: 0.6 ; }
.sortable ul li, .sortable ol li { margin-top: -0.75em ; } /* nb: tighten up lists in sortable2 entries */ .sortable ul li, .sortable ol li { margin-top: -0.75em ; } /* nb: tighten up lists in sortable2 entries */

@ -21,7 +21,7 @@
.panel-ob_ordnance .footer { margin-top: 0.5em ; display: flex ; align-items: center ; } .panel-ob_ordnance .footer { margin-top: 0.5em ; display: flex ; align-items: center ; }
/* nb: the following CSS is shared by vehicles and ordnance */ /* nb: the following CSS is shared by vehicles and ordnance */
.panel-ob_vo .sortable .vo-entry { display: flex ; } .panel-ob_vo .sortable .vo-entry { display: flex ; position: relative ; }
.panel-ob_vo .sortable .vo-entry img.vasl-image { display: inline-block ; vertical-align: middle ; height: 3.25em ; margin-right: 0.5em ; } .panel-ob_vo .sortable .vo-entry img.vasl-image { display: inline-block ; vertical-align: middle ; height: 3.25em ; margin-right: 0.5em ; }
.panel-ob_vo .sortable .vo-entry.small-piece img.vasl-image { height: 2.25em ; margin-left: 0.5em ; margin-right: 0.75em ; } .panel-ob_vo .sortable .vo-entry.small-piece img.vasl-image { height: 2.25em ; margin-left: 0.5em ; margin-right: 0.75em ; }
.panel-ob_vo .sortable .vo-entry .detail { flex-grow: 1 ; display: flex ; flex-direction: column ; justify-content: center ; } .panel-ob_vo .sortable .vo-entry .detail { flex-grow: 1 ; display: flex ; flex-direction: column ; justify-content: center ; }

Binary file not shown.

After

Width:  |  Height:  |  Size: 980 B

@ -6,6 +6,7 @@ gVehicleOrdnanceListings = {} ;
gVehicleOrdnanceNotes = {} ; gVehicleOrdnanceNotes = {} ;
gVaslPieceInfo = {} ; gVaslPieceInfo = {} ;
gOnlineCounterImages = {} ; gOnlineCounterImages = {} ;
gAslRulebook2VoNoteTargets = {} ;
gWebChannelHandler = null ; gWebChannelHandler = null ;
gEmSize = null ; gEmSize = null ;
@ -347,6 +348,16 @@ $(document).ready( function () {
update_page_load_status( "template-pack" ) ; update_page_load_status( "template-pack" ) ;
} ) ; } ) ;
// get the ASL Rulebook2 vehicle/ordnance note targets
$.getJSON( gGetAslRulebook2VoNoteTargetsUrl, function(data) {
gAslRulebook2VoNoteTargets = data ;
update_page_load_status( "asl-rulebook2-vo-note-targets" ) ;
} ).fail( function( xhr, status, errorMsg ) {
if ( xhr.status != 404 )
showErrorMsg( "Can't get the ASL Rulebook2 vehicle/ordnance note targets:<div class='pre'>" + escapeHTML(errorMsg) + "</div>" ) ;
update_page_load_status( "asl-rulebook2-vo-note-targets" ) ;
} ) ;
// fixup the layout // fixup the layout
var prevHeight = [] ; var prevHeight = [] ;
$(window).resize( function() { $(window).resize( function() {
@ -534,7 +545,7 @@ function init_snippet_button( $btn )
gPageLoadStatus = [ gPageLoadStatus = [
"main", "app-config", "main", "app-config",
"vehicle-listings", "ordnance-listings", "reset-scenario", "vehicle-listings", "ordnance-listings", "reset-scenario",
"vehicle-notes", "ordnance-notes", "vehicle-notes", "ordnance-notes", "asl-rulebook2-vo-note-targets",
"vasl-piece-info", "online-counter-images", "template-pack", "default-scenario" "vasl-piece-info", "online-counter-images", "template-pack", "default-scenario"
] ; ] ;

@ -459,7 +459,7 @@ function get_month_name( month )
// -------------------------------------------------------------------- // --------------------------------------------------------------------
function fixup_external_links( $root ) function fixup_external_links( $root, fixAll )
{ {
// NOTE: We want to open externals links in a new browser window, but simply adding target="_blank" // NOTE: We want to open externals links in a new browser window, but simply adding target="_blank"
// breaks the desktop app's ability to intercept clicks (in AppWebPage.acceptNavigationRequest()), // breaks the desktop app's ability to intercept clicks (in AppWebPage.acceptNavigationRequest()),
@ -467,7 +467,7 @@ function fixup_external_links( $root )
var regex = new RegExp( "^https?://" ) ; var regex = new RegExp( "^https?://" ) ;
$root.find( "a" ).each( function() { $root.find( "a" ).each( function() {
var url = $(this).attr( "href" ) ; var url = $(this).attr( "href" ) ;
if ( url && url.match( regex ) ) if ( fixAll || ( url && url.match( regex ) ) )
$(this).attr( "target", gWebChannelHandler?"":"_blank" ) ; $(this).attr( "target", gWebChannelHandler?"":"_blank" ) ;
} ) ; } ) ;
} }

@ -155,6 +155,9 @@ function do_add_vo( vo_type, player_no, vo_entry, vo_image_id, elite, custom_cap
{ {
// initialize // initialize
var nat = get_player_nat( player_no ) ; var nat = get_player_nat( player_no ) ;
var nat_type = gTemplatePack.nationalities[ nat ].type ;
var vo_note_key = get_vo_note_key( vo_entry ) ;
var is_landing_craft = vo_note_key ? vo_note_key.substring( 0, 3 ) === "LC " : null ;
var $sortable2 = $( "#ob_" + vo_type + "-sortable_" + player_no ) ; var $sortable2 = $( "#ob_" + vo_type + "-sortable_" + player_no ) ;
if ( seq_id === null ) { if ( seq_id === null ) {
// auto-assign a sequence ID // auto-assign a sequence ID
@ -165,6 +168,43 @@ function do_add_vo( vo_type, player_no, vo_entry, vo_image_id, elite, custom_cap
seq_id = auto_assign_id( usedSeqIds, "seq_id" ) ; seq_id = auto_assign_id( usedSeqIds, "seq_id" ) ;
} }
// check if an asl-rulebook2 Chapter H note is available
var aslrb2_url = null ;
var aslrb2_nat = nat ;
if ( [ "allied-minor", "axis-minor" ].indexOf( nat_type ) != -1 )
aslrb2_nat = nat_type ;
else {
var pos = aslrb2_nat.indexOf( "~" ) ;
if ( pos > 0 ) {
// NOTE: This is a derived nationality - use the base nationality.
aslrb2_nat = aslrb2_nat.substring( 0, pos ) ;
} else {
// check for K:FW vehicles/ordnance
pos = vo_entry.id.indexOf( "/" ) ;
if ( pos > 0 ) {
var nat2 = vo_entry.id.substring( 0, pos ) ;
if ( nat2 == "kfw-uro" || nat2 == "kfw-bcfk" || nat2 == "kfw-un-common")
aslrb2_nat = "un-forces" ;
else if ( nat2 == "kfw-kpa" || nat2 == "kfw-cpva" )
aslrb2_nat = "communist-forces" ;
}
}
}
var entries = is_landing_craft ? gAslRulebook2VoNoteTargets["landing-craft"] : gAslRulebook2VoNoteTargets[aslrb2_nat] && gAslRulebook2VoNoteTargets[aslrb2_nat][vo_type] ;
if ( entries ) {
var key = vo_note_key ;
if ( is_landing_craft )
key = vo_note_key.substring( 3 ) ;
else {
var match = key.match( /^kfw-(un|un-common|comm):/ ) ;
if ( match )
key = key.substring( match[0].length ) ;
}
var aslrb2_entry = entries[ key ] ;
if ( aslrb2_entry )
aslrb2_url = gShowAslRulebook2VoNoteUrl.replace( "TARGET", aslrb2_entry.target ) ;
}
// add the specified vehicle/ordnance // add the specified vehicle/ordnance
// NOTE: We set a fixed height for the sortable2 entries (based on the CSS settings in tabs-ob.css), // NOTE: We set a fixed height for the sortable2 entries (based on the CSS settings in tabs-ob.css),
// so that the vehicle/ordnance images won't get truncated if there are a lot of them. // so that the vehicle/ordnance images won't get truncated if there are a lot of them.
@ -194,11 +234,10 @@ function do_add_vo( vo_type, player_no, vo_entry, vo_image_id, elite, custom_cap
"<div class='vo-capabilities'></div>", "<div class='vo-capabilities'></div>",
"</div>" "</div>"
] ; ] ;
var vo_note_key = get_vo_note_key( vo_entry ) ;
var vo_note = get_vo_note( vo_type, nat, vo_note_key ) ; var vo_note = get_vo_note( vo_type, nat, vo_note_key ) ;
var vo_note_image_url = null ; var vo_note_image_url = null ;
if ( vo_note ) { if ( vo_note ) {
if ( vo_note_key.substring( 0, 3 ) === "LC " ) if ( is_landing_craft )
vo_note_image_url = make_app_url( "/" + vo_type + "/landing-craft/note/" + vo_note_key.substring(3), true ) ; vo_note_image_url = make_app_url( "/" + vo_type + "/landing-craft/note/" + vo_note_key.substring(3), true ) ;
else else
vo_note_image_url = make_app_url( "/" + vo_type + "/" + nat + "/note/" + vo_note_key, true ) ; vo_note_image_url = make_app_url( "/" + vo_type + "/" + nat + "/note/" + vo_note_key, true ) ;
@ -206,7 +245,6 @@ function do_add_vo( vo_type, player_no, vo_entry, vo_image_id, elite, custom_cap
// NOTE: Note numbers seem to be distinct across all Allied Minor or all Axis Minor vehicles/ordnance, // NOTE: Note numbers seem to be distinct across all Allied Minor or all Axis Minor vehicles/ordnance,
// so if we don't find a note in a given nationality's normal vehicles/ordnance, we can get away with // so if we don't find a note in a given nationality's normal vehicles/ordnance, we can get away with
// just checking their corresponding common vehicles/ordnance. // just checking their corresponding common vehicles/ordnance.
var nat_type = gTemplatePack.nationalities[ nat ].type ;
if ( ["allied-minor","axis-minor"].indexOf( nat_type ) !== -1 ) { if ( ["allied-minor","axis-minor"].indexOf( nat_type ) !== -1 ) {
vo_note = get_vo_note( vo_type, nat_type, vo_note_key ) ; vo_note = get_vo_note( vo_type, nat_type, vo_note_key ) ;
if ( vo_note ) if ( vo_note )
@ -224,8 +262,16 @@ function do_add_vo( vo_type, player_no, vo_entry, vo_image_id, elite, custom_cap
data.vo_note = vo_note ; data.vo_note = vo_note ;
data.vo_note_image_url = vo_note_image_url ; data.vo_note_image_url = vo_note_image_url ;
} }
if ( aslrb2_url ) {
buf.push(
"<a href='" + aslrb2_url + "' class='aslrb2'>",
"<img src='" + gImagesBaseUrl + "/aslrb2.png' class='aslrb2' title='Chapter H'>",
"</a>"
) ;
}
buf.push( "</div>" ) ; buf.push( "</div>" ) ;
var $content = $( buf.join("") ) ; var $content = $( buf.join("") ) ;
fixup_external_links( $content, true ) ;
var $entry = $sortable2.sortable2( "add", { var $entry = $sortable2.sortable2( "add", {
content: $content, content: $content,
data: data, data: data,

@ -126,6 +126,8 @@ gImagesBaseUrl = "{{url_for('static',filename='images')}}" ;
gAppConfigUrl = "{{url_for('get_app_config')}}" ; gAppConfigUrl = "{{url_for('get_app_config')}}" ;
gGetStartupMsgsUrl = "{{url_for('get_startup_msgs')}}" ; gGetStartupMsgsUrl = "{{url_for('get_startup_msgs')}}" ;
gGetTemplatePackUrl = "{{url_for('get_template_pack')}}" ; gGetTemplatePackUrl = "{{url_for('get_template_pack')}}" ;
gGetAslRulebook2VoNoteTargetsUrl = "{{url_for('get_asl_rulebook2_vo_note_targets')}}" ;
gShowAslRulebook2VoNoteUrl = "{{url_for('show_asl_rulebook2_target',target='TARGET')}}" ;
gGetDefaultScenarioUrl = "{{url_for('get_default_scenario')}}" ; gGetDefaultScenarioUrl = "{{url_for('get_default_scenario')}}" ;
gVehicleListingsUrl = "{{url_for('get_vehicle_listings',merge_common=1)}}" ; gVehicleListingsUrl = "{{url_for('get_vehicle_listings',merge_common=1)}}" ;
gOrdnanceListingsUrl = "{{url_for('get_ordnance_listings',merge_common=1)}}" ; gOrdnanceListingsUrl = "{{url_for('get_ordnance_listings',merge_common=1)}}" ;

@ -156,6 +156,7 @@ class ControlTestsServicer( BaseControlTestsServicer ): #pylint: disable=too-man
self.setAppConfigVal( SetAppConfigValRequest( key="DISABLE_DOWNLOADED_FILES", boolVal=True ), ctx ) self.setAppConfigVal( SetAppConfigValRequest( key="DISABLE_DOWNLOADED_FILES", boolVal=True ), ctx )
self.setAppConfigVal( SetAppConfigValRequest( key="DISABLE_LOCAL_ASA_INDEX_UPDATES", boolVal=True ), ctx ) self.setAppConfigVal( SetAppConfigValRequest( key="DISABLE_LOCAL_ASA_INDEX_UPDATES", boolVal=True ), ctx )
self.setAppConfigVal( SetAppConfigValRequest( key="DISABLE_LFA_HOTNESS_FADEIN", boolVal=True ), ctx ) self.setAppConfigVal( SetAppConfigValRequest( key="DISABLE_LFA_HOTNESS_FADEIN", boolVal=True ), ctx )
self.deleteAppConfigVal( DeleteAppConfigValRequest( key="ASL_RULEBOOK2_BASE_URL" ), ctx )
self.deleteAppConfigVal( DeleteAppConfigValRequest( key="ALTERNATE_WEBAPP_BASE_URL" ), ctx ) self.deleteAppConfigVal( DeleteAppConfigValRequest( key="ALTERNATE_WEBAPP_BASE_URL" ), ctx )
# NOTE: The webapp has been reconfigured, but the client must reloaed the home page # NOTE: The webapp has been reconfigured, but the client must reloaed the home page
# with "?force-reinit=1", to force it to re-initialize with the new settings. # with "?force-reinit=1", to force it to re-initialize with the new settings.

@ -0,0 +1,60 @@
{
"german": {
"vehicles": {
"1": { "caption": "german/vehicles #1", "target": "gv:1" }
}
},
"russian": {
"ordnance": {
"2": { "caption": "russian/ordnance #2", "target": "ro:2" }
}
},
"allied-minor": {
"vehicles": {
"1": { "caption": "dutch/vehicles #1", "target": "dv:1" },
"101": { "caption": "allied-minor/vehicles #101", "target": "almv:101" }
}
},
"axis-minor": {
"ordnance": {
"4": { "caption": "romanian/ordnance #4", "target": "ro:4" },
"104": { "caption": "axis-minor/ordnance #104", "target": "axmo:104" }
}
},
"landing-craft": {
"1": { "caption": "landing-craft #1", "target": "lc:1" },
"2": { "caption": "landing-craft #2", "target": "lc:2" }
},
"chinese": {
"vehicles": {
"1": { "caption": "chinese/vehicles #1", "target": "chv:1" }
}
},
"un-forces": {
"vehicles": {
"5": { "caption": "un-forces/vehicles #5", "target": "kfw-un:5" },
"6": { "caption": "un-forces/vehicles #6", "target": "kfw-un:6" }
},
"ordnance": {
"7": { "caption": "un-forces/ordnance #7", "target": "kfw-un:7" },
"8": { "caption": "un-forces/ordnance #8", "target": "kfw-un:8" }
}
},
"communist-forces": {
"vehicles": {
"15": { "caption": "communist-forces/vehicles #15", "target": "kfw-comm:15" }
},
"ordnance": {
"16": { "caption": "communist-forces/ordnance #16", "target": "kfw-comm:16" }
}
}
}

@ -81,6 +81,10 @@
"type": "axis-minor" "type": "axis-minor"
}, },
"kfw-kpa": {
"display_name": "North Korean",
"ob_colors": [ "OBCOL:kfw-kpa","OBCOL2:kfw-kpa", "OBCOL-BORDER:kfw-kpa" ]
},
"kfw-cpva": { "kfw-cpva": {
"display_name": "Communist Chinese", "display_name": "Communist Chinese",
"ob_colors": [ "OBCOL:kfw-cpva","OBCOL2:kfw-cpva", "OBCOL-BORDER:kfw-cpva" ] "ob_colors": [ "OBCOL:kfw-cpva","OBCOL2:kfw-cpva", "OBCOL-BORDER:kfw-cpva" ]

@ -0,0 +1,8 @@
[
{ "name": "kfw british ordnance",
"note_number": "7",
"id": "kfw-bcfk/o:7"
}
]

@ -0,0 +1,8 @@
[
{ "name": "cpva ordnance",
"note_number": "16",
"id": "kfw-cpva/o:016"
}
]

@ -0,0 +1,8 @@
[
{ "name": "kfw common ordnance",
"note_number": "8\u2020",
"id": "kfw-un-common/o:008"
}
]

@ -0,0 +1,8 @@
[
{ "name": "kpa vehicle",
"note_number": "15",
"id": "kfw-kpa/v:015"
}
]

@ -0,0 +1,8 @@
[
{ "name": "kfw common vehicle",
"note_number": "6\u2020",
"id": "kfw-un-common/v:006"
}
]

@ -0,0 +1,8 @@
[
{ "name": "kfw us vehicle",
"note_number": "5",
"id": "kfw-uro/v:005"
}
]

@ -1,6 +1,7 @@
[ [
{ "name": "landing craft", { "name": "landing craft",
"note_number": "1",
"notes": [ "A" ], "notes": [ "A" ],
"id": "sh/v:000", "id": "sh/v:000",
"gpid": [ 399, 397 ] "gpid": [ 399, 397 ]

@ -0,0 +1,117 @@
""" Test integration with asl-rulebook2. """
import os
from vasl_templates.webapp.tests.utils import init_webapp, find_child, find_children
from vasl_templates.webapp.tests.test_scenario_persistence import load_scenario
# ---------------------------------------------------------------------
def test_chapter_h( webapp, webdriver ):
"""Test links to Chapter H vehicle/ordnance notes."""
# initialize
webapp.control_tests.set_app_config_val( "ASL_RULEBOOK2_BASE_URL",
os.path.join( os.path.dirname(__file__), "fixtures/asl-rulebook2/vo-note-targets.json" )
)
init_webapp( webapp, webdriver, scenario_persistence=1 )
base_url = "{}/asl-rulebook2/".format( webapp.base_url )
# test normal vehicles/ordnance
load_scenario( {
"PLAYER_1": "german",
"OB_VEHICLES_1": [ { "name": "a german vehicle" }, { "name": "another german vehicle" } ],
"PLAYER_2": "russian",
"OB_ORDNANCE_2": [ { "name": "a russian ordnance" }, { "name": "another russian ordnance" } ],
} )
urls = _unload_aslrb2_urls( base_url )
assert urls == [
[ [ "gv:1", None ], [] ],
[ [], [ None, "ro:2" ] ]
]
# test Allied/Axis Minor vehicles/ordnance
load_scenario( {
"PLAYER_1": "dutch",
"OB_VEHICLES_1": [ { "name": "dutch vehicle" }, { "name": "common allied minor vehicle" } ],
"PLAYER_2": "romanian",
"OB_ORDNANCE_2": [ { "name": "romanian ordnance" }, { "name": "common axis minor ordnance" } ],
} )
urls = _unload_aslrb2_urls( base_url )
assert urls == [
[ [ "dv:1", "almv:101" ], [] ],
[ [], [ "ro:4", "axmo:104", ] ]
]
# test Landing Craft
load_scenario( {
"PLAYER_1": "american",
"OB_VEHICLES_1": [ { "name": "landing craft" } ],
"PLAYER_2": "japanese",
"OB_VEHICLES_2": [ { "name": "Daihatsu" } ],
} )
urls = _unload_aslrb2_urls( base_url )
assert urls == [
[ [ "lc:1" ], [] ],
[ [ "lc:2" ], [] ]
]
# test derived nationalities
load_scenario( {
"PLAYER_1": "chinese~gmd",
"OB_VEHICLES_1": [ { "name": "a chinese vehicle" } ],
} )
urls = _unload_aslrb2_urls( base_url )
assert urls == [
[ ["chv:1"], [] ],
[ [], [] ]
]
# test K:FW (UN Forces)
load_scenario( {
"PLAYER_1": "american",
"OB_VEHICLES_1": [ { "name": "kfw us vehicle" }, { "name": "kfw common vehicle" } ],
"PLAYER_2": "british",
"OB_ORDNANCE_2": [ { "name": "kfw british ordnance" }, { "name": "kfw common ordnance" } ],
} )
urls = _unload_aslrb2_urls( base_url )
assert urls == [
[ ["kfw-un:5","kfw-un:6"], [] ],
[ [], ["kfw-un:7","kfw-un:8"] ]
]
# test K:FW (Communist Forces)
load_scenario( {
"PLAYER_1": "kfw-kpa",
"OB_VEHICLES_1": [ { "name": "kpa vehicle" } ],
"PLAYER_2": "kfw-cpva",
"OB_ORDNANCE_2": [ { "name": "cpva ordnance" } ],
} )
urls = _unload_aslrb2_urls( base_url )
assert urls == [
[ ["kfw-comm:15"], [] ],
[ [], ["kfw-comm:16"] ]
]
# ---------------------------------------------------------------------
def _unload_aslrb2_urls( base_url ):
"""Unload the URL's to the asl-rulebook2 vehicle/ordnance notes."""
urls = [
[ [], [] ],
[ [], [] ]
]
for player_no in (1,2):
for vo_type_index, vo_type in enumerate(["vehicles","ordnance"]):
sortable = find_child( "#ob_{}-sortable_{}".format( vo_type, player_no ) )
urls2 = urls[ player_no-1 ][ vo_type_index ]
for vo_entry in find_children( ".vo-entry", sortable ):
link = find_child( "a.aslrb2", vo_entry )
if link:
url = link.get_attribute( "href" )
if url.startswith( base_url ):
url = url[ len(base_url): ]
else:
url = None
urls2.append( url )
return urls

@ -4,17 +4,22 @@
import os import os
import io import io
import re import re
import json
import copy import copy
import logging import logging
import urllib.request
from collections import defaultdict from collections import defaultdict
from flask import request, render_template, jsonify, send_file, abort, Response, url_for from flask import request, render_template, jsonify, send_file, abort, redirect, Response, url_for
from vasl_templates.webapp import app, globvars from vasl_templates.webapp import app, globvars
from vasl_templates.webapp.files import FileServer from vasl_templates.webapp.files import FileServer
from vasl_templates.webapp.webdriver import WebDriver from vasl_templates.webapp.webdriver import WebDriver
from vasl_templates.webapp.utils import read_text_file, resize_image_response, is_image_file, is_empty_file from vasl_templates.webapp.utils import read_text_file, resize_image_response, is_image_file, is_empty_file
_asl_rulebook2_targets = None
_asl_rulebook2_target_url_template = None
# --------------------------------------------------------------------- # ---------------------------------------------------------------------
@app.route( "/vehicles/notes" ) @app.route( "/vehicles/notes" )
@ -351,3 +356,44 @@ def get_vo_notes_report( nat, vo_type ):
NATIONALITY = nat, NATIONALITY = nat,
VO_TYPE = vo_type VO_TYPE = vo_type
) )
# ---------------------------------------------------------------------
@app.route( "/asl-rulebook2/vo-note-targets" )
def get_asl_rulebook2_vo_note_targets():
"""Return the Chapter H vehicle/ordnance note targets."""
if not _asl_rulebook2_targets:
abort( 404 )
return jsonify( _asl_rulebook2_targets )
@app.route( "/asl-rulebook2/<path:target>" )
def show_asl_rulebook2_target( target ):
"""Show the specified asl-rulebook2 target."""
base_url = app.config.get( "ASL_RULEBOOK2_BASE_URL" )
if not base_url:
abort( 404 )
url = "{}?target={}".format( base_url, target )
return redirect( url, code=307 )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
def load_asl_rulebook2_vo_note_targets( msg_store ):
"""Load the Chapter H vehicle/ordnance note targets."""
global _asl_rulebook2_targets, _asl_rulebook2_target_url_template
_asl_rulebook2_targets = _asl_rulebook2_target_url_template = None
base_url = app.config.get( "ASL_RULEBOOK2_BASE_URL" )
if not base_url:
return
try:
if os.path.isfile( base_url ):
fp = open( base_url, "r", encoding="utf-8" )
else:
fp = urllib.request.urlopen( base_url + "/vo-note-targets" )
_asl_rulebook2_targets = json.load( fp )
except Exception as ex: #pylint: disable=broad-except
msg = str( getattr(ex,"reason",None) or ex )
msg_store.warning( "Couldn't get the ASL Rulebook2 Chapter H targets: {}".format( msg ) )
return
_asl_rulebook2_target_url_template = app.config.get( "ASL_RULEBOOK2_TARGET_URL_TEMPLATE",
base_url + "/chapter-h/{NAT}/{VO-TYPE}/{ID}"
)

Loading…
Cancel
Save