Quote Bridge (Listener App)
This is a separate Python app that runs independently from the Flask app.
It watches for quote files in shared/outgoing and can run in two modes:
move(default): move incoming files toshared/processeddosbox: run DOSBox command/script per quote file, then move toshared/processedon success orshared/failedon error
Run
From repository root:
./.venv/bin/python quote-bridge/listener.py
Or from this folder:
../.venv/bin/python listener.py
Install DOSBox On Ubuntu
You will need DOSBox installed on the Ubuntu machine if you want to use
QUOTE_PROCESSOR_MODE=dosbox.
Option 1: Standard DOSBox
sudo apt update
sudo apt install dosbox
Option 2: DOSBox-X
If available in your environment or package source, DOSBox-X is a better choice for many protected-mode DOS applications.
Example:
sudo apt update
sudo apt install dosbox-x
If your distro does not provide dosbox-x, install it from your preferred
package source and then update dosboxBin in your profile.
Environment Variables
QUOTE_OUTGOING_DIR: Source directory to watchQUOTE_PROCESSED_DIR: Destination directory for moved filesQUOTE_FAILED_DIR: Destination for failed quote filesQUOTE_PROCESSOR_MODE:moveordosbox(default:move)QUOTE_PROFILE_DIR: Directory containing per-location DOSBox profilesQUOTE_POLL_INTERVAL_SECONDS: Poll interval (default:2)
DOSBox Mode Variables
When QUOTE_PROCESSOR_MODE=dosbox, these variables are used:
DOSBOX_BIN: DOSBox executable (default:dosbox)DOSBOX_CONF: Optional DOSBox config file pathDOSBOX_MOUNT_PATH: Host path mounted into DOS (default: shared parent path)DOSBOX_MOUNT_DRIVE: DOS drive letter (default:C)DOSBOX_BRIDGE_COMMAND: DOS command/batch to run (default:BRIDGE.BAT)DOSBOX_EXTRA_COMMANDS: Extra DOS commands separated by;DOSBOX_TIMEOUT_SECONDS: Timeout for one DOSBox run (default:120)DOSBOX_NOCONSOLE:true/falseto add-noconsoleflag
Profiles
When QUOTE_PROCESSOR_MODE=dosbox, the helper looks at the quote file's
createdBy.location field and tries to load a matching profile from:
quote-bridge/profiles/<LOCATION>.json- then
quote-bridge/profiles/default.json
Included sample profiles:
quote-bridge/profiles/IOLA.jsonquote-bridge/profiles/KC.jsonquote-bridge/profiles/LINDS.jsonquote-bridge/profiles/default.json
Where To Enter The Remote Path
For each location profile, set:
mountPath: the Linux path where that remote PC's shared drive/folder is mounted
Example:
{
"mountPath": "/mnt/iola-cgw"
}
That is the main place to enter the mapped path.
Where To Enter The DOS App Folder
For each location profile, set:
workingDirectory: the DOS folder under the mounted share that contains the app
Example:
{
"workingDirectory": "CGWAPP"
}
If the DOS app lives at:
/mnt/iola-cgw/CGWAPP
then use:
mountPath = /mnt/iola-cgwworkingDirectory = CGWAPP
Where To Enter The DOS Entry Script
For each location profile, set:
bridgeCommand: the DOS-side batch/script/executable to run after mounting and changing directory
Example:
{
"bridgeCommand": "BRIDGE.BAT"
}
Suggested Setup For Multiple PCs
If each location runs from a different PC, the clean pattern is:
- Mount each remote PC's application share on Ubuntu.
- Put that mount path into the matching location profile.
- Keep one profile per location.
- Let the helper auto-select the profile based on the quote's current location.
Example mapping:
IOLA->/mnt/iola-cgwKC->/mnt/kc-cgwLINDS->/mnt/linds-cgw
Mounting Remote PC Shares On Ubuntu
If the DOS app is stored on remote Windows PCs, Ubuntu needs those folders mounted locally first.
Example mount points:
sudo mkdir -p /mnt/iola-cgw
sudo mkdir -p /mnt/kc-cgw
sudo mkdir -p /mnt/linds-cgw
Example CIFS mount command:
sudo mount -t cifs //REMOTE-PC/SharedFolder /mnt/iola-cgw \
-o username=YOUR_USER,password=YOUR_PASSWORD,uid=$(id -u),gid=$(id -g)
Replace:
REMOTE-PCwith the Windows machine name or IPSharedFolderwith the shared folder nameYOUR_USERandYOUR_PASSWORDwith Windows credentials
After the mount is working, put that Linux mount path into the matching profile
as mountPath.
Example .env-Style Setup
You can export variables in the shell before starting the listener.
Example:
export QUOTE_PROCESSOR_MODE=dosbox
export QUOTE_PROFILE_DIR=/home/jsalmon/Documents/git/quote-builder/quote-bridge/profiles
./.venv/bin/python quote-bridge/listener.py
If you prefer, create a small shell script such as start-quote-bridge.sh that
exports these values and starts the listener.
Sample Profile Fields
Example profile:
{
"profileName": "IOLA",
"dosboxBin": "dosbox-x",
"mountDrive": "C",
"mountPath": "/mnt/iola-cgw",
"workingDirectory": "CGWAPP",
"bridgeCommand": "BRIDGE.BAT",
"extraCommands": [
"SET CLIPPER=F200"
],
"timeoutSeconds": 180,
"noConsole": false
}
DOS-Side BRIDGE.BAT Contract
The helper currently assumes a DOS-side entry script like:
BRIDGE.BAT "C:\OUTGOING\20260629-153012-ab12cd34.json"
That means BRIDGE.BAT should accept the quote file path as %1.
Minimal example:
@echo off
rem %1 is the quote JSON file path inside DOSBox
echo Processing quote file: %1
rem Start your DOS app here and pass or import the file as needed
rem Example only:
rem MYAPP.EXE %1
If your DOS app requires a different startup sequence, change bridgeCommand
in the location profile.
End-To-End Flow
- User clicks
Quotein the Flask app. - Flask writes a quote JSON file to
shared/outgoing. - Listener sees the new file.
- Listener selects profile based on
createdBy.locationin the quote. - In
dosboxmode, listener launches DOSBox using that profile. - DOSBox runs the configured
bridgeCommand. - File moves to:
shared/processedon successshared/failedon failure
Current Behavior
- Processes
.jsonfiles only - Ignores temporary files such as
*.tmp - Appends a timestamp suffix if a destination filename already exists
- In
movemode, files are moved from outgoing to processed - In
dosboxmode, each file is passed to DOSBox first, then moved to:processedon successfailedon failure
Use Ctrl+C to stop the listener.