Compare commits

...

141 Commits
v1.8 ... master

Author SHA1 Message Date
Pacman Ghost 85616567f8 Updated the help. 2 months ago
Pacman Ghost f20693f8ae Added support for VASL 6.6.8 and VASSAL 3.7.9. 2 months ago
Pacman Ghost f87acbea56 Handle SIGTERM and shutdown gracefully. 2 months ago
Pacman Ghost 19002a03e5 Updated the version strings. 2 months ago
Pacman Ghost 396ebcef73 Allow ASL_RULEBOOK2_BASE_URL to be set from an env.var. 2 months ago
Pacman Ghost 24106fb7e5 Updated the documentation. 6 months ago
Pacman Ghost 2b4bc9045a Updated for VASL 6.6.7 and VASSAL 3.7.5. 6 months ago
Pacman Ghost 71b07accd8 Disable the context help button in the title bar (Windows). 7 months ago
Pacman Ghost acdb8351ef Added a link to the repo issues page in the About box. 7 months ago
Pacman Ghost 5606fe0d1a Show a better error message if Java is not configured. 7 months ago
Pacman Ghost cb0369b85a Show the "Program Info" menu item in the desktop program. 7 months ago
Pacman Ghost fdaf2f0cde Added logging for testing different VASSAL+VASL combinations. 7 months ago
Pacman Ghost bb075ef0da Tidied up some test fixtures. 7 months ago
Pacman Ghost a30cbbb616 Applied errata from ASLJ 13 for when the KMC get black OBA numbers. 7 months ago
Pacman Ghost 3e7daad138 Use blue counters for some French ordnance. 7 months ago
Pacman Ghost 2c6f0f2ba3 Updated the dependencies. 7 months ago
Pacman Ghost 127c5d46e0 Updated the dependencies. 8 months ago
Pacman Ghost 4df0f5cf77 Updated the version number to v1.12. 1 year ago
Pacman Ghost 8269917bee Updated the documentation 1 year ago
Pacman Ghost a274775bf7 Updated for VASSAL 3.6.14 and VASL 6.6.6. 1 year ago
Pacman Ghost 1c28ba4373 Show a better error message if the VASL data directory is not there. 2 years ago
Pacman Ghost bc87c398bb Added options to configure logging when running Docker. 2 years ago
Pacman Ghost 1e72a57d8d Added options to store data files outside a Docker container. 2 years ago
Pacman Ghost 8b8c3b2698 Fixed how external links in the help are opened. 2 years ago
Pacman Ghost 51a5bcee90 Booby Trap labels are now associated with a player nationality. 2 years ago
Pacman Ghost 6f070eb17a Correctly flag pieces from extensions as small. 2 years ago
Pacman Ghost 21d7aa2b68 Tweaked the display format for the Docker build timestamp. 2 years ago
Pacman Ghost 632e0e7e6d Tweaked a Trumbowyg icon. 2 years ago
Pacman Ghost 2c02163c46 Don't automatically create THH labels. 2 years ago
Pacman Ghost 20739d78de Updated the version strings. 2 years ago
Pacman Ghost 19734ac076 Updated for VASSAL 3.6.7 and VASL 6.6.5. 2 years ago
Pacman Ghost 85b625d54e Updated links to point to pacman-ghost.com. 2 years ago
Pacman Ghost 446a53b32f Fixed a possible timing error during startup. 2 years ago
Pacman Ghost c7a002b1c6 Fixed a test to work inside a Docker container with no internet access. 2 years ago
Pacman Ghost 8172fa7070 Allow the Canadians to generate a PIAT snippet. 2 years ago
Pacman Ghost 330d05e47d Don't show the loading spinner if Javascript is disabled. 2 years ago
Pacman Ghost b285a044ab Updated the documentation. 2 years ago
Pacman Ghost c555614ac6 Updated the examples. 2 years ago
Pacman Ghost 618fe3bd68 Tweaked a log message. 2 years ago
Pacman Ghost 0b720dc8bc Automatically set up basic logging for the desktop app. 2 years ago
Pacman Ghost 499e5645bc When loading a scenario, forget the previous .vsav file used. 2 years ago
Pacman Ghost fc3e1110f8 Worked around a layout problem when the Victory Conditions are long. 2 years ago
Pacman Ghost 8388cec67e Added large flags to the WYSIWYG editor's dropdown. 2 years ago
Pacman Ghost 569edbc48a Added shortcuts for Alt-Shift-< and >. 2 years ago
Pacman Ghost db7fecbc39 Optimized searching for scenarios. 2 years ago
Pacman Ghost 380dae5559 Merged the Extras templates for Kampfgruppe Scherer. 2 years ago
Pacman Ghost e5ad66658a Set focus to the correct default button if there are nested dialogs. 2 years ago
Pacman Ghost c5e1e53df4 Extended the files/directories monitored for Flask hot-reloading. 2 years ago
Pacman Ghost d00d809877 Don't reset the current directory for saving/loading files on "new scenario". 2 years ago
Pacman Ghost c4c2010170 Updated the National Capabilities label for the Free French. 2 years ago
Pacman Ghost c2e0b48343 Added Alt-Click handlers. 2 years ago
Pacman Ghost 0e0df4e3a6 Tightened up some tests. 2 years ago
Pacman Ghost d78ac34c1f Handle missing landing craft Chapter H notes. 2 years ago
Pacman Ghost 05933ad753 Reset the HTML editor controls each time they are used. 2 years ago
Pacman Ghost f6e5081605 Adjusted the layout of the SCENARIO panel. 2 years ago
Pacman Ghost b31f64ed7f Show an indicator when an HTML textbox goes multi-line. 2 years ago
Pacman Ghost 2d317c57bd Moved the "edit template" buttons into a drop-down menu. 2 years ago
Pacman Ghost 941439a2ae Allowed Extras templates to set the width of their dropdown's. 2 years ago
Pacman Ghost 071b6f587d Stopped incorrectly detecting "split MG" v/o comments as having been changed. 2 years ago
Pacman Ghost 437865b47d Improved time-based comments in the Axis Minor nat.caps. snippets. 2 years ago
Pacman Ghost 650a6f86d4 Grouped notes in Nationality Capabilities snippets. 2 years ago
Pacman Ghost 0682dc1dca Added an Extras template for Booby Traps. 2 years ago
Pacman Ghost 4ae19ca212 Tightened up how we detect if HTML content has been changed. 2 years ago
Pacman Ghost e7888e88e0 Cached V/O note images for extensions are now saved in their own sub-directory. 2 years ago
Pacman Ghost 1294d0e3d2 Store config and data files in the standard locations. 2 years ago
Pacman Ghost fbcf4e9184 Confirm closing the EDIT V/O dialog if changes have been made. 2 years ago
Pacman Ghost 6d261032be Improved the keyboard interface in the TURN TRACK dialog. 2 years ago
Pacman Ghost 4629b3421b Only show custom list bullets in the UI if they have been enabled. 2 years ago
Pacman Ghost 53e14f753f Allow single-line textbox's to be edited as HTML. 2 years ago
Pacman Ghost a09286bc50 Include the build git info in the SCENARIO template. 2 years ago
Pacman Ghost 4762a36eb6 Removed code supporting Internet Explorer. 2 years ago
Pacman Ghost 23256bbc63 Tightened up some tests. 2 years ago
Pacman Ghost 2628105ea9 Minor UI tweaks. 2 years ago
Pacman Ghost 77b1bc9548 Allow SSR snippets to be auto-generated. 2 years ago
Pacman Ghost ee4d8fbe02 Fixed a problem when auto-generating a simple note snippet with no content. 2 years ago
Pacman Ghost 2ee42f37b5 Tightened up the presentation of lists in the UI and snippets. 2 years ago
Pacman Ghost 15c632b522 Sanitize HTML content. 2 years ago
Pacman Ghost c420c168d1 Added a WYSIWYG editor for HTML content. 2 years ago
Pacman Ghost d5021f7960 Added the ASA and ROAR ID's to the SCENARIO template. 2 years ago
Pacman Ghost daef7c1c15 Gave VASSAL tests more time to run. 2 years ago
Pacman Ghost b10105f2a7 Improved the positioning and sizing of dialogs. 2 years ago
Pacman Ghost 6b909a37eb Changed how flags are resized. 2 years ago
Pacman Ghost 7e070c3b68 Update the UI after importing an ASA scenario. 2 years ago
Pacman Ghost 0312fa2fc7 Confirm closing the "add/edit simple note" dialog if changes have been made. 2 years ago
Pacman Ghost 95167f4888 Allow snippets to be generated from the "add/edit simple note" dialog. 2 years ago
Pacman Ghost 2a707863d2 Fixed a timing error during startup. 2 years ago
Pacman Ghost 13a1b511e6 Added splitters to make some UI elements resizable. 2 years ago
Pacman Ghost a556d22117 Got 1/2" counters showing at the smaller size again. 2 years ago
Pacman Ghost a52e7f8ba9 Added a splitter to the "edit vehicle/ordnance" dialog. 2 years ago
Pacman Ghost fa5a99e87c Changed how Java is detected (and reported) from the PATH. 2 years ago
Pacman Ghost 7f17a634eb Updated some icons, tightened up the UI. 2 years ago
Pacman Ghost fbc420d4b3 Tightened up the player flags. 2 years ago
Pacman Ghost feebe9f63c Disable snippet-width textbox's when disabling snippet buttons. 2 years ago
Pacman Ghost e479bf2a76 Removed the "Width:" labels from the UI. 2 years ago
Pacman Ghost 520ea43d9d Tidy-up strings coming from ROAR and ASA. 2 years ago
Pacman Ghost ff0f40b22b Tightened up how we map ASA theaters to our own. 2 years ago
Pacman Ghost 55c15e5157 Made the compass label part of the default template pack. 2 years ago
Pacman Ghost 757c78dbd8 Removed the text caption from some snippet buttons. 2 years ago
Pacman Ghost 1079ac7e60 Got the LFA tests going again in Firefox. 2 years ago
Pacman Ghost d165bfdefd Allow multiple levels of shading in the turn track. 2 years ago
Pacman Ghost 729c6e306d Reset the turn track when importing a scenario. 2 years ago
Pacman Ghost cd831446fd Allow turn track squares to be shaded. 2 years ago
Pacman Ghost 40c2b87cbe Added a new extras template for the compass. 2 years ago
Pacman Ghost bc724e426d Removed the option to create National Capabilities labels. 2 years ago
Pacman Ghost c850bbd281 Tweaked the presentation of the "VASSAL shim error" dialog. 2 years ago
Pacman Ghost 42cad6f87c Fixed a resizing problem in the "connect to ROAR" dialog. 2 years ago
Pacman Ghost c363acb73e Added more padding to dialogs. 2 years ago
Pacman Ghost c5cdaf27dd Return a spacer image as a flag for nationalities that don't have one. 2 years ago
Pacman Ghost 0966c08dd4 Added the turn track template. 2 years ago
Pacman Ghost 3a5e472b36 Updated dependencies. 2 years ago
Pacman Ghost f93888c51b Updated the version strings. 2 years ago
Pacman Ghost 786f35be9a Added the Swedish nationality. 2 years ago
Pacman Ghost cde6649918 Added support for VASL 6.6.4 and VASSAL 3.6.6. 2 years ago
Pacman Ghost 0cbce2182c Report the VASSAL and VASL versions when analyzing .vsav files. 2 years ago
Pacman Ghost 0ab71fb70e Added some more logging to the VASSAL shim. 2 years ago
Pacman Ghost 560f2e3e65 Default to showing images in snippets, and using custom list bullets. 2 years ago
Pacman Ghost 7a0c4044e4 Fixed an error caused by the VASL .vmod not loading properly. 2 years ago
Pacman Ghost 5d425f2ded Allow logging to a file during tests. 2 years ago
Pacman Ghost 22274a6183 Improved the help. 2 years ago
Pacman Ghost 0cbe6435cf Completely hide the UI controls if there are no vehicles/ordnance. 2 years ago
Pacman Ghost dad7dab770 Made a new VO_NOTE_IMAGE_URL_PATH parameter available to templates. 2 years ago
Pacman Ghost 114db959bd Minor tweaks to the templates. 2 years ago
Pacman Ghost b497aa6e0f Stop the DOS box from showing when we launch the webdriver. 2 years ago
Pacman Ghost 27bb528312 Updated the flags for the Allied/Axis Minor nationalities. 2 years ago
Pacman Ghost d8c9d20e2c Added some comments. 2 years ago
Pacman Ghost 6f1dbae5c8 Set the location of the geckodriver log file during tests. 2 years ago
Pacman Ghost ba8a2d425b Tightened up how the test suite skips certain versions of VASL. 2 years ago
Pacman Ghost 32efa5b1c7 Updated the Chapter H placeholders ZIP file. 2 years ago
Pacman Ghost 82ab463eab Use different backend webdriver's when running the test suite. 2 years ago
Pacman Ghost fe3d30d2e2 Added the Partisan nationality. 2 years ago
Pacman Ghost 38399c355f Allow VASL versions to be aliased. 2 years ago
Pacman Ghost 5c19af124a Got the embedded browser in the desktop app going again on Fedora 35. 2 years ago
Pacman Ghost 7c4e01eeec Allow URL's for downloaded artifacts for the Docker image to be overridden. 2 years ago
Pacman Ghost aeb3eaf5c8 Updated dependencies. 2 years ago
Pacman Ghost 4288125a7a Added some comments. 2 years ago
Pacman Ghost 44e4ff53dd Got accelerator underlines to show properly on Windows. 2 years ago
Pacman Ghost 1584988476 Show the Java version in the Program Info dialog. 2 years ago
Pacman Ghost dc8a05a78b Show the nationality colors as a palette in the LFA color-picker. 2 years ago
Pacman Ghost cbc86e6fe8 Tightened up the Docker build. 3 years ago
Pacman Ghost 2946b2d10f Use waitress to serve the webapp. 3 years ago
Pacman Ghost 2fc57b88ac Updated the version strings. 3 years ago
  1. 90
      .pylintrc
  2. 91
      Dockerfile
  3. 9
      README.md
  4. BIN
      chapter-h/chapter-h-placeholders.zip
  5. 76
      conftest.py
  6. 1
      docker/config/site.cfg
  7. 6
      docker/run.sh
  8. BIN
      examples/Hill 621 (Scenario E) (online).vsav
  9. 32
      examples/Hill 621 (Scenario E).json
  10. BIN
      examples/Hill 621 (Scenario E).png
  11. BIN
      examples/Hill 621 (Scenario E).small.jpg
  12. BIN
      examples/Hill 621 (Scenario E).vsav
  13. BIN
      examples/Hube's Pocket (Scenario G) (online).vsav
  14. 30
      examples/Hube's Pocket (Scenario G).json
  15. BIN
      examples/Hube's Pocket (Scenario G).png
  16. BIN
      examples/Hube's Pocket (Scenario G).small.jpg
  17. BIN
      examples/Hube's Pocket (Scenario G).vsav
  18. 2
      examples/README.md
  19. BIN
      examples/The Streets Of Stalingrad (Scenario C) (online).vsav
  20. 30
      examples/The Streets Of Stalingrad (Scenario C).json
  21. BIN
      examples/The Streets Of Stalingrad (Scenario C).png
  22. BIN
      examples/The Streets Of Stalingrad (Scenario C).small.jpg
  23. BIN
      examples/The Streets Of Stalingrad (Scenario C).vsav
  24. 4
      freeze.py
  25. 2
      loader/freeze.py
  26. 6
      loader/main.py
  27. 14
      requirements-dev.txt
  28. 15
      requirements.txt
  29. 105
      run-container.sh
  30. 4
      setup.py
  31. 9
      vasl_templates/about.py
  32. 19
      vasl_templates/file_dialog.py
  33. 60
      vasl_templates/main.py
  34. 21
      vasl_templates/main_window.py
  35. 4
      vasl_templates/server_settings.py
  36. 83
      vasl_templates/tools/get_piece_info.py
  37. 3
      vasl_templates/tools/tests/fixtures/chapter-h-placeholders.txt
  38. 49
      vasl_templates/ui/about.ui
  39. 2
      vasl_templates/ui/server_settings.ui
  40. 26
      vasl_templates/utils.py
  41. 4
      vasl_templates/web_channel.py
  42. 73
      vasl_templates/webapp/__init__.py
  43. 3
      vasl_templates/webapp/config/constants.py
  44. 4
      vasl_templates/webapp/config/logging.yaml.example
  45. 2
      vasl_templates/webapp/config/site.cfg.example
  46. 5
      vasl_templates/webapp/data/asl-scenario-archive.json
  47. 7
      vasl_templates/webapp/data/default-template-pack/atmm-romanian.j2
  48. 2
      vasl_templates/webapp/data/default-template-pack/atmm.j2
  49. 10
      vasl_templates/webapp/data/default-template-pack/baz-cpva16.j2
  50. 10
      vasl_templates/webapp/data/default-template-pack/baz-cpva17.j2
  51. 14
      vasl_templates/webapp/data/default-template-pack/baz.j2
  52. 14
      vasl_templates/webapp/data/default-template-pack/baz45.j2
  53. 14
      vasl_templates/webapp/data/default-template-pack/baz50.j2
  54. 2
      vasl_templates/webapp/data/default-template-pack/common.css
  55. 5
      vasl_templates/webapp/data/default-template-pack/compass.j2
  56. 41
      vasl_templates/webapp/data/default-template-pack/extras/booby-traps.j2
  57. 2
      vasl_templates/webapp/data/default-template-pack/extras/count-remaining.j2
  58. 4
      vasl_templates/webapp/data/default-template-pack/extras/grid.j2
  59. 2
      vasl_templates/webapp/data/default-template-pack/extras/kakazu-ridge-cave-complexes.j2
  60. 87
      vasl_templates/webapp/data/default-template-pack/extras/kgs.j2
  61. 49
      vasl_templates/webapp/data/default-template-pack/extras/kgs/grenade-bundles.j2
  62. 57
      vasl_templates/webapp/data/default-template-pack/extras/kgs/molotov-cocktails.j2
  63. 2
      vasl_templates/webapp/data/default-template-pack/extras/victory-points.j2
  64. 12
      vasl_templates/webapp/data/default-template-pack/mol-p.j2
  65. 6
      vasl_templates/webapp/data/default-template-pack/mol.j2
  66. 15
      vasl_templates/webapp/data/default-template-pack/nat_caps.j2
  67. 238
      vasl_templates/webapp/data/default-template-pack/national-capabilities.json
  68. 11
      vasl_templates/webapp/data/default-template-pack/nationalities.json
  69. 5
      vasl_templates/webapp/data/default-template-pack/ob_vo_note.css
  70. 19
      vasl_templates/webapp/data/default-template-pack/pf-finnish.j2
  71. 18
      vasl_templates/webapp/data/default-template-pack/pf-hungarian.j2
  72. 17
      vasl_templates/webapp/data/default-template-pack/pf-romanian.j2
  73. 4
      vasl_templates/webapp/data/default-template-pack/pf.j2
  74. 10
      vasl_templates/webapp/data/default-template-pack/piat.j2
  75. 2
      vasl_templates/webapp/data/default-template-pack/player_flag.include
  76. 2
      vasl_templates/webapp/data/default-template-pack/player_flag_large.include
  77. 4
      vasl_templates/webapp/data/default-template-pack/players.j2
  78. 10
      vasl_templates/webapp/data/default-template-pack/psk.j2
  79. 4
      vasl_templates/webapp/data/default-template-pack/scenario.j2
  80. 2
      vasl_templates/webapp/data/default-template-pack/ssr.j2
  81. 6
      vasl_templates/webapp/data/default-template-pack/thh.j2
  82. 116
      vasl_templates/webapp/data/default-template-pack/turn_track.j2
  83. 6
      vasl_templates/webapp/data/ordnance/french.json
  84. 26
      vasl_templates/webapp/data/ordnance/swedish.json
  85. 65
      vasl_templates/webapp/data/vasl-6.6.0/piece-info.json
  86. 65
      vasl_templates/webapp/data/vasl-6.6.1/piece-info.json
  87. 65
      vasl_templates/webapp/data/vasl-6.6.2/piece-info.json
  88. 65
      vasl_templates/webapp/data/vasl-6.6.3/piece-info.json
  89. 43
      vasl_templates/webapp/data/vasl-6.6.4/expected-multiple-images.json
  90. 2
      vasl_templates/webapp/data/vasl-6.6.4/online-counter-images.json
  91. 65
      vasl_templates/webapp/data/vasl-6.6.4/piece-info.json
  92. 147
      vasl_templates/webapp/data/vasl-6.6.4/vasl-overrides.json
  93. 49
      vasl_templates/webapp/data/vasl-6.6.5/expected-multiple-images.json
  94. 2
      vasl_templates/webapp/data/vasl-6.6.5/online-counter-images.json
  95. 65
      vasl_templates/webapp/data/vasl-6.6.5/piece-info.json
  96. 147
      vasl_templates/webapp/data/vasl-6.6.5/vasl-overrides.json
  97. 61
      vasl_templates/webapp/data/vasl-6.6.6/expected-multiple-images.json
  98. 2
      vasl_templates/webapp/data/vasl-6.6.6/online-counter-images.json
  99. 71
      vasl_templates/webapp/data/vasl-6.6.6/piece-info.json
  100. 147
      vasl_templates/webapp/data/vasl-6.6.6/vasl-overrides.json
  101. Some files were not shown because too many files have changed in this diff Show More

@ -54,88 +54,14 @@ confidence=
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=print-statement,
parameter-unpacking,
unpacking-in-except,
old-raise-syntax,
backtick,
long-suffix,
old-ne-operator,
old-octal-literal,
import-star-module-level,
non-ascii-bytes-literal,
invalid-unicode-literal,
disable=
raw-checker-failed,
bad-inline-option,
locally-disabled,
locally-enabled,
file-ignored,
suppressed-message,
useless-suppression,
deprecated-pragma,
apply-builtin,
basestring-builtin,
buffer-builtin,
cmp-builtin,
coerce-builtin,
execfile-builtin,
file-builtin,
long-builtin,
raw_input-builtin,
reduce-builtin,
standarderror-builtin,
unicode-builtin,
xrange-builtin,
coerce-method,
delslice-method,
getslice-method,
setslice-method,
no-absolute-import,
old-division,
dict-iter-method,
dict-view-method,
next-method-called,
metaclass-assignment,
indexing-exception,
raising-string,
reload-builtin,
oct-method,
hex-method,
nonzero-method,
cmp-method,
input-builtin,
round-builtin,
intern-builtin,
unichr-builtin,
map-builtin-not-iterating,
zip-builtin-not-iterating,
range-builtin-not-iterating,
filter-builtin-not-iterating,
using-cmp-argument,
eq-without-hash,
div-method,
idiv-method,
rdiv-method,
exception-message-attribute,
invalid-str-codec,
sys-max-int,
bad-python3-import,
deprecated-string-function,
deprecated-str-translate-call,
deprecated-itertools-function,
deprecated-types-field,
next-method-defined,
dict-items-not-iterating,
dict-keys-not-iterating,
dict-values-not-iterating,
deprecated-operator-function,
deprecated-urllib-function,
xreadlines-attribute,
deprecated-sys-function,
exception-escape,
comprehension-escape,
bad-whitespace,
bad-continuation,
invalid-name,
wrong-import-position,
global-statement,
@ -148,7 +74,10 @@ disable=print-statement,
import-outside-toplevel,
isinstance-second-argument-not-valid-type,
consider-using-f-string,
consider-using-max-builtin
consider-using-max-builtin,
use-implicit-booleaness-not-comparison,
unnecessary-lambda-assignment,
duplicate-string-formatting-argument,
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
@ -293,13 +222,6 @@ max-line-length=120
# Maximum number of lines in a module
max-module-lines=1000
# List of optional constructs for which whitespace checking is disabled. `dict-
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
# `empty-line` allows space-only lines.
no-space-check=trailing-comma,
dict-separator
# Allow the body of a class to be on the same line as the declaration if body
# contains single statement.
single-line-class-stmt=no
@ -558,4 +480,4 @@ known-third-party=enchant
# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception
overgeneral-exceptions=builtins.Exception

@ -1,77 +1,55 @@
# NOTE: Use the run-container.sh script to build and launch this container.
# We do a multi-stage build (requires Docker >= 17.05) to install everything, then copy it all
# to the final target image.
# NOTE: Multi-stage builds require Docker >= 17.05.
FROM rockylinux:9.1 AS base
FROM centos:8 AS base
# update packages and install requirements
RUN dnf -y upgrade-minimal && \
dnf install -y python3.11
# update packages
RUN dnf -y upgrade-minimal
# NOTE: We don't need the following stuff for the build step, but it's nice to not have to re-install
# it all every time we change the requirements :-/
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# install Java
RUN dnf install -y java-17-openjdk
# NOTE: We install the Python dependencies into a temporary intermediate stage, then copy everything over
# to the final image, because some modules (e.g. grpcio) need pre-requisites to be installed.
# This saves us about 300 MB for the final image and, importantly, adding a requirement doesn't cause us
# to re-install Java and Firefox below, when we start building the final image.
# install Firefox
# NOTE: We could install this using dnf, but the version of geckodriver needs to match it.
ARG FIREFOX_URL=https://ftp.mozilla.org/pub/firefox/releases/117.0.1/linux-x86_64/en-US/firefox-117.0.1.tar.bz2
RUN dnf install -y bzip2 xorg-x11-server-Xvfb gtk3 dbus-glib && \
curl -s "$FIREFOX_URL" | tar -jx -C /usr/local/ && \
ln -s /usr/local/firefox/firefox /usr/bin/firefox && \
echo "exclude=firefox" >>/etc/dnf/dnf.conf
FROM base AS build
# install geckodriver
ARG GECKODRIVER_URL=https://github.com/mozilla/geckodriver/releases/download/v0.33.0/geckodriver-v0.33.0-linux64.tar.gz
RUN curl -sL "$GECKODRIVER_URL" | tar -xz -C /usr/bin/
# install Python
# NOTE: The version of Python we want is newer than what's in Centos 8,
# so we have to install from source :-/
RUN dnf -y groupinstall "Development Tools" && \
dnf -y install openssl-devel bzip2-devel libffi-devel sqlite-devel
RUN cd /tmp && \
dnf -y install wget && \
wget https://www.python.org/ftp/python/3.8.7/Python-3.8.7.tgz && \
tar xvf Python-3.8.7.tgz && \
cd Python-3.8.7/ && \
./configure --enable-optimizations && \
make install
# clean up
RUN dnf clean all
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FROM base AS build
# set up a virtualenv
RUN python3 -m venv /opt/venv
RUN python3.11 -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN pip install --upgrade pip
# install the application requirements
COPY requirements.txt requirements-dev.txt ./
RUN pip3 install -r requirements.txt
COPY requirements.txt requirements-dev.txt /tmp/
RUN pip3 install -r /tmp/requirements.txt
ARG CONTROL_TESTS_PORT
RUN if [ -n "$CONTROL_TESTS_PORT" ]; then \
dnf install -y gcc-c++ python3-devel && \
pip3 install -r requirements-dev.txt \
pip3 install -r /tmp/requirements-dev.txt \
; fi
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FROM base
# copy the Python installation from the build image
COPY --from=build /usr/local/bin/python3.8 /usr/local/bin/python3.8
COPY --from=build /usr/local/lib/python3.8 /usr/local/lib/python3.8
COPY --from=build /usr/local/bin/pip3 /usr/local/bin/pip3
RUN ln -s /usr/local/bin/python3.8 /usr/local/bin/python3
# install Java
RUN url="https://download.java.net/java/GA/jdk15.0.1/51f4f36ad4ef43e39d0dfdbaf6549e32/9/GPL/openjdk-15.0.1_linux-x64_bin.tar.gz" ; \
curl -s "$url" | tar -C /usr/bin/ -xz
# install Firefox
RUN dnf install -y wget bzip2 xorg-x11-server-Xvfb gtk3 dbus-glib && \
wget -qO- "https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=en-US" \
| tar -C /usr/local/ -jx && \
ln -s /usr/local/firefox/firefox /usr/bin/firefox && \
echo "exclude=firefox" >>/etc/dnf/dnf.conf
# install geckodriver
RUN url=$( curl -s https://api.github.com/repos/mozilla/geckodriver/releases/latest | grep -Poh 'https.*linux64\.tar\.gz(?!\.)' ) && \
curl -sL "$url" | tar -C /usr/bin/ -xz
# clean up
RUN dnf clean all
# install the application requirements
# copy the virtualenv from the build image
COPY --from=build /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
@ -95,6 +73,13 @@ COPY docker/config/ ./vasl_templates/webapp/config/
RUN useradd --create-home app
USER app
# FUDGE! We need this to stop spurious warning messages:
# Fork support is only compatible with the epoll1 and poll polling strategies
# Setting the verbosity to ERROR should suppress these, but doesn't :-/
# https://github.com/grpc/grpc/issues/17253
# https://github.com/grpc/grpc/blob/master/doc/environment_variables.md
ENV GRPC_VERBOSITY=NONE
# run the application
EXPOSE 5010
COPY docker/run.sh ./

@ -1,16 +1,14 @@
# VASL Templates
<a href="https://github.com/pacman-ghost/vasl-templates/raw/master/vasl_templates/webapp/static/help/images/hill-621.png" target="_blank">
<img src="https://github.com/pacman-ghost/vasl-templates/raw/master/vasl_templates/webapp/static/help/images/hill-621.small.png" width="200" align="right" hspace="10">
</a>
[<img src="vasl_templates/webapp/static/help/images/hill-621.small.png" width="200" align="right" hspace="10">](vasl_templates/webapp/static/help/images/hill-621.png)
*VASL Templates* makes it easy to set up attractive VASL scenarios, with loads of useful information embedded to assist with game play.
Simply enter the scenario information into the UI, and the program will generate HTML snippets that you can transfer into VASL labels in your scenario.
<img src="https://github.com/pacman-ghost/vasl-templates/raw/master/vasl_templates/webapp/static/help/images/ob_setup.png" width="200">
[<img src="vasl_templates/webapp/static/help/images/ob_setup.png" width="200">](vasl_templates/webapp/static/help/images/ob_setup.png)
You can find more examples of the program in action [here](https://github.com/pacman-ghost/vasl-templates/tree/master/examples/).
You can find more examples of the program in action [here](examples/).
### Documentation
@ -20,3 +18,4 @@ You can find more examples of the program in action [here](https://github.com/pa
* [Setting up Chapter H data](https://vasl-templates.org/help?tab=chapterh)
* [Writing your own templates](https://vasl-templates.org/help?tab=templatepacks)
* [For developers](https://vasl-templates.org/help?tab=fordevelopers)
* [FAQ](https://vasl-templates.org/FAQ)

@ -1,17 +1,16 @@
""" pytest support functions. """
import os
import shutil
import threading
import json
import re
import logging
import tempfile
import logging
import urllib.request
from urllib.error import URLError
import pytest
from flask import url_for
from vasl_templates.webapp import app
from vasl_templates.webapp.tests import utils
from vasl_templates.webapp.tests.control_tests import ControlTests
@ -19,6 +18,7 @@ from vasl_templates.webapp.tests.control_tests import ControlTests
FLASK_WEBAPP_PORT = 5011
_pytest_options = None
_orig_url_for = app.url_for
# ---------------------------------------------------------------------
@ -42,7 +42,7 @@ def pytest_addoption( parser ):
help="Run the tests headless."
)
parser.addoption(
"--window-size", action="store", dest="window_size", default="1000x700",
"--window-size", action="store", dest="window_size", default="1020x700",
help="Browser window size."
)
@ -70,6 +70,13 @@ def pytest_configure( config ):
import vasl_templates.webapp.tests
vasl_templates.webapp.tests.pytest_options = config.option
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@pytest.fixture( scope="session" )
def monkeypatch():
"""Override the default monkeypatch fixture."""
assert False, "Don't use monkeypatch!" # it won't work when testing against a remote server
# ---------------------------------------------------------------------
_webapp = None
@ -100,7 +107,7 @@ def _make_webapp():
if webapp_url and not webapp_url.startswith( "http://" ):
webapp_url = "http://" + webapp_url
app.base_url = webapp_url if webapp_url else "http://localhost:{}".format( FLASK_WEBAPP_PORT )
logging.disable( logging.CRITICAL )
_disable_console_logging()
# initialize
# WTF?! https://github.com/pallets/flask/issues/824
@ -122,7 +129,9 @@ def _make_webapp():
# NOTE: It's not a bad idea to bypass the clipboard, even when running in a browser,
# to avoid problems if something else uses the clipboard while the tests are running.
kwargs["store_clipboard"] = 1
url = url_for( endpoint, _external=True, **kwargs )
if kwargs.get( "_external" ) is None:
kwargs["_external"] = True
url = _orig_url_for( endpoint, **kwargs )
url = url.replace( "http://localhost", app.base_url )
return url
app.url_for = make_webapp_url
@ -147,7 +156,8 @@ def _make_webapp():
def is_ready():
"""Try to connect to the webapp server."""
try:
with urllib.request.urlopen( app.url_for("ping") ) as resp:
url = app.url_for( "ping" )
with urllib.request.urlopen( url ) as resp:
assert resp.read().startswith( b"pong: " )
return True
except URLError:
@ -172,6 +182,17 @@ def _make_webapp():
addr = "{}:{}".format( mo.group(1), port_no )
app.control_tests = ControlTests( addr )
# NOTE: We set the back-end webdriver to be the of the same type (Firefox or Chrome) as the browser
# being used to drive the tests, which, strictly speaking, doesn't make sense, since the two things
# don't have anything to do with each other. However, this is a convenient way to switch the backend
# webdriver's and exercise both of them. The webdriver binary must be on the path, but if it's not,
# we won't have even got this far, since it needs to be there to drive the browser.
# NOTE: This will have no effect if we're talking to a remote server, but we can live with that.
if _pytest_options.webdriver == "firefox":
app.config[ "WEBDRIVER_PATH" ] = shutil.which( "geckodriver" )
elif _pytest_options.webdriver == "chrome":
app.config[ "WEBDRIVER_PATH" ] = shutil.which( "chromedriver" )
return app
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -179,7 +200,7 @@ def _make_webapp():
@pytest.fixture( scope="session" )
def test_client():
"""Return a test client that can be used to connect to the webapp."""
logging.disable( logging.CRITICAL )
_disable_console_logging()
return app.test_client()
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -198,26 +219,19 @@ def webdriver( request ):
driver = request.config.getoption( "--webdriver" )
from selenium import webdriver as wb
if driver == "firefox":
options = wb.FirefoxOptions()
options.headless = _pytest_options.headless
driver = wb.Firefox(
options = options,
service_log_path = os.path.join( tempfile.gettempdir(), "geckodriver.log" )
service = wb.firefox.service.Service(
log_output = os.path.join( tempfile.gettempdir(), "webdriver-pytest.log" )
)
options = wb.FirefoxOptions()
if _pytest_options.headless:
options.add_argument( "--headless" )
driver = wb.Firefox( options=options, service=service )
elif driver == "chrome":
options = wb.ChromeOptions()
options.headless = _pytest_options.headless
if _pytest_options.headless:
options.add_argument( "--headless" )
options.add_argument( "--disable-gpu" )
driver = wb.Chrome( options=options )
elif driver == "ie":
# NOTE: IE11 requires a registry key to be set:
# https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver#required-configuration
options = wb.IeOptions()
if _pytest_options.headless:
raise RuntimeError( "IE WebDriver cannot be run headless." )
options.IntroduceInstabilityByIgnoringProtectedModeSettings = True
options.EnsureCleanSession = True
driver = wb.Ie( ie_options=options )
else:
raise RuntimeError( "Unknown webdriver: {}".format( driver ) )
@ -230,3 +244,19 @@ def webdriver( request ):
yield driver
finally:
driver.quit()
# ---------------------------------------------------------------------
def _disable_console_logging():
"""Disable Python logging to the console.
We do this when running tests because:
(1) pytest's output is voluminous enough without including our stuff in there as well (and it tends to be
not that helpful, anyway)
(2) pytest captures all output and shows it when the test ends i.e. we don't get to see messages in real-time.
"""
for logger in utils.get_all_loggers():
# NOTE: FileHandler derives from StreamHandler, and we want to keep those, so we can't use isinstance().
handlers = [ h for h in logger.handlers if type( h ) is logging.StreamHandler ] #pylint: disable=unidiomatic-typecheck
for h in handlers:
logger.removeHandler( h )

@ -2,5 +2,4 @@
IS_CONTAINER = 1
JAVA_PATH = /usr/bin/jdk-15.0.1/bin/java
WEBDRIVER_PATH = /usr/bin/geckodriver

@ -6,6 +6,10 @@ export DISPLAY=:10.0
Xvfb :10 -ac 1>/tmp/xvfb.log 2>/tmp/xvfb.err &
# run the webapp server
python3 /app/vasl_templates/webapp/run_server.py \
# IMPORTANT! This script runs as PID 1, which is the only process that will receive signals,
# so we must replace it with the Python webserver process if it is to receive e.g. SIGTERM,
# which we must handle if "docker stop" and scaling down in Kubernetes is to work (otherwise
# things timeout and we get SIGKILL'ed).
exec python3 /app/vasl_templates/webapp/run_server.py \
--addr 0.0.0.0 \
--force-init-delay 30

@ -1,16 +1,12 @@
{
"SCENARIO_NAME": "Hill 621",
"SCENARIO_ID": "ASL E",
"SCENARIO_LOCATION": "Near Minsk, Russia",
"COMPASS": "right",
"SCENARIO_DATE": "1944-07-01",
"SCENARIO_WIDTH": "",
"PLAYER_1_DESCRIPTION": "Retreating elements of 170th Infantry Division",
"PLAYER_2_DESCRIPTION": "Elements of 5th Guards Army",
"ASA_ID": "56512",
"ROAR_ID": "129",
"PLAYERS_WIDTH": "",
"VICTORY_CONDITIONS_WIDTH": "240px",
"SSR_WIDTH": "500px",
"VICTORY_CONDITIONS_WIDTH": "",
"SSR_WIDTH": "400px",
"OB_VEHICLES_WIDTH_1": "",
"OB_VEHICLES_MA_NOTES_WIDTH_1": "300px",
"OB_ORDNANCE_WIDTH_1": "",
@ -19,7 +15,12 @@
"OB_VEHICLES_MA_NOTES_WIDTH_2": "300px",
"OB_ORDNANCE_WIDTH_2": "",
"OB_ORDNANCE_MA_NOTES_WIDTH_2": "300px",
"VICTORY_CONDITIONS": "The Russians win at Game End if they Control &ge; five Level 3 hill hexes on Board 2.",
"SCENARIO_NAME": "Hill 621",
"SCENARIO_ID": "ASL E",
"SCENARIO_LOCATION": "Near Minsk, Russia",
"PLAYER_1_DESCRIPTION": "Retreating elements of 170th Infantry Division",
"PLAYER_2_DESCRIPTION": "Elements of 5th Guards Army",
"VICTORY_CONDITIONS": "The Russians win at Game End if they Control<br>≥ five Level 3 hill hexes on Board 2.",
"SCENARIO_THEATER": "ETO",
"PLAYER_1": "russian",
"PLAYER_1_ELR": "4",
@ -27,6 +28,15 @@
"PLAYER_2": "german",
"PLAYER_2_ELR": "3",
"PLAYER_2_SAN": "4",
"TURN_TRACK": {
"NTURNS": "10",
"WIDTH": "",
"VERTICAL": false,
"SHADING": "",
"REINFORCEMENTS_1": "2,5",
"REINFORCEMENTS_2": "1,2,4,5,8",
"SWAP_PLAYERS": false
},
"SSR": [
"EC are Moderate, with no wind at start.",
"After \"At Start\" placement, each German infantry unit must take a TC. The only possible consequence of failure is that the unit must begin the scenario broken. Those units which break during this pre-game TC are not subject to DM in the initial German RPh.",
@ -106,7 +116,7 @@
],
"SCENARIO_NOTES": [
{
"caption": "Download the scenario card from <a href=\"http://www.multimanpublishing.com/Support/ASLASLSK/ASLOfficialDownloads/tabid/109/Default.aspx\">Multi-Man Publishing</a> (ASL Classic pack).",
"caption": "Download the scenario card from <a href=\"https://mmpgamers.com/asl-downloads-ezp-3#scenarios\">Multi-Man Publishing</a> (ASL Classic pack).",
"width": "300px",
"id": 1
}
@ -173,7 +183,7 @@
"id": 2
}
],
"_app_version": "v1.3",
"_last_update_time": "2020-09-27T04:13:08.719Z",
"_app_version": "v1.10",
"_last_update_time": "2022-09-12T02:46:18.035Z",
"_creation_time": "2020-09-27T03:46:56.089Z"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 109 KiB

@ -1,15 +1,11 @@
{
"SCENARIO_NAME": "Hube's Pocket",
"SCENARIO_ID": "ASL G",
"SCENARIO_LOCATION": "Near Buchach, Southern Russia",
"COMPASS": "down",
"SCENARIO_DATE": "1944-04-06",
"SCENARIO_WIDTH": "",
"PLAYER_1_DESCRIPTION": "Advance elements of 5th Tank Corps",
"PLAYER_2_DESCRIPTION": "10th SS Panzer Division \"Frundsberg\" and the First Panzer Army ",
"ASA_ID": "56514",
"ROAR_ID": "131",
"PLAYERS_WIDTH": "",
"VICTORY_CONDITIONS_WIDTH": "320px",
"VICTORY_CONDITIONS_WIDTH": "",
"SSR_WIDTH": "330px",
"OB_VEHICLES_WIDTH_1": "",
"OB_VEHICLES_MA_NOTES_WIDTH_1": "300px",
@ -19,7 +15,12 @@
"OB_VEHICLES_MA_NOTES_WIDTH_2": "300px",
"OB_ORDNANCE_WIDTH_2": "",
"OB_ORDNANCE_MA_NOTES_WIDTH_2": "300px",
"VICTORY_CONDITIONS": "The Germans win immediately by exiting &ge; 10 vehicles <br>\noff the west edge in either one or two Convoys (see SSR 4).",
"SCENARIO_NAME": "Hube's Pocket",
"SCENARIO_ID": "ASL G",
"SCENARIO_LOCATION": "Near Buchach, Southern Russia",
"PLAYER_1_DESCRIPTION": "Advance elements of 5th Tank Corps",
"PLAYER_2_DESCRIPTION": "10th SS Panzer Division \"Frundsberg\" and the First Panzer Army",
"VICTORY_CONDITIONS": "The Germans win immediately by exiting ≥ 10 vehicles <br>\noff the west edge in either one or two Convoys (see SSR 4).",
"SCENARIO_THEATER": "ETO",
"PLAYER_1": "german",
"PLAYER_1_ELR": "4",
@ -27,6 +28,15 @@
"PLAYER_2": "russian",
"PLAYER_2_ELR": "3",
"PLAYER_2_SAN": "2",
"TURN_TRACK": {
"NTURNS": "14",
"WIDTH": "5",
"VERTICAL": false,
"SHADING": "",
"REINFORCEMENTS_1": "1,5",
"REINFORCEMENTS_2": "1",
"SWAP_PLAYERS": true
},
"SSR": [
"The SPW 251/sMG inherent HS is a 3-4-8.",
"German inherent crews have a morale of 9.",
@ -84,7 +94,7 @@
],
"SCENARIO_NOTES": [
{
"caption": "Download the scenario card from <a href=\"http://www.multimanpublishing.com/Support/ASLASLSK/ASLOfficialDownloads/tabid/109/Default.aspx\">Multi-Man Publishing</a> (ASL Classic pack).",
"caption": "Download the scenario card from <a href=\"https://mmpgamers.com/asl-downloads-ezp-3#scenarios\">Multi-Man Publishing</a> (ASL Classic pack).",
"width": "",
"id": 1
}
@ -110,7 +120,7 @@
],
"OB_NOTES_1": [],
"OB_NOTES_2": [],
"_app_version": "v1.3",
"_last_update_time": "2020-09-27T04:33:18.643Z",
"_app_version": "v1.10",
"_last_update_time": "2022-09-12T02:22:47.511Z",
"_creation_time": "2020-09-27T04:11:07.200Z"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 79 KiB

@ -4,4 +4,4 @@ This directory contains examples of *VASL Templates* in action, with the `.json`
The online versions contain images that will be loaded from the internet, which looks much better, but there will be a short delay when you open the scenario in VASSAL as the images are downloaded.
These scenarios were taken from Multi-Man Publishing's [*ASL Classic* scenario pack](http://www.multimanpublishing.com/Support/ASLASLSK/ASLOfficialDownloads/tabid/109/Default.aspx).
These scenarios were taken from Multi-Man Publishing's [*ASL Classic* scenario pack](https://mmpgamers.com/asl-downloads-ezp-3#scenarios).

@ -1,15 +1,11 @@
{
"SCENARIO_NAME": "The Streets Of Stalingrad",
"SCENARIO_ID": "ASL C",
"SCENARIO_LOCATION": "Stalingrad, Russia",
"COMPASS": "up",
"SCENARIO_DATE": "1942-10-06",
"SCENARIO_WIDTH": "",
"PLAYER_1_DESCRIPTION": "308th Rifle Division / 295th Rifle Division / 2nd Battalion, 37th Guards Division",
"PLAYER_2_DESCRIPTION": "389th Infantry Division",
"ASA_ID": "56510",
"ROAR_ID": "127",
"PLAYERS_WIDTH": "",
"VICTORY_CONDITIONS_WIDTH": "400px",
"VICTORY_CONDITIONS_WIDTH": "450px",
"SSR_WIDTH": "500px",
"OB_VEHICLES_WIDTH_1": "",
"OB_VEHICLES_MA_NOTES_WIDTH_1": "300px",
@ -19,7 +15,12 @@
"OB_VEHICLES_MA_NOTES_WIDTH_2": "300px",
"OB_ORDNANCE_WIDTH_2": "",
"OB_ORDNANCE_MA_NOTES_WIDTH_2": "300px",
"VICTORY_CONDITIONS": "Victory is based upon satisfying the Victory Conditions of Scenarios A and B:\n<ul style=\"margin:0 0 10px 10px;\">\n<li> If each side fulfills one Victory Condition, the game is a draw.\n<li> If a player fulfills one Victory Condition and draws the other, he wnis.\n<li> A decisive victory is achieved when a player fulfills both Victory Conditions.\n</ul>\n\n<p> <b>Scenario A:</b> The Russians win at Game End if they Control &ge; 2 more buildings initially occupied by the Germans than they lose of their own initially-held stone buildings to German Control, and/or have a favorable 3:1 ratio of unbroken squad-equivalents.\n<p> <b>Scenario B:</b> At Game End, the player with undisputed control of at least 6 hexes of building X3 wins. A hex containing a Melee is controlled by neither player. If only one player has an unbroken unit in the building at Game End, that player is the winner. Any other result is a draw.\n</ul>",
"SCENARIO_NAME": "The Streets Of Stalingrad",
"SCENARIO_ID": "ASL C",
"SCENARIO_LOCATION": "Stalingrad, Russia",
"PLAYER_1_DESCRIPTION": "308th Rifle Division / 295th Rifle Division / 2nd Battalion, 37th Guards Division",
"PLAYER_2_DESCRIPTION": "389th Infantry Division",
"VICTORY_CONDITIONS": "Victory is based upon satisfying the Victory Conditions of Scenarios A and B:\n<ul style=\"margin:0 0 10px 10px;\">\n<li> If each side fulfills one Victory Condition, the game is a draw.\n</li><li> If a player fulfills one Victory Condition and draws the other, he wnis.\n</li><li> A decisive victory is achieved when a player fulfills both Victory Conditions.\n</li></ul>\n\n<p> <b>Scenario A:</b> The Russians win at Game End if they Control ≥ 2 more buildings initially occupied by the Germans than they lose of their own initially-held stone buildings to German Control, and/or have a favorable 3:1 ratio of unbroken squad-equivalents.\n</p><p> <b>Scenario B:</b> At Game End, the player with undisputed control of at least 6 hexes of building X3 wins. A hex containing a Melee is controlled by neither player. If only one player has an unbroken unit in the building at Game End, that player is the winner. Any other result is a draw.\n</p>",
"SCENARIO_THEATER": "ETO",
"PLAYER_1": "russian",
"PLAYER_1_ELR": "3",
@ -27,6 +28,15 @@
"PLAYER_2": "german",
"PLAYER_2_ELR": "4",
"PLAYER_2_SAN": "6",
"TURN_TRACK": {
"NTURNS": "7",
"WIDTH": "",
"VERTICAL": false,
"SHADING": "",
"REINFORCEMENTS_1": "2",
"REINFORCEMENTS_2": "3",
"SWAP_PLAYERS": false
},
"SSR": [
"Roll a die to determine who moves first.",
"Set up the forces of Scenario A prior to placing the units of Scenario B.",
@ -61,7 +71,7 @@
],
"SCENARIO_NOTES": [
{
"caption": "Download the scenario card from <a href=\"http://www.multimanpublishing.com/Support/ASLASLSK/ASLOfficialDownloads/tabid/109/Default.aspx\">Multi-Man Publishing</a> (ASL Classic pack).",
"caption": "Download the scenario card from <a href=\"https://mmpgamers.com/asl-downloads-ezp-3#scenarios\">Multi-Man Publishing</a> (ASL Classic pack).",
"width": "",
"id": 1
}
@ -157,7 +167,7 @@
],
"OB_NOTES_1": [],
"OB_NOTES_2": [],
"_app_version": "v1.3",
"_last_update_time": "2020-09-27T04:46:21.803Z",
"_app_version": "v1.10",
"_last_update_time": "2022-09-12T02:58:13.237Z",
"_creation_time": "2020-09-27T04:44:48.473Z"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 902 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 61 KiB

@ -95,8 +95,8 @@ def main( args ): #pylint: disable=too-many-locals
args.append( "--noconsole" )
args.extend( [ "--icon", APP_ICON ] )
# NOTE: These files are not always required but it's probably safer to always include them.
import distutils.sysconfig #pylint: disable=import-error
dname = os.path.join( distutils.sysconfig.get_python_lib() , "PyQt5/Qt5/bin" )
import sysconfig
dname = os.path.join( sysconfig.get_path("platlib") , "PyQt5/Qt5/bin" )
args.extend( [ "--add-binary", os.path.join(dname,"libEGL.dll") + os.pathsep + "PyQt5/Qt/bin" ] )
args.extend( [ "--add-binary", os.path.join(dname,"libGLESv2.dll") + os.pathsep + "PyQt5/Qt/bin" ] )
args.append( MAIN_SCRIPT )

@ -98,7 +98,7 @@ def _convert_app_icon( save_fname ):
# to an image, then insert it into the PyInstaller-generated executable (so that
# we don't have to bundle Pillow into the release).
img = Image.open( APP_ICON )
img = img.convert( "RGBA" ).resize( (64, 64) )
img = img.convert( "RGBA" ).resize( (48, 48) )
img.save( save_fname, "png" )
# ---------------------------------------------------------------------

@ -93,7 +93,7 @@ def create_window( app_icon ):
"""Create the splash window."""
# create the splash window
main_window.geometry( "290x75" )
main_window.geometry( "275x64" )
main_window.title( "vasl-templates loader" )
main_window.overrideredirect( 1 ) # nb: "-type splash" doesn't work on Windows :-/
main_window.eval( "tk::PlaceWindow . center" )
@ -103,11 +103,11 @@ def create_window( app_icon ):
# add the app icon
label = tkinter.Label( main_window, image=app_icon )
label.grid( row=0, column=0, rowspan=2, padx=5, pady=5 )
label.grid( row=0, column=0, rowspan=2, padx=8, pady=8 )
# add the caption
label = tkinter.Label( main_window, text="Loading vasl-templates...", font=("Helvetica",12) )
label.grid( row=0, column=1, padx=5, pady=(5,0) )
label.grid( row=0, column=1, padx=5, pady=(8,0) )
# add the "loading" image (we have to animate it ourself :-/)
anim_label = tkinter.Label( main_window )

@ -1,7 +1,7 @@
pytest==6.2.5
grpcio-tools==1.41.0
tabulate==0.8.9
lxml==4.6.3
pylint==2.11.1
pytest-pylint==0.18.0
pyinstaller==4.5.1
pytest==7.4.2
grpcio-tools==1.58.0
tabulate==0.9.0
lxml==4.9.3
pylint==2.17.5
pytest-pylint==0.19.0
pyinstaller==5.13.2

@ -1,7 +1,10 @@
# python 3.8.7
# python 3.11.4
flask==2.0.1
pyyaml==5.4.1
pillow==8.3.2
selenium==3.141.0
click==8.0.1
flask==2.3.3
pyyaml==6.0.1
# NOTE: Pillow 9.5.0 is the last version that provides 32-bit wheels.
pillow==9.5.0
selenium==4.12.0
waitress==2.1.2
appdirs==1.4.4
click==8.1.7

@ -14,11 +14,17 @@ function main
VASL_BOARDS=
CHAPTER_H_NOTES=
USER_FILES=
LOGGING_CONFIG=
VASSAL_SHIM_LOGGING_CONFIG=
ASA_INDEX=
ROAR_INDEX=
VO_NOTES_IMAGE_CACHE=
TEMPLATE_PACK=
IMAGE_TAG=latest
CONTAINER_NAME=vasl-templates
DETACH=
NO_BUILD=
BUILD_ARGS=
BUILD_NETWORK=
RUN_NETWORK=
CONTROL_TESTS_PORT=
@ -30,7 +36,7 @@ function main
print_help
exit 0
fi
params="$(getopt -o p:v:e:k:t:d -l port:,control-tests-port:,vassal:,vasl:,vasl-extensions:,boards:,chapter-h:,template-pack:,user-files:,tag:,name:,detach,no-build,build-network:,run-network:,test-data-vassal:,test-data-vasl-mods:,help --name "$0" -- "$@")"
params="$(getopt -o p:v:e:k:t:d -l port:,control-tests-port:,vassal:,vasl:,vasl-extensions:,boards:,chapter-h:,template-pack:,user-files:,logging:,vassal-shim-logging:,asa-index:,roar-index:,vo-notes-image-cache:,tag:,name:,detach,no-build,build-arg:,build-network:,run-network:,test-data-vassal:,test-data-vasl-mods:,help --name "$0" -- "$@")"
if [ $? -ne 0 ]; then exit 1; fi
eval set -- "$params"
while true; do
@ -59,6 +65,21 @@ function main
-k | --template-pack)
TEMPLATE_PACK=$2
shift 2 ;;
--logging)
LOGGING_CONFIG=$2
shift 2 ;;
--vassal-shim-logging)
VASSAL_SHIM_LOGGING_CONFIG=$2
shift 2 ;;
--asa-index)
ASA_INDEX=$2
shift 2 ;;
--roar-index)
ROAR_INDEX=$2