Files
Projektarbeit-MYP/backend/manual_redundancy_analysis.py
Till Tomczak 7a99af7ace 🎉 Feat: Import & Function Analysis Tool Enhancements 🎉
This commit introduces a suite of tools for analyzing and optimizing imports and functions within the backend codebase. The following files have been updated:

- backend/FRONTEND_ASSETS_ANALYSE.md
- backend/REDUNDANZ_ANALYSE_FINAL.md
- backend/SOFORT_L\303\226SCHBARE_FUN
2025-06-19 18:13:18 +02:00

324 lines
12 KiB
Python

#!/usr/bin/env python3
"""
Manuelle detaillierte Redundanz-Analyse für MYP Backend
Fokussiert auf wirklich redundante und ungenutzte Funktionen
"""
import os
import re
import ast
from collections import defaultdict
def analyze_imports_and_calls():
"""Analysiert tatsächliche Importe und Funktionsaufrufe"""
backend_path = "/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend"
function_calls = set()
function_defs = {}
file_imports = defaultdict(set)
# Alle Python-Dateien durchgehen
for root, dirs, files in os.walk(backend_path):
# Ignoriere bestimmte Verzeichnisse
dirs[:] = [d for d in dirs if d not in ['.git', '__pycache__', 'node_modules', 'instance']]
for file in files:
if not file.endswith('.py'):
continue
file_path = os.path.join(root, file)
rel_path = os.path.relpath(file_path, backend_path)
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Funktionsaufrufe mit Regex finden (umfassender als AST)
# Direkte Funktionsaufrufe
direct_calls = re.findall(r'(\w+)\s*\(', content)
function_calls.update(direct_calls)
# Attributaufrufe (object.method())
attr_calls = re.findall(r'\.(\w+)\s*\(', content)
function_calls.update(attr_calls)
# Import-Aufrufe
import_calls = re.findall(r'from\s+[\w.]+\s+import\s+([\w,\s]+)', content)
for imports in import_calls:
for imp in imports.split(','):
function_calls.add(imp.strip())
# AST für Funktionsdefinitionen
try:
tree = ast.parse(content)
for node in ast.walk(tree):
if isinstance(node, ast.FunctionDef):
key = f"{rel_path}:{node.name}"
function_defs[key] = {
'name': node.name,
'file': rel_path,
'line': node.lineno,
'is_private': node.name.startswith('_'),
'is_dunder': node.name.startswith('__') and node.name.endswith('__'),
'decorators': [getattr(d, 'id', str(d)) for d in node.decorator_list]
}
except:
pass
except Exception as e:
print(f"Fehler bei {file_path}: {e}")
return function_calls, function_defs
def find_truly_unused_functions():
"""Findet wirklich ungenutzte Funktionen"""
function_calls, function_defs = analyze_imports_and_calls()
unused = []
for key, func in function_defs.items():
func_name = func['name']
# Ausschließen:
# 1. Dunder-Methoden (__init__, __str__, etc.)
# 2. Flask-Route-Handler (haben @app.route oder @blueprint.route)
# 3. Test-Funktionen
# 4. Main-Funktionen
# 5. Flask-Login required Methoden
if func['is_dunder']:
continue
if func_name in ['main', 'create_app']:
continue
if func_name.startswith('test_'):
continue
# Flask-Login required methods
if func_name in ['is_authenticated', 'is_active', 'is_anonymous', 'get_id']:
continue
# Flask-Route handlers (check decorators)
is_route_handler = any('route' in str(d) or 'login_required' in str(d)
for d in func['decorators'])
if is_route_handler:
continue
# Check if function is actually called
if func_name not in function_calls:
unused.append({
'key': key,
'name': func_name,
'file': func['file'],
'line': func['line'],
'is_private': func['is_private']
})
return unused
def find_duplicate_implementations():
"""Findet Funktionen mit sehr ähnlichen oder identischen Implementierungen"""
backend_path = "/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend"
# Bekannte Duplikate basierend auf Funktionsnamen
known_duplicates = [
# Status-Checking-Funktionen
('get_printer_status', 'check_printer_status', 'printer_status'),
('get_tapo_status', 'check_tapo_status', 'tapo_status'),
# Validation-Funktionen
('validate_email', 'check_email', 'is_valid_email'),
('validate_ip', 'check_ip', 'is_valid_ip'),
# Database-Helper
('get_db_session', 'create_session', 'db_session'),
('close_db', 'close_session', 'cleanup_db'),
# Logging-Funktionen
('log_error', 'error_log', 'write_error'),
('log_info', 'info_log', 'write_info'),
# User-Helper
('get_user_by_id', 'find_user', 'user_by_id'),
('check_permission', 'has_permission', 'validate_permission'),
# File-Handling
('upload_file', 'handle_upload', 'process_upload'),
('delete_file', 'remove_file', 'cleanup_file'),
]
duplicates = []
function_defs = {}
# Sammle alle Funktionsdefinitionen
for root, dirs, files in os.walk(backend_path):
dirs[:] = [d for d in dirs if d not in ['.git', '__pycache__', 'node_modules', 'instance']]
for file in files:
if not file.endswith('.py'):
continue
file_path = os.path.join(root, file)
rel_path = os.path.relpath(file_path, backend_path)
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
tree = ast.parse(content)
for node in ast.walk(tree):
if isinstance(node, ast.FunctionDef):
function_defs[node.name] = function_defs.get(node.name, [])
function_defs[node.name].append({
'file': rel_path,
'line': node.lineno,
'name': node.name
})
except:
continue
# Prüfe auf bekannte Duplikate
for duplicate_group in known_duplicates:
found_functions = []
for func_name in duplicate_group:
if func_name in function_defs:
found_functions.extend(function_defs[func_name])
if len(found_functions) > 1:
duplicates.append({
'group': duplicate_group,
'functions': found_functions,
'count': len(found_functions)
})
# Prüfe auf Funktionen mit identischen Namen in verschiedenen Dateien
for func_name, locations in function_defs.items():
if len(locations) > 1 and not func_name.startswith('_'):
duplicates.append({
'group': [func_name],
'functions': locations,
'count': len(locations),
'type': 'identical_names'
})
return duplicates
def analyze_utils_redundancy():
"""Analysiert Redundanz in utils/ Verzeichnis"""
utils_path = "/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/utils"
utils_files = []
for file in os.listdir(utils_path):
if file.endswith('.py') and file != '__init__.py':
utils_files.append(file)
# Kategorisiere Utils-Dateien nach Funktionalität
categories = {
'database': ['database_cleanup.py', 'database_suite.py', 'data_management.py'],
'security': ['security_suite.py', 'ip_security.py', 'ip_validation.py'],
'ssl': ['ssl_manager.py', 'ssl_suite.py'],
'job_management': ['job_scheduler.py', 'job_queue_system.py'],
'system': ['core_system.py', 'system_management.py'],
'monitoring': ['monitoring_analytics.py', 'audit_logger.py'],
'ui': ['ui_components.py', 'drag_drop_system.py'],
'utilities': ['utilities_collection.py', 'script_collection.py', 'development_tools.py']
}
redundant_categories = []
for category, files in categories.items():
existing_files = [f for f in files if f in utils_files]
if len(existing_files) > 1:
redundant_categories.append({
'category': category,
'files': existing_files,
'recommendation': f"Konsolidiere {len(existing_files)} {category}-bezogene Dateien"
})
return redundant_categories, utils_files
def analyze_blueprint_redundancy():
"""Analysiert Redundanz in blueprints/ Verzeichnis"""
blueprints_path = "/cbin/C0S1-cernel/C02L2/Dateiverwaltung/nextcloud/core/files/3_Beruf_Ausbildung_und_Schule/IHK-Abschlussprüfung/Projektarbeit-MYP/backend/blueprints"
blueprint_files = []
for file in os.listdir(blueprints_path):
if file.endswith('.py'):
blueprint_files.append(file)
# Identifiziere potentielle Duplikate
potential_duplicates = [
('api.py', 'api_simple.py'), # Zwei API-Blueprints
('admin_unified.py', 'sessions.py'), # Überlappende Admin-Funktionalität
]
duplicates = []
for file1, file2 in potential_duplicates:
if file1 in blueprint_files and file2 in blueprint_files:
duplicates.append({
'files': [file1, file2],
'reason': 'Potential functional overlap'
})
return duplicates, blueprint_files
def main():
"""Hauptanalyse"""
print("=" * 80)
print("MANUELLE REDUNDANZ-ANALYSE - MYP BACKEND")
print("=" * 80)
print("\n1. UNGENUTZTE FUNKTIONEN")
print("-" * 40)
unused = find_truly_unused_functions()
unused_public = [f for f in unused if not f['is_private']]
unused_private = [f for f in unused if f['is_private']]
print(f"🔴 Öffentliche ungenutzte Funktionen: {len(unused_public)}")
for func in unused_public[:10]: # Top 10
print(f" {func['file']}:{func['line']} - {func['name']}()")
print(f"\n🟡 Private ungenutzte Funktionen: {len(unused_private)}")
for func in unused_private[:5]: # Top 5
print(f" {func['file']}:{func['line']} - {func['name']}()")
print("\n2. DOPPELTE IMPLEMENTIERUNGEN")
print("-" * 40)
duplicates = find_duplicate_implementations()
for dup in duplicates[:5]: # Top 5
print(f"🔄 {dup['group']}: {dup['count']} Implementierungen")
for func in dup['functions']:
print(f" {func['file']}:{func['line']} - {func['name']}()")
print()
print("\n3. UTILS-VERZEICHNIS REDUNDANZ")
print("-" * 40)
redundant_categories, all_utils = analyze_utils_redundancy()
print(f"📁 Gesamt Utils-Dateien: {len(all_utils)}")
for cat in redundant_categories:
print(f"🔧 {cat['category'].upper()}: {cat['recommendation']}")
for file in cat['files']:
print(f" - {file}")
print()
print("\n4. BLUEPRINT REDUNDANZ")
print("-" * 40)
blueprint_duplicates, all_blueprints = analyze_blueprint_redundancy()
print(f"📁 Gesamt Blueprint-Dateien: {len(all_blueprints)}")
for dup in blueprint_duplicates:
print(f"🔄 Potentielle Duplikate: {' + '.join(dup['files'])}")
print(f" Grund: {dup['reason']}")
print("\n" + "=" * 80)
print("EMPFEHLUNGEN FÜR CLEANUP")
print("=" * 80)
print(f"1. 🗑️ Lösche {len(unused_public)} ungenutzte öffentliche Funktionen")
print(f"2. 🧹 Prüfe {len(unused_private)} ungenutzte private Funktionen")
print(f"3. 🔄 Konsolidiere {len(duplicates)} Duplikat-Gruppen")
print(f"4. 📁 Reorganisiere {len(redundant_categories)} Utils-Kategorien")
print(f"5. 🔗 Prüfe {len(blueprint_duplicates)} Blueprint-Überlappungen")
if __name__ == "__main__":
main()