Files
infoscreen/server/routes/system_settings.py
RobbStarkAustria 10f446dfb5 feat: Add organization name and scheduler refresh interval settings
- Superadmin-only organization name setting displayed in dashboard header
- Advanced Options tab with configurable scheduler refresh interval (0 = disabled)
- Make system settings GET endpoint public for frontend reads
- Scheduler reads refresh_seconds from DB dynamically each loop
- Seed default system settings in init_defaults.py
2026-01-10 08:33:18 +00:00

330 lines
9.4 KiB
Python

"""
System Settings API endpoints.
Provides key-value storage for system-wide configuration.
"""
from flask import Blueprint, jsonify, request
from server.database import Session
from models.models import SystemSetting
from server.permissions import admin_or_higher, superadmin_only
from sqlalchemy.exc import SQLAlchemyError
system_settings_bp = Blueprint('system_settings', __name__, url_prefix='/api/system-settings')
@system_settings_bp.route('', methods=['GET'])
@admin_or_higher
def get_all_settings():
"""
Get all system settings.
Admin+ only.
"""
session = Session()
try:
settings = session.query(SystemSetting).all()
return jsonify({
'settings': [s.to_dict() for s in settings]
}), 200
except SQLAlchemyError as e:
return jsonify({'error': str(e)}), 500
finally:
session.close()
@system_settings_bp.route('/<key>', methods=['GET'])
def get_setting(key):
"""
Get a specific system setting by key.
Public endpoint - settings are read-only configuration.
"""
session = Session()
try:
setting = session.query(SystemSetting).filter_by(key=key).first()
if not setting:
return jsonify({'error': 'Setting not found'}), 404
return jsonify(setting.to_dict()), 200
except SQLAlchemyError as e:
return jsonify({'error': str(e)}), 500
finally:
session.close()
@system_settings_bp.route('/<key>', methods=['POST', 'PUT'])
@admin_or_higher
def update_setting(key):
"""
Create or update a system setting.
Admin+ only.
Request body:
{
"value": "string",
"description": "string" (optional)
}
"""
session = Session()
try:
data = request.get_json()
if not data:
return jsonify({'error': 'No data provided'}), 400
value = data.get('value')
description = data.get('description')
# Try to find existing setting
setting = session.query(SystemSetting).filter_by(key=key).first()
if setting:
# Update existing
setting.value = value
if description is not None:
setting.description = description
else:
# Create new
setting = SystemSetting(
key=key,
value=value,
description=description
)
session.add(setting)
session.commit()
return jsonify(setting.to_dict()), 200
except SQLAlchemyError as e:
session.rollback()
return jsonify({'error': str(e)}), 500
finally:
session.close()
@system_settings_bp.route('/<key>', methods=['DELETE'])
@admin_or_higher
def delete_setting(key):
"""
Delete a system setting.
Admin+ only.
"""
session = Session()
try:
setting = session.query(SystemSetting).filter_by(key=key).first()
if not setting:
return jsonify({'error': 'Setting not found'}), 404
session.delete(setting)
session.commit()
return jsonify({'message': 'Setting deleted successfully'}), 200
except SQLAlchemyError as e:
session.rollback()
return jsonify({'error': str(e)}), 500
finally:
session.close()
# Convenience endpoints for specific settings
@system_settings_bp.route('/supplement-table', methods=['GET'])
@admin_or_higher
def get_supplement_table_settings():
"""
Get supplement table URL and enabled status.
Admin+ only.
"""
session = Session()
try:
url_setting = session.query(SystemSetting).filter_by(key='supplement_table_url').first()
enabled_setting = session.query(SystemSetting).filter_by(key='supplement_table_enabled').first()
return jsonify({
'url': url_setting.value if url_setting else '',
'enabled': enabled_setting.value == 'true' if enabled_setting else False,
}), 200
except SQLAlchemyError as e:
return jsonify({'error': str(e)}), 500
finally:
session.close()
@system_settings_bp.route('/supplement-table', methods=['POST'])
@admin_or_higher
def update_supplement_table_settings():
"""
Update supplement table URL and enabled status.
Admin+ only.
Request body:
{
"url": "https://...",
"enabled": true/false
}
"""
session = Session()
try:
data = request.get_json()
if not data:
return jsonify({'error': 'No data provided'}), 400
url = data.get('url', '')
enabled = data.get('enabled', False)
# Update or create URL setting
url_setting = session.query(SystemSetting).filter_by(key='supplement_table_url').first()
if url_setting:
url_setting.value = url
else:
url_setting = SystemSetting(
key='supplement_table_url',
value=url,
description='URL für Vertretungsplan / WebUntis (Stundenplan-Änderungstabelle)'
)
session.add(url_setting)
# Update or create enabled setting
enabled_setting = session.query(SystemSetting).filter_by(key='supplement_table_enabled').first()
if enabled_setting:
enabled_setting.value = 'true' if enabled else 'false'
else:
enabled_setting = SystemSetting(
key='supplement_table_enabled',
value='true' if enabled else 'false',
description='Ob Vertretungsplan aktiviert ist'
)
session.add(enabled_setting)
session.commit()
return jsonify({
'url': url,
'enabled': enabled,
'message': 'Supplement table settings updated successfully'
}), 200
except SQLAlchemyError as e:
session.rollback()
return jsonify({'error': str(e)}), 500
finally:
session.close()
@system_settings_bp.route('/holiday-banner', methods=['GET'])
def get_holiday_banner_setting():
"""
Get holiday banner enabled status.
Public endpoint - dashboard needs this.
"""
session = Session()
try:
setting = session.query(SystemSetting).filter_by(key='holiday_banner_enabled').first()
enabled = setting.value == 'true' if setting else True
return jsonify({'enabled': enabled}), 200
except SQLAlchemyError as e:
return jsonify({'error': str(e)}), 500
finally:
session.close()
@system_settings_bp.route('/holiday-banner', methods=['POST'])
@admin_or_higher
def update_holiday_banner_setting():
"""
Update holiday banner enabled status.
Admin+ only.
Request body:
{
"enabled": true/false
}
"""
session = Session()
try:
data = request.get_json()
if not data:
return jsonify({'error': 'No data provided'}), 400
enabled = data.get('enabled', True)
# Update or create setting
setting = session.query(SystemSetting).filter_by(key='holiday_banner_enabled').first()
if setting:
setting.value = 'true' if enabled else 'false'
else:
setting = SystemSetting(
key='holiday_banner_enabled',
value='true' if enabled else 'false',
description='Ferienstatus-Banner auf Dashboard anzeigen'
)
session.add(setting)
session.commit()
return jsonify({
'enabled': enabled,
'message': 'Holiday banner setting updated successfully'
}), 200
except SQLAlchemyError as e:
session.rollback()
return jsonify({'error': str(e)}), 500
finally:
session.close()
@system_settings_bp.route('/organization-name', methods=['GET'])
def get_organization_name():
"""
Get organization name.
Public endpoint - header needs this.
"""
session = Session()
try:
setting = session.query(SystemSetting).filter_by(key='organization_name').first()
name = setting.value if setting and setting.value else ''
return jsonify({'name': name}), 200
except SQLAlchemyError as e:
return jsonify({'error': str(e)}), 500
finally:
session.close()
@system_settings_bp.route('/organization-name', methods=['POST'])
@superadmin_only
def update_organization_name():
"""
Update organization name.
Superadmin only.
Request body:
{
"name": "Meine Organisation"
}
"""
session = Session()
try:
data = request.get_json()
if not data:
return jsonify({'error': 'No data provided'}), 400
name = data.get('name', '')
# Update or create setting
setting = session.query(SystemSetting).filter_by(key='organization_name').first()
if setting:
setting.value = name
else:
setting = SystemSetting(
key='organization_name',
value=name,
description='Name der Organisation (wird im Header angezeigt)'
)
session.add(setting)
session.commit()
return jsonify({
'name': name,
'message': 'Organization name updated successfully'
}), 200
except SQLAlchemyError as e:
session.rollback()
return jsonify({'error': str(e)}), 500
finally:
session.close()