🎉 3 Änderungen an Tools-Modul vorgenommen:
- backend/form_test_automator.py -> backend/tools/analysis/form_test_automator.py - backend/simple_form_tester.py -> backend/tools/analysis/simple_form_tester.py - backend/template_analysis_tool.py -> backend/tools/analysis/template_analysis_tool.py - backend
This commit is contained in:
245
backend/tools/analysis/template_analysis_tool.py
Normal file
245
backend/tools/analysis/template_analysis_tool.py
Normal file
@ -0,0 +1,245 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Intelligentes Template-Analyse-Tool für MYP Admin Panel
|
||||
Systematische Identifikation und Behebung aller Template-Probleme
|
||||
|
||||
Autor: MYP Team - Till Tomczak
|
||||
Datum: 2025-06-19
|
||||
"""
|
||||
|
||||
import re
|
||||
import os
|
||||
import json
|
||||
from typing import Dict, List, Set, Tuple
|
||||
from pathlib import Path
|
||||
|
||||
class TemplateAnalyzer:
|
||||
"""
|
||||
Intelligenter Template-Analyzer für systematische Problemerkennung
|
||||
"""
|
||||
|
||||
def __init__(self, template_path: str, blueprint_path: str):
|
||||
self.template_path = template_path
|
||||
self.blueprint_path = blueprint_path
|
||||
self.template_endpoints: Set[str] = set()
|
||||
self.available_endpoints: Set[str] = set()
|
||||
self.endpoint_mapping: Dict[str, str] = {}
|
||||
self.problems: List[Dict] = []
|
||||
self.corrections: List[Dict] = []
|
||||
|
||||
def analyze_template_endpoints(self) -> Set[str]:
|
||||
"""
|
||||
1. Jinja2 Syntax-Analyse: Extrahiere alle url_for() Aufrufe
|
||||
"""
|
||||
print("🔍 PHASE 1: Template Endpoint-Analyse")
|
||||
|
||||
with open(self.template_path, 'r', encoding='utf-8') as f:
|
||||
template_content = f.read()
|
||||
|
||||
# Regex für url_for() Aufrufe in Jinja2-Templates
|
||||
url_for_pattern = r"{{\s*url_for\(['\"]([^'\"]+)['\"][^}]*\)\s*}}"
|
||||
matches = re.findall(url_for_pattern, template_content)
|
||||
|
||||
self.template_endpoints = set(matches)
|
||||
|
||||
print(f" ✓ Gefundene Template-Endpoints: {len(self.template_endpoints)}")
|
||||
for endpoint in sorted(self.template_endpoints):
|
||||
print(f" - {endpoint}")
|
||||
|
||||
return self.template_endpoints
|
||||
|
||||
def analyze_blueprint_routes(self) -> Set[str]:
|
||||
"""
|
||||
2. Backend Blueprint-Analyse: Scanne alle registrierten Routen
|
||||
"""
|
||||
print("\n🔍 PHASE 2: Blueprint Route-Analyse")
|
||||
|
||||
with open(self.blueprint_path, 'r', encoding='utf-8') as f:
|
||||
blueprint_content = f.read()
|
||||
|
||||
# Regex für Blueprint-Routen
|
||||
route_pattern = r'@admin_blueprint\.route\(["\']([^"\']+)["\'][^)]*\)\s*@admin_required\s*def\s+([a-zA-Z_][a-zA-Z0-9_]*)'
|
||||
matches = re.findall(route_pattern, blueprint_content, re.MULTILINE | re.DOTALL)
|
||||
|
||||
# Erstelle verfügbare Endpoints mit admin.-Prefix
|
||||
for route_path, function_name in matches:
|
||||
endpoint = f"admin.{function_name}"
|
||||
self.available_endpoints.add(endpoint)
|
||||
self.endpoint_mapping[function_name] = endpoint
|
||||
|
||||
# Zusätzlich: API-Blueprint-Routen
|
||||
api_route_pattern = r'@admin_api_blueprint\.route\(["\']([^"\']+)["\'][^)]*\)\s*@admin_required\s*def\s+([a-zA-Z_][a-zA-Z0-9_]*)'
|
||||
api_matches = re.findall(api_route_pattern, blueprint_content, re.MULTILINE | re.DOTALL)
|
||||
|
||||
for route_path, function_name in api_matches:
|
||||
endpoint = f"admin_api.{function_name}"
|
||||
self.available_endpoints.add(endpoint)
|
||||
self.endpoint_mapping[function_name] = endpoint
|
||||
|
||||
print(f" ✓ Verfügbare Blueprint-Endpoints: {len(self.available_endpoints)}")
|
||||
for endpoint in sorted(self.available_endpoints):
|
||||
print(f" - {endpoint}")
|
||||
|
||||
return self.available_endpoints
|
||||
|
||||
def cross_reference_validation(self) -> List[Dict]:
|
||||
"""
|
||||
3. Cross-Reference Validierung: Vergleiche Template vs. Blueprint
|
||||
"""
|
||||
print("\n🔍 PHASE 3: Cross-Reference Validierung")
|
||||
|
||||
# Finde fehlende oder falsche Referenzen
|
||||
missing_endpoints = self.template_endpoints - self.available_endpoints
|
||||
unused_endpoints = self.available_endpoints - self.template_endpoints
|
||||
|
||||
for endpoint in missing_endpoints:
|
||||
problem = {
|
||||
'type': 'missing_endpoint',
|
||||
'endpoint': endpoint,
|
||||
'description': f'Template referenziert nicht existierenden Endpoint: {endpoint}',
|
||||
'severity': 'critical'
|
||||
}
|
||||
|
||||
# Versuche ähnliche Endpoints zu finden
|
||||
suggestions = self._find_similar_endpoints(endpoint)
|
||||
if suggestions:
|
||||
problem['suggestions'] = suggestions
|
||||
|
||||
self.problems.append(problem)
|
||||
|
||||
print(f" ❌ Problematische Endpoints: {len(missing_endpoints)}")
|
||||
for endpoint in missing_endpoints:
|
||||
print(f" - {endpoint}")
|
||||
|
||||
print(f" ⚠️ Ungenutzte Endpoints: {len(unused_endpoints)}")
|
||||
for endpoint in unused_endpoints:
|
||||
print(f" - {endpoint}")
|
||||
|
||||
return self.problems
|
||||
|
||||
def _find_similar_endpoints(self, target: str) -> List[str]:
|
||||
"""
|
||||
Finde ähnliche Endpoints basierend auf String-Ähnlichkeit
|
||||
"""
|
||||
suggestions = []
|
||||
target_parts = target.split('.')
|
||||
|
||||
for available in self.available_endpoints:
|
||||
available_parts = available.split('.')
|
||||
|
||||
# Ähnlichkeits-Heuristiken
|
||||
if len(target_parts) == len(available_parts):
|
||||
# Gleiche Struktur
|
||||
if target_parts[-1] in available_parts[-1] or available_parts[-1] in target_parts[-1]:
|
||||
suggestions.append(available)
|
||||
|
||||
# Ähnliche Funktionsnamen
|
||||
if target_parts[-1] in available_parts[-1]:
|
||||
suggestions.append(available)
|
||||
|
||||
return suggestions[:3] # Maximal 3 Vorschläge
|
||||
|
||||
def generate_corrections(self) -> List[Dict]:
|
||||
"""
|
||||
4. Auto-Fix Generator: Generiere MultiEdit-Korrekturen
|
||||
"""
|
||||
print("\n🔧 PHASE 4: Korrektur-Generierung")
|
||||
|
||||
with open(self.template_path, 'r', encoding='utf-8') as f:
|
||||
template_content = f.read()
|
||||
|
||||
for problem in self.problems:
|
||||
if problem['type'] == 'missing_endpoint' and 'suggestions' in problem:
|
||||
old_endpoint = problem['endpoint']
|
||||
suggested_endpoint = problem['suggestions'][0] # Beste Suggestion
|
||||
|
||||
# Erstelle Korrektur
|
||||
old_pattern = f"url_for('{old_endpoint}'"
|
||||
new_pattern = f"url_for('{suggested_endpoint}'"
|
||||
|
||||
# Prüfe ob Pattern im Template vorkommt
|
||||
if old_pattern in template_content:
|
||||
correction = {
|
||||
'old_string': old_pattern,
|
||||
'new_string': new_pattern,
|
||||
'description': f'Korrigiere {old_endpoint} → {suggested_endpoint}',
|
||||
'confidence': 'high'
|
||||
}
|
||||
self.corrections.append(correction)
|
||||
|
||||
print(f" ✓ Generierte Korrekturen: {len(self.corrections)}")
|
||||
for correction in self.corrections:
|
||||
print(f" - {correction['description']}")
|
||||
|
||||
return self.corrections
|
||||
|
||||
def generate_report(self) -> Dict:
|
||||
"""
|
||||
Generiere strukturierten Analysebericht
|
||||
"""
|
||||
return {
|
||||
'summary': {
|
||||
'template_endpoints': len(self.template_endpoints),
|
||||
'available_endpoints': len(self.available_endpoints),
|
||||
'problems_found': len(self.problems),
|
||||
'corrections_generated': len(self.corrections)
|
||||
},
|
||||
'template_endpoints': list(self.template_endpoints),
|
||||
'available_endpoints': list(self.available_endpoints),
|
||||
'problems': self.problems,
|
||||
'corrections': self.corrections,
|
||||
'endpoint_mapping': self.endpoint_mapping
|
||||
}
|
||||
|
||||
def main():
|
||||
"""
|
||||
Hauptfunktion für Template-Analyse
|
||||
"""
|
||||
print("🚀 MYP Template-Analyse-Tool")
|
||||
print("=" * 50)
|
||||
|
||||
template_path = "/mnt/c/Users/TTOMCZA.EMEA/Dev/Projektarbeit-MYP/backend/templates/admin.html"
|
||||
blueprint_path = "/mnt/c/Users/TTOMCZA.EMEA/Dev/Projektarbeit-MYP/backend/blueprints/admin_unified.py"
|
||||
|
||||
analyzer = TemplateAnalyzer(template_path, blueprint_path)
|
||||
|
||||
# Durchführung der Analyse
|
||||
analyzer.analyze_template_endpoints()
|
||||
analyzer.analyze_blueprint_routes()
|
||||
analyzer.cross_reference_validation()
|
||||
analyzer.generate_corrections()
|
||||
|
||||
# Generiere Bericht
|
||||
report = analyzer.generate_report()
|
||||
|
||||
print("\n📊 ANALYSEBERICHT")
|
||||
print("=" * 50)
|
||||
print(f"Template-Endpoints: {report['summary']['template_endpoints']}")
|
||||
print(f"Verfügbare Endpoints: {report['summary']['available_endpoints']}")
|
||||
print(f"Gefundene Probleme: {report['summary']['problems_found']}")
|
||||
print(f"Generierte Korrekturen: {report['summary']['corrections_generated']}")
|
||||
|
||||
if report['problems']:
|
||||
print("\n❌ GEFUNDENE PROBLEME:")
|
||||
for i, problem in enumerate(report['problems'], 1):
|
||||
print(f" {i}. {problem['description']}")
|
||||
if 'suggestions' in problem:
|
||||
print(f" Vorschläge: {', '.join(problem['suggestions'])}")
|
||||
|
||||
if report['corrections']:
|
||||
print("\n🔧 EMPFOHLENE KORREKTUREN:")
|
||||
for i, correction in enumerate(report['corrections'], 1):
|
||||
print(f" {i}. {correction['description']}")
|
||||
print(f" Alt: {correction['old_string']}")
|
||||
print(f" Neu: {correction['new_string']}")
|
||||
|
||||
# Speichere Bericht als JSON
|
||||
with open('/mnt/c/Users/TTOMCZA.EMEA/Dev/Projektarbeit-MYP/backend/template_analysis_report.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(report, f, indent=2, ensure_ascii=False)
|
||||
|
||||
print(f"\n💾 Bericht gespeichert: template_analysis_report.json")
|
||||
|
||||
return report
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in New Issue
Block a user