diff --git a/vasl_templates/webapp/data/default-template-pack/extras/kgs/grenade-bundles.j2 b/vasl_templates/webapp/data/default-template-pack/extras/kgs/grenade-bundles.j2 index 9388b4f..c24ce4b 100644 --- a/vasl_templates/webapp/data/default-template-pack/extras/kgs/grenade-bundles.j2 +++ b/vasl_templates/webapp/data/default-template-pack/extras/kgs/grenade-bundles.j2 @@ -18,7 +18,7 @@ font-size: 105% ; font-weight: bold ; "> {# Some versions of Java require tags to have the width and height specified!?! #} - {%if PLAYER_FLAGS["german"]%} {%endif%}Grenade Bundles + {%if PLAYER_FLAGS["german"]%} {%endif%}Grenade Bundles diff --git a/vasl_templates/webapp/data/default-template-pack/extras/kgs/molotov-cocktails.j2 b/vasl_templates/webapp/data/default-template-pack/extras/kgs/molotov-cocktails.j2 index 47ff02b..77b8e19 100644 --- a/vasl_templates/webapp/data/default-template-pack/extras/kgs/molotov-cocktails.j2 +++ b/vasl_templates/webapp/data/default-template-pack/extras/kgs/molotov-cocktails.j2 @@ -18,7 +18,7 @@ font-size: 105% ; font-weight: bold ; "> {# Some versions of Java require tags to have the width and height specified!?! #} - {%if PLAYER_FLAGS["german"]%} {%endif%}Molotov Cocktails + {%if PLAYER_FLAGS["german"]%} {%endif%}Molotov Cocktails diff --git a/vasl_templates/webapp/data/default-template-pack/player_flag.include b/vasl_templates/webapp/data/default-template-pack/player_flag.include index fbc38c7..4424b4f 100644 --- a/vasl_templates/webapp/data/default-template-pack/player_flag.include +++ b/vasl_templates/webapp/data/default-template-pack/player_flag.include @@ -1,2 +1,2 @@ {# Some versions of Java require tags to have the width and height specified!?! #} -{%if PLAYER_FLAG%} {%endif%} +{%if PLAYER_FLAG%} {%endif%} diff --git a/vasl_templates/webapp/data/default-template-pack/player_flag_large.include b/vasl_templates/webapp/data/default-template-pack/player_flag_large.include index 62d9c76..50b1a6c 100644 --- a/vasl_templates/webapp/data/default-template-pack/player_flag_large.include +++ b/vasl_templates/webapp/data/default-template-pack/player_flag_large.include @@ -1,2 +1,2 @@ {# Some versions of Java require tags to have the width and height specified!?! #} -{%if PLAYER_FLAG%} {%endif%} +{%if PLAYER_FLAG%} {%endif%} diff --git a/vasl_templates/webapp/data/default-template-pack/players.j2 b/vasl_templates/webapp/data/default-template-pack/players.j2 index 5e435f6..786acf7 100644 --- a/vasl_templates/webapp/data/default-template-pack/players.j2 +++ b/vasl_templates/webapp/data/default-template-pack/players.j2 @@ -26,7 +26,7 @@ td.description { font-size: 90% ; font-style: italic ; color: #808080 ; } {# Some versions of Java require tags to have the width and height specified!?! #} - {%if PLAYER_FLAG_1%} {%endif%} + {%if PLAYER_FLAG_1%} {%endif%} {{PLAYER_1_NAME}}:   ELR: {{PLAYER_1_ELR}}   SAN: {{PLAYER_1_SAN}} @@ -39,7 +39,7 @@ td.description { font-size: 90% ; font-style: italic ; color: #808080 ; } {# Some versions of Java require tags to have the width and height specified!?! #} - {%if PLAYER_FLAG_2%} {%endif%} + {%if PLAYER_FLAG_2%} {%endif%} {{PLAYER_2_NAME}}:   ELR: {{PLAYER_2_ELR}}   SAN: {{PLAYER_2_SAN}} diff --git a/vasl_templates/webapp/snippets.py b/vasl_templates/webapp/snippets.py index f3d7744..fd0cf30 100644 --- a/vasl_templates/webapp/snippets.py +++ b/vasl_templates/webapp/snippets.py @@ -191,13 +191,27 @@ def make_snippet_image(): def get_flag( nat ): """Get a flag image.""" + # NOTE: Serving flag images should be so easy :-/ Normally, we would just return the appropriate image file, + # and let the client resize it to whatever it wants. However, VASSAL does a fairly bad job of this, so we allow + # the client to specify a preferred height, and we resize the image ourself. This gives slightly better results + # (although there's only so much you can do when your images are 11x11 :-/), but it's slow, and there are still + # some that don't look great (e.g. the German flag), so we allow the client to specify a preferred height, and + # if we have a prepared file of that size, we just return that directly. + # The downside of all this tomfoolery is when images are being downloaded from the internet, since the server + # needs to handle pre-sized files, based on a query parameter. The RewriteRule is funky, but it works :-/ + # NOTE: We could insert the preferred size into the URL (e.g. "$/flags/11/german"), but this takes control away + # from the templates wrt what goes into the labels, and won't work for custom flag URL's. It's probably cleaner + # and safer over the longer term to just have a single URL for each flag, and tweak it with something that + # won't break things if it's not there (i.e. a query parameter). At worst, the default image will be served + # and things will just look a bit bad, but it won't 404 :-/ + # initialize if not re.search( "^[-a-z~]+$", nat ): abort( 404 ) key = "flags:{}".format( nat ) - # NOTE: Most of the flags are at the larger size, so we default to that size (since we get better results - # doing that, and scaling down to the smaller size as needed, rather than the other way around). - height = app.config.get( "DEFAULT_FLAG_HEIGHT", 13 ) + height = int( request.args.get( "prefh", + app.config.get( "DEFAULT_FLAG_HEIGHT", 13 ) + ) ) # check if a custom flag has been configured if globvars.template_pack: @@ -205,16 +219,24 @@ def get_flag( nat ): if fname: if fname.startswith( ("http://","https://") ): with urllib.request.urlopen( fname ) as resp: - return _get_small_image( resp, key, height ) + return _get_resized_image( resp, key, height ) else: with open( fname, "rb" ) as fp: - return _get_small_image( fp, key, height ) + return _get_resized_image( fp, key, height ) # serve the standard flag - fname = os.path.join( "static/images/flags/", nat+".png" ) + # NOTE: Some flags don't reduce so well (e.g. German), so we allow for pre-reduced versions. + # This means that for labels that get images from the internet, we need some funky RewriteRule's + # on the online server, so that it can check the "height" query parameter, and serve the correct file. + # We could try to tweak image URL's so that the height is embedded in them (e.g. $/flags/11/german), + # but this is fiddly, and doesn't play well with custom flag URL's i.e. we're better off having + # a single base URL for each flag, and then tweaking it via query parameters. + fname = "static/images/flags/{}-{}.png".format( nat, height ) + if not os.path.isfile( os.path.join( app.root_path, fname ) ): + fname = "static/images/flags/{}.png".format( nat ) try: with app.open_resource( fname, "rb" ) as fp: - return _get_small_image( fp, key, height ) + return _get_resized_image( fp, key, height ) except FileNotFoundError: if nat in globvars.template_pack["nationalities"] and not request.args.get("no-spacer"): # NOTE: If the nationalitity is valid but has no flag, we return a spacer image, so that @@ -226,24 +248,21 @@ def get_flag( nat ): # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -_small_image_cache = {} -_small_image_cache_lock = threading.Lock() +_resized_image_cache = {} +_resized_image_cache_lock = threading.Lock() -def _get_small_image( fp, key, default_height ): - """Get a small image (cached).""" +def _get_resized_image( fp, key, height ): + """Get a resized image (cached).""" - # check how we should resize the image - # NOTE: Resizing images in the HTML snippets looks dreadful (presumably - # because VASSAL's HTML engine is so ancient), so we do it ourself :-/ - height = int( request.args.get( "height", default_height ) ) + # initialize if height <= 0: abort( 400 ) - with _small_image_cache_lock: + with _resized_image_cache_lock: # check if we have the image in the cache cache_key = ( key, height ) - if cache_key not in _small_image_cache: + if cache_key not in _resized_image_cache: # nope - load it img = Image.open( fp ) @@ -257,8 +276,8 @@ def _get_small_image( fp, key, default_height ): buf = io.BytesIO() img.save( buf, format="PNG" ) buf.seek( 0 ) - _small_image_cache[ cache_key ] = buf.read() + _resized_image_cache[ cache_key ] = buf.read() # return the flag image - img_data =_small_image_cache[ cache_key ] + img_data =_resized_image_cache[ cache_key ] return send_file( io.BytesIO(img_data), mimetype="image/png" ) diff --git a/vasl_templates/webapp/static/images/flags/american-11.png b/vasl_templates/webapp/static/images/flags/american-11.png new file mode 100644 index 0000000..1ae6f64 Binary files /dev/null and b/vasl_templates/webapp/static/images/flags/american-11.png differ diff --git a/vasl_templates/webapp/static/images/flags/free-french-11.png b/vasl_templates/webapp/static/images/flags/free-french-11.png new file mode 100644 index 0000000..80ee515 Binary files /dev/null and b/vasl_templates/webapp/static/images/flags/free-french-11.png differ diff --git a/vasl_templates/webapp/static/images/flags/german-11.png b/vasl_templates/webapp/static/images/flags/german-11.png new file mode 100644 index 0000000..0fcea0d Binary files /dev/null and b/vasl_templates/webapp/static/images/flags/german-11.png differ diff --git a/vasl_templates/webapp/static/images/flags/italian-11.png b/vasl_templates/webapp/static/images/flags/italian-11.png new file mode 100644 index 0000000..71bd46d Binary files /dev/null and b/vasl_templates/webapp/static/images/flags/italian-11.png differ diff --git a/vasl_templates/webapp/static/snippets.js b/vasl_templates/webapp/static/snippets.js index 93903d3..9a0271b 100644 --- a/vasl_templates/webapp/static/snippets.js +++ b/vasl_templates/webapp/static/snippets.js @@ -136,13 +136,12 @@ function make_snippet( $btn, params, extra_params, show_date_warnings ) params.SNIPPET_FONT_SIZE = gUserSettings["snippet-font-size"] ; if ( gUserSettings["custom-list-bullets"] ) params.CUSTOM_LIST_BULLETS = true ; - // some versions of Java require tags to have the width and height specified!?! - params.PLAYER_FLAG_SIZE = "width='11' height='11'" ; + params.PLAYER_FLAG_SIZE = 11 ; // FUDGE! A lot of labels use a larger font for their heading (e.g. V/O notes, PF, ATMM, etc.) and so // we would like to show a larger flag to match, or at least vertically center the flag. This would be // trivial to do with CSS, but VASSAL's HTML engine can't handle it, so we have to manually force // the flag to render at a larger size >:-/ - params.PLAYER_FLAG_SIZE_LARGE = "width='13' height='13'" ; + params.PLAYER_FLAG_SIZE_LARGE = 13 ; // set player-specific parameters var player_no ; diff --git a/vasl_templates/webapp/tests/test_online_images.py b/vasl_templates/webapp/tests/test_online_images.py index c184367..40efdc6 100644 --- a/vasl_templates/webapp/tests/test_online_images.py +++ b/vasl_templates/webapp/tests/test_online_images.py @@ -47,8 +47,8 @@ def test_online_images( webapp, webdriver ): # test player flags do_test( "players", - re.compile( r'