Skip to content

Releases: Lazy-Beee/simulation-batch-runner

v1.4.0

Choose a tag to compare

@Lazy-Beee Lazy-Beee released this 19 Jul 03:29

What's new

Telegram

  • The zip and upload stages now report live progress to Telegram, not just their start and finish. Each stage sends one notice per progress band (e.g. Compressing 'case' 40%, Uploading 'case' 60%), plus a single 100%, throttled so the chat is never flooded. Previously the archive stage went silent between "started" and "done", which made a long transfer look stalled to a remote watcher.
  • The TUI Running log and the CLI console show the same throttled progress. 7-Zip is switched to -bsp1 on the streaming path so its percent output can be parsed and forwarded.

TUI

  • The queue Status column now reflects the post-sim archive stage (ZIPPING / UPLOADING), so a case that has finished simulating but is still archiving no longer reads as done.
  • Pressing START now confirms before re-running cases that already finished simulating, so a stray keypress can't silently redo completed work.

Fixes

  • Deleting the .batch exe copy is now retried when a force-quit leaves the image briefly locked (Windows WinError 32), instead of giving up and leaving the copy behind.
  • CLI: stdout is made lossy (errors="replace") so 7-Zip / rclone output carrying odd bytes can no longer crash print() on a non-UTF-8 console codepage (e.g. GBK on a zh-CN box).

Config

  • No new keys. The new zip / upload progress notices reuse the existing upload.eta_step_percent throttle (default 20 -> a notice every 20%).

Copy config.example.json to config.json next to the exe and edit it before first run (config.json is never bundled into the exe).

v1.3.0

Choose a tag to compare

@Lazy-Beee Lazy-Beee released this 04 Jul 23:01

What's new

Telegram

  • Notifications can now be tagged with a machine name. Set the new telegram.machine_name config key and every message from that host is prefixed with a #machine_name hashtag, so a shared chat receiving batches from several machines stays sortable and filterable.
  • Notifications are now sent on a background thread, off the log-reader loop, so a slow or unreachable Telegram API can no longer stall reading the simulator's output.
  • A failed post no longer kills the sender thread; delivery keeps working for the rest of the run.
  • Backtick and backslash are escaped inside code blocks and the monospace ordering is fixed, so case names with special characters render correctly.
  • Failed cases now show - for their cost in the batch report instead of a misleading number.

Fixes

  • A case that is force-stopped exactly as the dispatcher sweeps the queue now has its process reliably killed instead of being left running.
  • Cases are dispatched by identity and claimed on the UI thread, so reordering or removing a case mid-batch can no longer skip or double-run one.
  • The per-case log buffer is bounded, capping memory on long-running batches.
  • Subprocess output is decoded as UTF-8 (with replacement) rather than the OS default, and TUI log lines render as plain text, so odd bytes or markup in the simulator's output can't corrupt the display.
  • Missing 7-Zip in zip_case_output is handled gracefully instead of crashing.
  • The CLI is hardened against a bad exe path or a failed spawn, and skips spawning on a pre-spawn stop.
  • cleanup_exe now refuses to delete anything but the .batch copies it made, guarding against removing the wrong file.

Config

  • New key telegram.machine_name (default "" — no prefix). See config.example.json.
  • upload.eta_step_percent is now documented in the config reference.

Copy config.example.json to config.json next to the exe and edit it before first run (config.json is never bundled into the exe).

v1.2.2

Choose a tag to compare

@Lazy-Beee Lazy-Beee released this 01 Jul 22:52

What's new

TUI

  • The queue ETA now counts down live between the simulator's (often sparse) ETA updates instead of sitting frozen, so the remaining-time estimate keeps ticking toward 0:00:00 and re-anchors whenever a fresh estimate arrives.
  • Quitting (Ctrl+Q) while a batch / zip / upload is still in flight now asks to confirm first. Confirming kills every running simulator, 7-Zip and rclone process so none are left orphaned holding the launching console; Cancel keeps the app running.
  • The running-row highlight now uses black text on the yellow background for readability.

Fixes

  • A case added mid-batch while the last queued case was still running is no longer stranded. The coordinator now keeps the queue open until every in-flight case finishes, so a just-added case is dispatched and run instead of the batch stopping the moment that last case completes.

Copy config.example.json to config.json next to the exe and edit it before first run (config.json is never bundled into the exe).

v1.2.1

Choose a tag to compare

@Lazy-Beee Lazy-Beee released this 15 Jun 16:34

What's new

Simulator process priority (new)

  • New simulator.priority config sets the Windows kernel scheduling priority class for the simulator process: idle / below_normal / normal (default) / above_normal / high / realtime. Use below_normal / idle to keep the machine responsive while a batch runs in the background, or high to favor the sim over other work. Under MPI the class is set on mpiexec and inherited by the spawned ranks; unknown values fall back to normal, and non-Windows platforms ignore it.

Cloud upload

  • rclone transfer progress now displays past 100% instead of clamping.
  • Added Google Drive robustness flags to the example config (--drive-chunk-size, --timeout, --contimeout, low-level/normal retries, --drive-stop-on-upload-limit).
  • The rclone stats flags (--stats-one-line -v --stats 15s) are now fixed in code so periodic progress lines always show; ETA log lines are throttled to one per upload.eta_step_percent (default: every 20%).

TUI

  • Refreshing the scene queue table keeps its scroll position instead of jumping back to the top.

Config

  • New key: simulator.priority. See the updated config.example.json.

Copy config.example.json to config.json next to the exe and edit it before first run (config.json is never bundled into the exe).

v1.2.0

Choose a tag to compare

@Lazy-Beee Lazy-Beee released this 31 May 17:37

What's new

Cloud upload (new)

  • Optional post-zip upload of each case archive to a cloud remote via rclone (rclone copy), configured in a new upload section (enabled / rclone_path / remote / args). Set up the remote once with rclone config (one-time OAuth for Google Drive).
  • Runs on its own background worker (upload.async, default true) so a transfer overlaps zipping the next case while staying serial. Per-case Upload switch in the TUI; --no-upload in the CLI.

Parallel case execution (new)

  • Run several cases at once via the Parallel control (config defaults.parallel_cases, default 1 = the original sequential behavior). Each case gets its own OMP_NUM_THREADS (no global race); the log interleaves output with [case name] prefixes. The value is read at START / RESUME and locked during a run; adjust with the ▲▼ stepper or the Up/Down arrow keys.

Three-state output cleanup (replaces the Remove switch)

  • A Cleanup control cycling Keep / Folder / Both: keep everything, delete the raw output folder (default), or delete the folder and the local archive — the archive only after a successful upload, so the sole remaining copy is never dropped. CLI: --keep-output / --purge.

TUI

  • Numeric fields (OMP / MPI / Parallel) step by ±1 with the Up/Down arrow keys; Parallel also has a ▲▼ click stepper. The OMP field is one cell wider so a 2-digit value stays visible when focused.
  • Queue table gains Clean and Upl columns. Zip / Upl show - (off), Y (enabled, pending), and D once that step completes for the case.

Bug fixes

  • Fixed a crash when adding cases mid-batch (call_from_thread invoked from the app thread).

Config

  • simulator.zip_async is now a documented on/off switch (default true). New keys: upload.*, defaults.parallel_cases, defaults.zip, defaults.cleanup — see the updated config.example.json.

v1.1.3

Choose a tag to compare

@Lazy-Beee Lazy-Beee released this 25 May 22:49

What's new

TUI

  • Queue table supports multi-select. Space toggles a * marker in the # column for the cursor row, Ctrl+A selects everything, Esc clears. With any selection: Remove selected drops every removable entry in one pass, Up / Down moves the whole group as a unit (rows that hit a boundary or a non-pending neighbour stay put while the rest still shift), and View log opens one tab per finished entry.
  • Zip + remove now run on a background daemon thread, so the next case starts as soon as the previous simulator exits while the previous output is still being archived. Tasks are serialised behind a single worker so multiple 7z runs don't thrash disk. The batch waits for any remaining tasks before declaring idle.
  • Time and ETA columns share the same left-flush H:MM:SS format (up to 999h), so they line up cleanly. Elapsed time no longer rolls into X days, ....

7-Zip

  • simulator.zip_ext (default .zip) picks the archive format from the filename extension. Switch to .7z for LZMA2.
  • simulator.zip_args (default []) passes extra switches between a and the archive name. Defaults in the shipped template set -mx=5 -mmt=on (7z's own defaults, made explicit) so the knobs are discoverable.

Bug fixes

  • Unquoted Windows paths typed / pasted into the Scene input no longer have their backslashes silently eaten (shlex.split is now called with posix=False).

Internal

  • One-pass comment cleanup across the codebase, keeping the WHY notes (subprocess deadlock, OLE drag-drop modality, Textual binding collisions, etc.) and dropping the WHAT / historical references.

v1.1.2

Choose a tag to compare

@Lazy-Beee Lazy-Beee released this 21 May 14:09

What's new

Bug fixes

  • 7z output no longer leaks ANSI / CR sequences into the Textual render. The zip pipeline now streams via PIPE and routes lines through the TUI log instead of inheriting the parent's stdio.
  • Mid-batch Add no longer strands the (index+1/total) denominator. run_case now accepts a callable for total so per-step Telegram messages and the TUI's status / running-case labels re-evaluate the live queue length on every formatting; the periodic refresh re-renders both labels at 1 Hz. A Queue extended mid-batch: +N, now M total info line is also logged through Telegram + the TUI log when the queue grows during a run, explaining the jump.

TUI

  • Queue table sizes columns to the terminal: Simulator / Scene cells show extension-stripped filenames (head + ellipsis + tail truncation when needed), and absorb any width beyond the baseline at a 1:2 ratio, with overflow rolling to whichever side is still truncated.
  • Warnings / Errors columns tick live as each case runs, alongside Time and ETA.
  • Simulator field's Type label now flags a red (file not found) when the entered path doesn't resolve to a file - catches bad paths before Add.
  • The whole table re-stats once a second so a simulator / scene file deleted between Add and run gets the [!] marker within a second.

ETA extraction

  • Profile regex now also accepts CAMMP's space-separated form 1h 01m in addition to 7h57m and <1m.

Testing

  • fake_simulator gains output_files / output_file_size fields and a new scene_output.json for exercising the zip + remove pipeline end-to-end.

v1.1.1

Choose a tag to compare

@Lazy-Beee Lazy-Beee released this 20 May 17:19

New

  • ETA column in the queue table, populated from a per-profile eta_pattern regex (capture group 1 = the ETA token). Renders as H:MM:SS to line up with the Time column. <1m becomes 0:00:00; unparseable tokens fall back to the raw text.
  • Time column ticks live at 1 Hz while a case is running — no need to switch to the Running tab to see the per-case clock.
  • Mid-batch Add is supported now. The worker reads self.scene_entries live, so cases queued during a batch fall under the cursor and run as part of the same batch instead of waiting for the next START / RESUME. The old "paste blocked while running" gate is gone.

Changes (potentially breaking config)

  • Simulator profile field step_marker is renamed to step_pattern and is now interpreted as a Python regex (re.search). Capture group 1, if present, is the display text. Migrate by renaming the key and escaping regex metacharacters — e.g. SPlisHSPlasH's literal [step] becomes "step_pattern": "\\[step\\]". CAMMP's "Processed layer " works unchanged.
  • requirements.txt: textual minimum bumped from >=0.50 to >=1.0 because we lean on newer API (App.copy_to_clipboard, Strip.text, events.DescendantFocus, Static.text_selection).

Polish

  • README: prebuilt-binary callout in Setup, dedicated Building binaries section explaining build.bat and PyInstaller quirks.
  • test/fake_simulator emits ETA tokens on every step line so the ETA column can be exercised; scene_long.json ticks down from 14h30m via eta_per_step: 30.
  • Per-Add exe snapshot semantics (introduced in v1.1.0) documented more clearly in How it works.

Assets

batch_simu_tui.exe (~35 MB) and batch_simu_cli.exe (~12 MB) are Windows x64 onefile binaries — drop next to a config.json (copy of config.example.json) and run, no Python install needed. Screenshots are the same UI as v1.1.0 except for the extra ETA column.

v1.1.0

Choose a tag to compare

@Lazy-Beee Lazy-Beee released this 20 May 16:05

New

  • Windows x64 onefile binaries ship as release assets — no Python install needed. Copy config.example.json next to the exe as config.json and run.
    • batch_simu_tui.exe (~35 MB, Textual TUI)
    • batch_simu_cli.exe (~12 MB, interactive CLI)
  • Per-Add exe snapshot: each Add takes its own copy of the simulator exe, so recompiling mid-batch only affects cases queued after the rebuild. Cases added in the same Add share one copy; reference-counted cleanup runs on Remove / Reset / app exit.
  • Copy log button on the Running and case-log tab toolbars (Textual's click-drag selection does not work on RichLog — this provides a reliable cross-terminal OSC-52 copy path).
  • Close button on case-log tabs.
  • Drag-target indicator + Clear buttons next to the Simulator and Scene inputs. The next paste / drop lands in whichever input you last clicked or Tab-focused.
  • OMP / MPI numeric inputs gray out when their switch is off.
  • TUI "Setup" tab renamed to Queue; redesigned with bold field labels, muted hints, accent-coloured queue-table border, consistent vertical breaks, and a progress bar with its own bottom margin.
  • Case-log tab now mirrors the Running tab's three-row header (case / simulator / stats + Copy) and the same accent border on the log panel.

Changes (potentially breaking for callers)

  • CLI script renamed: batch_simu.pybatch_simu_cli.py. Update any wrappers that invoke the CLI by name.
  • Queue-table column "Exe" → "Simulator" (UI label only).
  • Tab "Setup" → "Queue"; the F1 footer label follows.

Fixes

  • Simulator hang from unread stderr PIPE. stderr is now merged into stdout so the existing reader drains both streams; stdin is DEVNULL to avoid simulators stalling on accidental input reads.
  • Footer key order shifting when an Input was focused — Ctrl+X (Stop) and Ctrl+W (Close case tab) are now show=False so they no longer shuffle their visible position depending on focus.

Removed

  • Replay-mode fake simulator. Synthetic mode covers the manual testing path.

Internal

  • simulation.py:_app_root() resolves config.json correctly in both frozen-exe and source-tree modes (PyInstaller sets sys.frozen).
  • build.bat: one-step PyInstaller chain (--onefile, --collect-submodules textual so Textual's lazy widget loading survives freezing).

v1.0.1

Choose a tag to compare

@Lazy-Beee Lazy-Beee released this 20 May 01:40

Fixes

  • Simulator hang from unread stderr PIPE. stderr was opened but never drained; once the OS pipe buffer filled, the simulator's next write blocked — stdout stopped advancing and the UI appeared to freeze, even when stdout was producing fewer than one line per second. stderr is now merged into stdout so the existing reader handles both, and stdin is pointed at DEVNULL.
  • Footer key order shifting when an Input was focused. Ctrl+X (Stop) and Ctrl+W (Close case tab) collide with Input's built-in cut / delete-word bindings; Textual interleaves them at Input.BINDINGS slot positions, scrambling the visible key order. Both are now show=False. Ctrl+X stays priority so Stop still fires from inside an Input; Ctrl+W stays non-priority so Input keeps delete-word.

TUI improvements

  • Explicit drag-and-drop target. The next paste / drop lands in the input you last clicked or Tab-focused, shown as Drag target: Simulator / Scene under the Scene input. Replaces focus-based routing, which broke when an OLE drag cleared Textual focus.
  • Clear button next to each of Simulator / Scene inputs. Clear empties the field and re-focuses it (which also sets it as the next drag target).
  • Copy log button in the Running tab toolbar and in each case-log tab. Textual's click-drag selection works for Static / Label but not for RichLog (mouse-down is consumed by the scrollable container), so the button pipes the active RichLog through app.copy_to_clipboard (OSC 52) for a reliable cross-terminal copy. Terminal-native Shift+drag still works for finer-grained selection.
  • Tighter Running and case-tab headers. Single-line header rows now line up with the Copy button alongside them. Case-tab header shows Case | Exe on row 1 and Status | Time | Warnings | Errors + Copy on row 2.