Files
rss-bridge-ntfy/main.py
T
dimon 3f9b108482 RSS/Atom -> ntfy bridge with web UI, OPML import/export and RU/EN localization
Web-managed fork of nurefexc/rss-bridge-ntfy: Flask UI + REST API, background
sync engine (SQLite dedup, quiet hours, filters, flood protection, images),
OPML import/export and switchable interface/notification language.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 19:34:53 +08:00

62 lines
1.6 KiB
Python

"""Entry point: wire up the store, the background engine and the web server.
A single process hosts both the Flask web UI/API and the RSS->ntfy engine
(running in its own daemon thread). Served by waitress so it works the same on
Linux containers and Windows.
"""
import logging
import os
import signal
import sys
from waitress import serve
import store as store_mod
from engine import Engine
from webapp import create_app
def setup_logging(engine: Engine):
logger = logging.getLogger("bridge")
logger.setLevel(logging.INFO)
fmt = logging.Formatter("%(asctime)s [%(levelname)s] %(message)s", "%Y-%m-%d %H:%M:%S")
stream = logging.StreamHandler(sys.stdout)
stream.setFormatter(fmt)
logger.addHandler(stream)
file_handler = logging.FileHandler(store_mod.LOG_PATH, encoding="utf-8")
file_handler.setFormatter(fmt)
logger.addHandler(file_handler)
logger.addHandler(engine.ring) # in-memory buffer for the web UI
logger.propagate = False
def main():
host = os.environ.get("HOST", "0.0.0.0")
port = int(os.environ.get("PORT", "8080"))
store = store_mod.Store()
engine = Engine(store)
setup_logging(engine)
engine.start()
app = create_app(store, engine)
def shutdown(signum, frame): # noqa: ARG001
logging.getLogger("bridge").info("Shutting down (signal %s)", signum)
engine.stop()
sys.exit(0)
signal.signal(signal.SIGINT, shutdown)
signal.signal(signal.SIGTERM, shutdown)
logging.getLogger("bridge").info("Web UI on http://%s:%s", host, port)
serve(app, host=host, port=port, threads=8)
if __name__ == "__main__":
main()