diff --git a/templates/index_v2.html b/templates/index_v2.html index 92a62766..9e2c9b25 100644 --- a/templates/index_v2.html +++ b/templates/index_v2.html @@ -719,11 +719,12 @@ + On-Demand: None -
Service actions may require sudo privileges on the Pi.
+
Service actions may require sudo privileges on the Pi. Migrate Config adds new options with defaults while preserving your settings.
@@ -906,6 +907,9 @@ + @@ -2487,6 +2491,9 @@ if (action === 'reboot_system' && !confirm('Are you sure you want to reboot the system?')) { return; } + if (action === 'migrate_config' && !confirm('This will migrate your configuration to add any new options with default values. A backup will be created automatically. Continue?')) { + return; + } try { const response = await fetch('/api/system/action', { @@ -3038,6 +3045,41 @@ }); })(); + // Music form submit + (function augmentMusicForm(){ + const form = document.getElementById('music-form'); + form.addEventListener('submit', async function(e){ + e.preventDefault(); + const payload = { + music: { + enabled: document.getElementById('music_enabled').checked, + preferred_source: document.getElementById('music_preferred_source').value, + YTM_COMPANION_URL: document.getElementById('ytm_companion_url').value, + POLLING_INTERVAL_SECONDS: parseInt(document.getElementById('music_polling_interval').value) + } + }; + await saveConfigJson(payload); + }); + })(); + + // Calendar form submit + (function augmentCalendarForm(){ + const form = document.getElementById('calendar-form'); + form.addEventListener('submit', async function(e){ + e.preventDefault(); + const calendars = document.getElementById('calendar_calendars').value.split(',').map(s => s.trim()).filter(Boolean); + const payload = { + calendar: { + enabled: document.getElementById('calendar_enabled').checked, + max_events: parseInt(document.getElementById('calendar_max_events').value), + update_interval: parseInt(document.getElementById('calendar_update_interval').value), + calendars: calendars + } + }; + await saveConfigJson(payload); + }); + })(); + // News advanced save async function saveNewsAdvancedSettings(){ const payload = { diff --git a/web_interface_v2.py b/web_interface_v2.py index d255547a..9be93db5 100644 --- a/web_interface_v2.py +++ b/web_interface_v2.py @@ -735,6 +735,18 @@ def system_action(): }), 400 result = subprocess.run(['git', 'pull'], capture_output=True, text=True, cwd=str(repo_dir), check=False) + elif action == 'migrate_config': + # Run config migration script + repo_dir = Path(__file__).resolve().parent + migrate_script = repo_dir / 'migrate_config.sh' + if not migrate_script.exists(): + return jsonify({ + 'status': 'error', + 'message': f'Migration script not found: {migrate_script}' + }), 400 + + result = subprocess.run(['bash', str(migrate_script)], + cwd=str(repo_dir), capture_output=True, text=True, check=False) else: return jsonify({ 'status': 'error',