This commit is contained in:
Mateusz Gruszczyński
2026-02-14 09:46:26 +01:00
parent 768b30923d
commit e999fc77c2

101
app.py
View File

@@ -17,6 +17,7 @@ import config
from cve_handler import CVEHandler, update_all_vendors
import api
def setup_logging():
log_level = getattr(logging, config.LOG_LEVEL.upper(), logging.INFO)
@@ -60,16 +61,19 @@ if not config.DEBUG:
app.register_blueprint(api.api_bp, url_prefix='/api')
cve_handler = CVEHandler()
@app.context_processor
def inject_config():
return {'config': config}
def add_security_headers(response):
if config.ENABLE_SECURITY_HEADERS:
for header, value in config.SECURITY_HEADERS.items():
response.headers[header] = value
return response
def gzip_response(f):
@wraps(f)
def decorated_function(*args, **kwargs):
@@ -99,6 +103,7 @@ def gzip_response(f):
return response
return decorated_function
def etag_support(f):
@wraps(f)
def decorated_function(*args, **kwargs):
@@ -121,12 +126,14 @@ def etag_support(f):
return decorated_function
@app.route('/')
@gzip_response
@etag_support
def index():
return render_template('index.html', vendors=config.VENDORS)
@app.route('/health')
def health():
try:
@@ -166,10 +173,12 @@ def health():
'error': str(e)
}), 503
@app.route('/favicon.ico')
def favicon():
return '', 204
@app.route('/version')
def version():
return jsonify({
@@ -179,12 +188,14 @@ def version():
'flask_version': '3.0.2'
})
@app.errorhandler(404)
def not_found(error):
if request.path.startswith('/api/'):
return jsonify({'error': 'Endpoint not found'}), 404
return render_template('404.html'), 404
@app.errorhandler(500)
def internal_error(error):
logger.error(f"Internal error: {error}")
@@ -192,6 +203,7 @@ def internal_error(error):
return jsonify({'error': 'Internal server error'}), 500
return render_template('500.html'), 500
@app.after_request
def after_request(response):
response = add_security_headers(response)
@@ -204,6 +216,7 @@ def after_request(response):
return response
def background_update_task():
logger.info("Background update task started")
time.sleep(60)
@@ -225,31 +238,68 @@ def background_update_task():
def start_background_tasks():
if config.ENABLE_AUTO_UPDATE:
update_thread = threading.Thread(
target=background_update_task,
daemon=True,
name="CVE-Update-Thread"
)
update_thread.start()
logger.info("Auto-update enabled: background task started")
else:
logger.info("Auto-update disabled")
is_gunicorn = (
'gunicorn' in os.environ.get('SERVER_SOFTWARE', '').lower() or
os.environ.get('GUNICORN_CMD_ARGS') is not None
)
if config.DISCORD_BOT_ENABLED:
try:
from discord_bot import start_discord_bot
discord_thread = threading.Thread(
target=start_discord_bot,
daemon=True,
name="Discord-Bot-Thread"
)
discord_thread.start()
logger.info("Discord bot started")
except ImportError:
logger.warning("discord.py not installed, Discord bot disabled")
except Exception as e:
logger.error(f"Failed to start Discord bot: {e}", exc_info=True)
is_dev_mode = __name__ == '__main__'
if is_gunicorn:
logger.info("=" * 70)
logger.info("PRODUCTION MODE (Gunicorn)")
logger.info("=" * 70)
logger.info("Background tasks handled by separate containers:")
logger.info(" Scheduler: cve-monitor-scheduler")
logger.info(" Discord Bot: cve-monitor-discord")
logger.info("=" * 70)
return
if is_dev_mode:
logger.info("=" * 70)
logger.info("DEVELOPMENT MODE (Standalone Flask)")
logger.info("=" * 70)
logger.info("Starting background tasks in threads...")
logger.info("")
if config.ENABLE_AUTO_UPDATE:
try:
update_thread = threading.Thread(
target=background_update_task,
daemon=True,
name="CVE-Update-Thread"
)
update_thread.start()
logger.info(" Scheduler thread: STARTED")
except Exception as e:
logger.error(f" Scheduler thread: FAILED - {e}")
else:
logger.info(" Scheduler thread: DISABLED")
if config.DISCORD_BOT_ENABLED:
try:
from discord_bot import start_discord_bot
discord_thread = threading.Thread(
target=start_discord_bot,
daemon=True,
name="Discord-Bot-Thread"
)
discord_thread.start()
logger.info(" Discord bot thread: STARTED")
except ImportError:
logger.warning(" Discord bot thread: FAILED - discord.py not installed")
except Exception as e:
logger.error(f" Discord bot thread: FAILED - {e}")
else:
logger.info(" Discord bot thread: DISABLED")
logger.info("")
logger.info("=" * 70)
else:
logger.info("Production mode: background tasks in separate containers")
def initialize_app():
logger.info(f"{'='*60}")
@@ -282,6 +332,7 @@ def initialize_app():
logger.info(f"{'='*60}")
start_background_tasks()
_initialized = False
if __name__ == '__main__':
@@ -300,4 +351,4 @@ if __name__ == '__main__':
else:
if not _initialized:
initialize_app()
_initialized = True
_initialized = True