A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
192 lines
5.2 KiB
Python
192 lines
5.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Script to extract components from the monolithic studio.py file.
|
|
This script analyzes studio.py and extracts sections into separate component files.
|
|
"""
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
|
|
def read_file_lines(filepath: str, start: int, end: int) -> str:
|
|
"""Read specific lines from a file."""
|
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
lines = f.readlines()
|
|
return ''.join(lines[start-1:end])
|
|
|
|
|
|
def find_section_boundaries(filepath: str):
|
|
"""Find all section boundaries in the file."""
|
|
with open(filepath, 'r', encoding='utf-8') as f:
|
|
lines = f.readlines()
|
|
|
|
css_sections = []
|
|
html_sections = []
|
|
js_sections = []
|
|
|
|
for i, line in enumerate(lines, 1):
|
|
# Find CSS section markers
|
|
if '/* ==========================================' in line:
|
|
if i + 1 < len(lines):
|
|
title = lines[i].strip()
|
|
css_sections.append((i, title))
|
|
|
|
# Find JS section markers
|
|
if '// ==========================================' in line:
|
|
if i + 1 < len(lines):
|
|
title = lines[i].strip()
|
|
js_sections.append((i, title))
|
|
|
|
# Find HTML sections (major modal divs)
|
|
if '<div id="legal-modal"' in line or '<div id="auth-modal"' in line or '<div id="admin-panel"' in line:
|
|
html_sections.append((i, line.strip()))
|
|
|
|
return css_sections, html_sections, js_sections
|
|
|
|
|
|
def extract_legal_modal(source_file: str, output_dir: Path):
|
|
"""Extract Legal Modal component."""
|
|
with open(source_file, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
# Extract CSS (between LEGAL MODAL STYLES and AUTH MODAL STYLES)
|
|
css_match = re.search(
|
|
r'/\* ={40,}\s+LEGAL MODAL STYLES\s+={40,} \*/\s+(.*?)\s+/\* ={40,}\s+AUTH MODAL STYLES',
|
|
content,
|
|
re.DOTALL
|
|
)
|
|
|
|
# Extract HTML (legal-modal div)
|
|
html_match = re.search(
|
|
r'(<div id="legal-modal".*?</div>\s*<!-- /legal-modal -->)',
|
|
content,
|
|
re.DOTALL
|
|
)
|
|
|
|
# Extract JS (LEGAL MODAL section)
|
|
js_match = re.search(
|
|
r'// ={40,}\s+// LEGAL MODAL.*?\s+// ={40,}\s+(.*?)(?=\s+// ={40,})',
|
|
content,
|
|
re.DOTALL
|
|
)
|
|
|
|
css_content = css_match.group(1).strip() if css_match else ""
|
|
html_content = html_match.group(1).strip() if html_match else ""
|
|
js_content = js_match.group(1).strip() if js_match else ""
|
|
|
|
component_code = f'''"""
|
|
Legal Modal Component - AGB, Datenschutz, Cookies, Community Guidelines, GDPR Rights
|
|
"""
|
|
|
|
def get_legal_modal_css() -> str:
|
|
"""CSS für Legal Modal zurückgeben"""
|
|
return """
|
|
{css_content}
|
|
"""
|
|
|
|
|
|
def get_legal_modal_html() -> str:
|
|
"""HTML für Legal Modal zurückgeben"""
|
|
return """
|
|
{html_content}
|
|
"""
|
|
|
|
|
|
def get_legal_modal_js() -> str:
|
|
"""JavaScript für Legal Modal zurückgeben"""
|
|
return """
|
|
{js_content}
|
|
"""
|
|
'''
|
|
|
|
output_file = output_dir / 'legal_modal.py'
|
|
with open(output_file, 'w', encoding='utf-8') as f:
|
|
f.write(component_code)
|
|
|
|
print(f"✓ Created {output_file}")
|
|
return output_file
|
|
|
|
|
|
def extract_auth_modal(source_file: str, output_dir: Path):
|
|
"""Extract Auth Modal component."""
|
|
with open(source_file, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
# Extract CSS (between AUTH MODAL STYLES and next section)
|
|
css_match = re.search(
|
|
r'/\* ={40,}\s+AUTH MODAL STYLES\s+={40,} \*/\s+(.*?)(?=/\* ={40,})',
|
|
content,
|
|
re.DOTALL
|
|
)
|
|
|
|
# Extract HTML (auth-modal div)
|
|
html_match = re.search(
|
|
r'(<div id="auth-modal".*?</div>\s*<!-- /auth-modal -->)',
|
|
content,
|
|
re.DOTALL
|
|
)
|
|
|
|
# Extract JS (AUTH MODAL section)
|
|
js_match = re.search(
|
|
r'// ={40,}\s+// AUTH MODAL\s+// ={40,}\s+(.*?)(?=\s+// ={40,})',
|
|
content,
|
|
re.DOTALL
|
|
)
|
|
|
|
css_content = css_match.group(1).strip() if css_match else ""
|
|
html_content = html_match.group(1).strip() if html_match else ""
|
|
js_content = js_match.group(1).strip() if js_match else ""
|
|
|
|
component_code = f'''"""
|
|
Auth Modal Component - Login, Register, 2FA
|
|
"""
|
|
|
|
def get_auth_modal_css() -> str:
|
|
"""CSS für Auth Modal zurückgeben"""
|
|
return """
|
|
{css_content}
|
|
"""
|
|
|
|
|
|
def get_auth_modal_html() -> str:
|
|
"""HTML für Auth Modal zurückgeben"""
|
|
return """
|
|
{html_content}
|
|
"""
|
|
|
|
|
|
def get_auth_modal_js() -> str:
|
|
"""JavaScript für Auth Modal zurückgeben"""
|
|
return """
|
|
{js_content}
|
|
"""
|
|
'''
|
|
|
|
output_file = output_dir / 'auth_modal.py'
|
|
with open(output_file, 'w', encoding='utf-8') as f:
|
|
f.write(component_code)
|
|
|
|
print(f"✓ Created {output_file}")
|
|
return output_file
|
|
|
|
|
|
if __name__ == '__main__':
|
|
source_file = Path(__file__).parent.parent / 'studio.py'
|
|
output_dir = Path(__file__).parent
|
|
|
|
print(f"Extracting components from {source_file}...")
|
|
print(f"Output directory: {output_dir}")
|
|
|
|
# Find boundaries
|
|
css_sections, html_sections, js_sections = find_section_boundaries(str(source_file))
|
|
|
|
print(f"\nFound {len(css_sections)} CSS sections")
|
|
print(f"Found {len(html_sections)} HTML sections")
|
|
print(f"Found {len(js_sections)} JS sections")
|
|
|
|
# Extract components
|
|
# extract_legal_modal(str(source_file), output_dir)
|
|
# extract_auth_modal(str(source_file), output_dir)
|
|
|
|
print("\nDone!")
|