EuljiroWorship

File:

EuljiroWorship/EuljiroWorship.py

Author:

Benjamin Jaedon Choi - https://github.com/saintbenjamin

Affiliated Church:

The Eulji-ro Presbyterian Church [대한예수교장로회(통합) 을지로교회]

Address:

The Eulji-ro Presbyterian Church, 24-10, Eulji-ro 20-gil, Jung-gu, Seoul 04549, South Korea

Telephone:

+82-2-2266-3070

E-mail:

euljirochurch [at] G.M.A.I.L. (replace [at] with @ and G.M.A.I.L as you understood.)

License:

MIT License with Attribution Requirement (see LICENSE file for details); Copyright (c) 2025 The Eulji-ro Presbyterian Church.

Main entry point for the EuljiroWorship application.

This module launches the Qt-based Slide Generator UI and starts the background servers required for the browser-based overlay:

  • An HTTP server (static file hosting; default: port 8080)

  • A WebSocket server (real-time slide updates; default: port 8765)

Typical usage:

python EuljiroWorship.py

Note

  • The HTTP document root is currently set to the project root directory. If your overlay/static files live under a specific subdirectory (e.g. web/), update http_cwd accordingly.

  • Both servers are started as subprocesses. They are terminated on normal Qt exit and also via atexit as a fallback.

  • Alternate launcher modes (controller / HTTP server / WebSocket server / interruptor) are exposed so the same entry point can be reused in frozen executable builds.

  • If the server subprocess exits immediately (e.g., port already in use), the launcher raises a RuntimeError.

EuljiroWorship._project_root()[source]

Return the project root directory.

In source execution, this resolves to the repository root. In frozen execution, this resolves to the directory containing the bundled executable and its staged resource folders.

Returns:

Absolute path to the project root directory.

Return type:

pathlib.Path

EuljiroWorship._start_http_server(cwd, port=8080)[source]

Start the static-file HTTP server as a subprocess.

The subprocess relaunches the main application entry point in dedicated --http-server mode so the same implementation works in both source and frozen executable builds.

Parameters:
  • cwd (pathlib.Path) – The directory to serve as the HTTP document root (process working directory).

  • port (int, optional) – TCP port to bind the HTTP server to. Default is 8080.

Returns:

A handle to the spawned HTTP server process.

Return type:

subprocess.Popen

Note

  • start_new_session=True is used to improve shutdown reliability across platforms by detaching the child process session.

  • Standard output/error are inherited by default (stdout=None, stderr=None).

EuljiroWorship._start_ws_server(root)[source]

Start the WebSocket server as a subprocess.

The subprocess relaunches the main application entry point in dedicated --ws-server mode so the same launcher path works in both source and frozen executable builds.

Parameters:

root (pathlib.Path) – Absolute path to the project root directory.

Returns:

A handle to the spawned WebSocket server process.

Return type:

subprocess.Popen

Note

  • The process is spawned with its working directory set to the project root.

  • start_new_session=True is used to improve shutdown reliability across platforms.

EuljiroWorship._terminate_process(p)[source]

Terminate a subprocess gracefully, with a forced kill as fallback.

This function attempts a soft shutdown first using terminate(), then waits briefly. If the process does not exit within the timeout, it escalates to kill(). Any exceptions during shutdown are suppressed intentionally (shutdown paths should not crash the main application).

Parameters:

p (subprocess.Popen) – Subprocess handle to terminate. If the process is already exited, this function does nothing.

Returns:

None

Return type:

None

EuljiroWorship._ensure_alive(p, name)[source]

Verify that a freshly spawned subprocess is still running.

This is a small safety check to catch immediate failures such as:

  • address/port already in use

  • missing dependencies

  • import/runtime errors causing instant exit

The function waits briefly and then checks the return code via poll(). If the process has already exited, a RuntimeError is raised.

Parameters:
  • p (subprocess.Popen) – Subprocess handle to validate.

  • name (str) – Human-readable process name used in the error message.

Raises:

RuntimeError – If the subprocess has already exited.

Returns:

None

Return type:

None

EuljiroWorship._parse_mode_args(argv=None)[source]

Parse launcher mode arguments.

Parameters:

argv (list[str] | None) – Optional explicit argument list. If None, sys.argv[1:] is used.

Returns:

Parsed launcher arguments.

Return type:

argparse.Namespace

EuljiroWorship._run_static_http_server(root, port=8080)[source]

Run a static-file HTTP server in the current process.

Parameters:
  • root (pathlib.Path) – Directory to expose as the HTTP document root.

  • port (int, optional) – TCP port to bind. Defaults to 8080.

Returns:

None

Return type:

None

EuljiroWorship._run_mode_from_cli(args)[source]

Dispatch alternate launcher modes.

Parameters:

args (argparse.Namespace) – Parsed launcher arguments.

Returns:

True if an alternate mode was executed and normal GUI startup should be skipped, False otherwise.

Return type:

bool

EuljiroWorship.main()[source]

Launch the default Slide Generator application workflow.

Returns:

None

Return type:

None