controller.helper.verse_interruptor
- File:
EuljiroWorship/controller/helper/verse_interruptor.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.
Watches core.config.paths.VERSE_FILE and converts it into slide JSON
written to core.config.paths.SLIDE_FILE for real-time display by the slide controller.
This module runs as a small background helper process. It uses watchdog to
monitor the project base directory for changes to the core.config.paths.VERSE_FILE, then
parses the content into one or more slide dictionaries.
Key behaviors:
If the last line looks like a structured Bible reference header, it generates per-verse slides with wrapped lines (textwrap.wrap) and style “verse”.
Otherwise, it treats the file as a free-form emergency message and generates style “lyrics” slides grouped by up to 2 lines (or by character budget).
Before overwriting the slide file, it may create a backup at
core.config.paths.SLIDE_BACKUP_FILE(only if the backup file does not already exist).
- controller.helper.verse_interruptor.parse_verse_output(file_path, max_chars=60)[source]
Parse
file_pathinto a list of slide dictionaries.The input file is interpreted as:
Structured mode: If the last line matches one of the expected header forms (e.g.,
<book> <chapter>장 ...,<book> <chapter>:<verse>, ...), the earlier lines are treated as verse body lines. Each verse line is wrapped tomax_charsand converted into style “verse” slides.Fallback mode: If no header pattern matches, the entire file is treated as a free-form emergency message. Non-empty lines are grouped into slides (up to 2 lines per slide or until the approximate character budget is met) using style “lyrics” and a fixed church caption.
Note
This function does not validate that the file is a real Bible reference. It only checks header patterns and then formats accordingly.
The caption format in structured mode follows the current implementation (e.g.,
<book> <chapter>장 <verse>절).
- Parameters:
file_path (str) – Path to the
core.config.paths.VERSE_FILEto parse.max_chars (int, optional) – Maximum character width used when wrapping long verse text or when grouping fallback message lines. Defaults to 60. (See also
core.config.constants.MAX_CHARS.)
- Returns:
List of slide dictionaries. Each slide dict contains:
”style”: “verse” (structured) or “lyrics” (fallback)
”caption”: caption string
”headline”: display text (possibly multi-line in fallback mode)
- Return type:
list[dict]
- controller.helper.verse_interruptor.backup_slide_if_not_emergency()[source]
Create a backup copy of the current slide JSON file if no backup exists yet.
This function writes
core.config.paths.SLIDE_BACKUP_FILEonly when that file does not already exist. The source iscore.config.paths.SLIDE_FILEif it exists and can be read.The backup is intended to support restoration after an emergency subtitle session ends. The current implementation skips backup if the loaded slides contain any slide whose “style” equals “verse_interrupt”.
- Returns:
None
- controller.helper.verse_interruptor.save_slides(slides, path)[source]
Save a list of slide dictionaries to a JSON file.
- Parameters:
slides (list[dict]) – Slide dictionaries to write.
path (str) – Destination JSON file path (typically
core.config.paths.SLIDE_FILE).
- Returns:
None
- class controller.helper.verse_interruptor.VerseFileHandler(*args, **kwargs)[source]
Bases:
FileSystemEventHandlerWatchdog event handler for updates to
core.config.paths.VERSE_FILE.This handler listens for filesystem modification events and, when the target file is modified, parses it into slides and writes the resulting JSON to
core.config.paths.SLIDE_FILE. If slides are generated, it attempts to create a backup viacontroller.helper.verse_interruptor.backup_slide_if_not_emergency()before overwriting the slide file.- Parameters:
args (Any)
kwargs (Any)
- Return type:
Any
- on_modified(event)[source]
Handle watchdog “modified” events for
core.config.paths.VERSE_FILE.If the modified path matches the target
core.config.paths.VERSE_FILE, this callback:Parses
core.config.paths.VERSE_FILEinto slide dictionaries.If any slides were produced:
Creates a backup (if applicable)
Writes slides to
core.config.paths.SLIDE_FILE
Otherwise logs that no slides were generated.
- Parameters:
event (FileSystemEvent) –
Watchdog event object describing the filesystem change.
- Returns:
None
- controller.helper.verse_interruptor.start_interruptor()[source]
Start the watchdog observer loop for
core.config.paths.VERSE_FILE.This sets up an Observer to watch
core.config.paths.BASE_DIR(non-recursive) and usescontroller.helper.verse_interruptor.VerseFileHandlerto react to modifications. The function then blocks the main thread in a sleep loop until interrupted (Ctrl+C).- Returns:
None