fix: Restore all files lost during destructive rebase
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>
This commit is contained in:
191
backend/frontend/components/extract_components.py
Normal file
191
backend/frontend/components/extract_components.py
Normal file
@@ -0,0 +1,191 @@
|
||||
#!/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!")
|
||||
Reference in New Issue
Block a user