| title |
aliases |
tags |
sources |
created |
updated |
| Hotfolder Daemon — Box Monitoring |
| hotfolder |
| daemon |
| box-monitor |
| systemd-daemon |
|
| hotfolder |
| daemon |
| systemd |
| box |
| ford |
| automation |
| python |
|
| 01 Projects/ford_qc |
| 01 Projects/ford-gechub-sftp |
|
2026-04-15 |
2026-04-15 |
Hotfolder Daemon — Box Monitoring
Persistent background daemon that watches a Box folder for new files, processes them automatically, and archives the originals.
Key Takeaways
- Ford QC runs as a systemd service on a production server — survives reboots
- Hotfolder pattern: poll Box folder → detect new files → process → upload result → archive original
- Archive processed files immediately to prevent reprocessing
- CLI mode (single file) and daemon mode (continuous) — same core logic, different entry points
- Ford SFTP uses daemon mode (
python main.py --daemon) without systemd (simpler)
When to Use
Any automation that must respond to files dropped in a Box folder without human intervention.
Architecture
Ford QC Hotfolder
Box folder 332861865120 (hotfolder, poll every N seconds)
↓ detect new ZIP
ford_qc_box_hotfolder_process.py
↓
qc_engine.py → 13 QC check modules (checks/)
↓
JSON results → HTML report (html_reporter.py)
↓
Upload HTML report → Box 332864939558 (reports)
Archive ZIP → Box 332861653811 (archive)
Ford SFTP Daemon
Box folders (PROD / EDU / QA — 3 separate targets)
↓ poll for new ZIPs
ford_qc_box_hotfolder_process.py
↓
Download ZIP → Upload to GECHUB SFTP (paramiko)
↓
Archive in Box
↓
Email notification (Mailgun)
Systemd Service (Ford QC)
# /etc/systemd/system/ford-qc-hotfolder.service
[Unit]
Description=Ford QC Hotfolder Daemon
[Service]
ExecStart=/usr/bin/python3 /path/to/ford_qc_box_hotfolder_process.py
Restart=always
[Install]
WantedBy=multi-user.target
# Commands
sudo systemctl start ford-qc-hotfolder.service
sudo systemctl enable ford-qc-hotfolder.service # start on boot
sudo systemctl status ford-qc-hotfolder.service
Projects Using This Pattern
QC Module Pattern (Ford QC)
# qc_module.py
class QCModule:
def check(self, zip_path: str, profile: dict) -> dict:
"""Returns {"passed": bool, "issues": [...]}"""
# 13 modules in checks/:
# image resolution, format, file size, layer depth, colour existence,
# linking validation, MEC/BAU compliance, powertrain validation, lifestyle inventory
Gotchas & Lessons
- Always archive processed files — the daemon will reprocess on next poll if not archived
- Box JWT config (
ford_box_config.json) must not be committed to git
- Ranger ptvl pattern is configurable via profile JSON — don't hardcode (fix: 2026-03-16)
- Three environments (PROD/EDU/QA) have completely separate Box folder IDs and SFTP targets
- Mailgun integration: keep email templates simple — Mailgun rejects complex HTML occasionally
Related