Initial import: Carteasy Shop (Dev-Stand)

This commit is contained in:
Thomas Bartelt
2026-04-20 01:03:43 +02:00
commit d504f8a05d
3845 changed files with 761050 additions and 0 deletions
Binary file not shown.
+270
View File
@@ -0,0 +1,270 @@
#!/usr/bin/env python3
"""
🎛️ Intelectra AI Control Center - Flask Dashboard
Trackt KI-Besucher und steuert FAQ/Schema System
"""
from flask import Flask, render_template, request, jsonify, redirect, url_for, flash
import mysql.connector
import json
import re
from datetime import datetime, timedelta
import os
from config import DB_CONFIG
app = Flask(__name__)
app.secret_key = 'intelectra_ai_dashboard_secret_2025'
class AIAdminDashboard:
def __init__(self):
self.db_config = DB_CONFIG
# KI-Detection Patterns
self.ai_signatures = {
'ChatGPT': ['GPTBot', 'ChatGPT-User', 'OpenAI', 'gpt-crawler'],
'Claude': ['Claude-Web', 'Anthropic', 'Claude', 'anthropic'],
'Gemini': ['Google-Extended', 'Bard', 'Gemini', 'GoogleOther'],
'Perplexity': ['PerplexityBot', 'perplexity'],
'Bing AI': ['BingBot', 'EdgeBot', 'msnbot'],
'Meta AI': ['FacebookBot', 'Meta', 'facebookexternalhit'],
'You.com': ['YouBot', 'you.com'],
'SearchGPT': ['SearchGPT', 'OpenAI-SearchBot']
}
def get_db_connection(self):
"""Sichere DB-Verbindung"""
try:
return mysql.connector.connect(**self.db_config)
except Exception as e:
print(f"DB Connection failed: {e}")
return None
def detect_ai_visitor(self, user_agent, referer=''):
"""Erkennt KI-Besucher anhand User-Agent & Referer"""
user_agent = user_agent.lower()
referer = referer.lower()
for ai_name, signatures in self.ai_signatures.items():
for signature in signatures:
if signature.lower() in user_agent or signature.lower() in referer:
return ai_name
return None
def log_ai_visit(self, ai_name, url, user_agent, ip_address, referer=''):
"""Loggt KI-Besuch in Datenbank"""
try:
conn = self.get_db_connection()
if not conn:
return False
cursor = conn.cursor()
# Artikel-ID aus URL extrahieren
article_id = None
url_match = re.search(r'/artikel/(\d+)', url)
if url_match:
article_id = int(url_match.group(1))
query = """
INSERT INTO ai_visitor_log
(ai_name, url, article_id, user_agent, ip_address, referer, visited_at)
VALUES (%s, %s, %s, %s, %s, %s, %s)
"""
cursor.execute(query, (ai_name, url, article_id, user_agent, ip_address, referer, datetime.now()))
conn.commit()
cursor.close()
conn.close()
return True
except Exception as e:
print(f"AI visit logging failed: {e}")
return False
def get_ai_stats(self, days=7):
"""Holt KI-Statistiken der letzten N Tage"""
try:
conn = self.get_db_connection()
if not conn:
return {}
cursor = conn.cursor(dictionary=True)
# Basis-Statistiken
since_date = datetime.now() - timedelta(days=days)
# KI-Besuche pro AI
cursor.execute("""
SELECT ai_name, COUNT(*) as visit_count,
COUNT(DISTINCT ip_address) as unique_visitors
FROM ai_visitor_log
WHERE visited_at >= %s
GROUP BY ai_name
ORDER BY visit_count DESC
""", (since_date,))
ai_visits = cursor.fetchall()
# Top besuchte Artikel
cursor.execute("""
SELECT avl.article_id, COUNT(*) as visit_count,
GROUP_CONCAT(DISTINCT avl.ai_name) as visiting_ais
FROM ai_visitor_log avl
WHERE avl.visited_at >= %s AND avl.article_id IS NOT NULL
GROUP BY avl.article_id
ORDER BY visit_count DESC
LIMIT 10
""", (since_date,))
top_articles = cursor.fetchall()
# Zeitverteilung (Stunden)
cursor.execute("""
SELECT HOUR(visited_at) as hour, COUNT(*) as visits
FROM ai_visitor_log
WHERE visited_at >= %s
GROUP BY HOUR(visited_at)
ORDER BY hour
""", (since_date,))
hourly_distribution = cursor.fetchall()
cursor.close()
conn.close()
return {
'ai_visits': ai_visits,
'top_articles': top_articles,
'hourly_distribution': hourly_distribution,
'period_days': days
}
except Exception as e:
print(f"Stats retrieval failed: {e}")
return {}
# Flask Dashboard Routes
dashboard = AIAdminDashboard()
@app.route('/')
def dashboard_home():
"""Hauptdashboard mit KI-Statistiken"""
stats = dashboard.get_ai_stats(days=7)
return render_template('dashboard.html', stats=stats)
@app.route('/faq-management')
def faq_management():
"""FAQ/Problem Management Interface"""
try:
conn = dashboard.get_db_connection()
cursor = conn.cursor(dictionary=True)
# Alle Probleme laden
cursor.execute("""
SELECT * FROM problem_solutions
WHERE active = TRUE
ORDER BY frequency_score DESC
""")
problems = cursor.fetchall()
cursor.close()
conn.close()
return render_template('faq_management.html', problems=problems)
except Exception as e:
flash(f'Error loading problems: {e}', 'error')
return redirect(url_for('dashboard_home'))
@app.route('/add-problem', methods=['GET', 'POST'])
def add_problem():
"""Neues Problem hinzufügen"""
if request.method == 'POST':
try:
conn = dashboard.get_db_connection()
cursor = conn.cursor()
# Form-Daten extrahieren
data = {
'problem_category': request.form['category'],
'problem_title': request.form['title'],
'problem_description': request.form['description'],
'symptoms': json.dumps(request.form['symptoms'].split('\n')),
'keywords': json.dumps(request.form['keywords'].split(',')),
'urgency_level': request.form['urgency'],
'repair_complexity': request.form['complexity'],
'frequency_score': int(request.form.get('frequency', 50))
}
query = """
INSERT INTO problem_solutions
(problem_category, problem_title, problem_description, symptoms,
keywords, urgency_level, repair_complexity, frequency_score)
VALUES (%(problem_category)s, %(problem_title)s, %(problem_description)s,
%(symptoms)s, %(keywords)s, %(urgency_level)s,
%(repair_complexity)s, %(frequency_score)s)
"""
cursor.execute(query, data)
conn.commit()
cursor.close()
conn.close()
flash('Problem erfolgreich hinzugefügt!', 'success')
return redirect(url_for('faq_management'))
except Exception as e:
flash(f'Error adding problem: {e}', 'error')
return render_template('add_problem.html')
@app.route('/api/ai-visits')
def api_ai_visits():
"""API Endpoint für Live AI-Visit Updates"""
stats = dashboard.get_ai_stats(days=1)
return jsonify(stats)
@app.route('/api/detect-visitor', methods=['POST'])
def api_detect_visitor():
"""API Endpoint für KI-Visitor Detection (wird vom PHP Shop aufgerufen)"""
try:
data = request.json
user_agent = data.get('user_agent', '')
url = data.get('url', '')
ip_address = data.get('ip_address', '')
referer = data.get('referer', '')
# KI erkennen
ai_name = dashboard.detect_ai_visitor(user_agent, referer)
if ai_name:
# In DB loggen
dashboard.log_ai_visit(ai_name, url, user_agent, ip_address, referer)
return jsonify({
'ai_detected': True,
'ai_name': ai_name,
'logged': True
})
else:
return jsonify({
'ai_detected': False,
'ai_name': None,
'logged': False
})
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/schema-preview/<int:article_id>')
def schema_preview(article_id):
"""Live Preview des generierten AI Schemas für einen Artikel"""
# Hier würde das AI Schema für den Artikel generiert und angezeigt
return render_template('schema_preview.html', article_id=article_id)
if __name__ == '__main__':
# Development Server - NUR für Testing!
app.run(host='127.0.0.1', port=5000, debug=True)
+346
View File
@@ -0,0 +1,346 @@
#!/usr/bin/env python3
"""
🤖 AI Shopping Schema Generator - Intelectra
Erzeugt KI-optimierte JSON-LD Schemas für bessere AI-Findbarkeit
SICHER: Läuft komplett isoliert, keine Live-Shop Auswirkungen!
"""
import json
import sys
import re
from datetime import datetime
import os
class AIShoppingSchemaGenerator:
def __init__(self):
self.base_url = "https://intelectra.de"
self.safety_icon_base = "/themes/theme2/media/images/safety/"
def generate_schema(self, item_data):
"""Erzeugt KI-optimiertes Schema für einen Artikel"""
try:
schema = {
"@context": "https://schema.org",
"@type": "Product",
"name": item_data.get('name', ''),
"identifier": f"intelectra-{item_data.get('item_id', '')}",
"category": "Elektro-Ersatzteil",
"url": f"{self.base_url}/artikel/{item_data.get('item_id', '')}",
# Timestamp für Monitoring
"_meta": {
"generated": datetime.now().isoformat(),
"generator": "AI Shopping Schema v1.0",
"source": "intelectra_live_shop"
}
}
# Sicherheitshinweise hinzufügen (wenn vorhanden)
if item_data.get('warnings'):
schema["safetyConsiderations"] = self.build_safety_schema(item_data['warnings'])
# Problem-Solution-Mapping (Smart Feature!)
schema["solves"] = self.build_problem_solutions(item_data)
# Kompatibilitäts-Informationen
if item_data.get('attributes'):
schema["compatibleWith"] = self.build_compatibility_schema(item_data['attributes'])
# Installations-Hinweise
schema["installationHints"] = self.generate_installation_hints(item_data)
return schema
except Exception as e:
self.log_error(f"Schema generation failed: {str(e)}")
return None
def build_safety_schema(self, warnings):
"""Konvertiert Sicherheitshinweise in KI-optimiertes Format"""
safety_considerations = []
for warning in warnings:
consideration = {
"@type": "SafetyConsideration",
"name": warning.get('name', ''),
"description": warning.get('beschreibung', ''),
"warningLevel": self.detect_warning_level(warning.get('name', '')),
"iconPath": f"{self.safety_icon_base}{warning.get('image_filename', '')}"
}
# Intelligente Kategorisierung
if "elektrisch" in warning.get('name', '').lower():
consideration["category"] = "electrical_hazard"
consideration["preventiveMeasures"] = ["Netzstecker ziehen", "Spannungsfreiheit prüfen"]
elif "quetsch" in warning.get('name', '').lower():
consideration["category"] = "mechanical_hazard"
consideration["preventiveMeasures"] = ["Schutzhandschuhe tragen", "Vorsichtig arbeiten"]
safety_considerations.append(consideration)
return safety_considerations
def build_problem_solutions(self, item_data):
"""🚀 UNIVERSAL PROBLEM-SOLUTION ENGINE - Der komplette Motor!"""
name = item_data.get('name', '').lower()
solutions = []
# 🚰 WASSERSYSTEM - Pumpen, Schläuche, Ventile
if any(word in name for word in ['pumpe', 'pump', 'ablaufpumpe', 'laugenpumpe']):
solutions.append({
"@type": "ProblemSolution",
"problem": "Wasser läuft nicht ab / Pumpe defekt",
"symptoms": ["Gerät pumpt nicht", "Wasser steht", "Ablauf verstopft", "Pumpe brummt", "E20 Fehler", "E03 Fehler", "F03 Fehler", "OE Fehler", "5E Fehler"],
"urgencyLevel": "HIGH",
"repairComplexity": "MEDIUM",
"problemKeywords": ["pumpe defekt", "wasser läuft nicht ab", "ablauf verstopft", "e20 fehler", "pumpe brummt", "f03 fehler"]
})
if any(word in name for word in ['schlauch', 'aquastop', 'zulaufschlauch', 'ablaufschlauch']):
solutions.append({
"@type": "ProblemSolution",
"problem": "Wasserschlauch defekt / Undichtigkeit",
"symptoms": ["Wasser tropft", "Schlauch porös", "Undichtigkeit", "Aquastop löst aus", "E10 Fehler", "F17 Fehler"],
"urgencyLevel": "HIGH",
"repairComplexity": "EASY",
"problemKeywords": ["schlauch kaputt", "wasser tropft", "undicht", "aquastop piepst", "e10 fehler"]
})
# 🔥 HEIZSYSTEM - Heizstäbe, Thermostate, NTC
if any(word in name for word in ['heizstab', 'heizung', 'thermostat', 'ntc', 'temperaturfühler']):
solutions.append({
"@type": "ProblemSolution",
"problem": "Gerät heizt nicht / Temperaturproblem",
"symptoms": ["Kein warmes Wasser", "Geschirr bleibt kalt", "Heizung defekt", "E15 Fehler", "F25 Fehler", "E01 Fehler"],
"urgencyLevel": "MEDIUM",
"repairComplexity": "MEDIUM",
"problemKeywords": ["heizt nicht", "kein warmes wasser", "heizstab defekt", "e15 fehler", "f25 fehler"]
})
# ⚡ MOTOREN - Antriebsmotoren, Umwälzpumpen
if any(word in name for word in ['motor', 'antrieb', 'antriebsmotor', 'umwälzpumpe']):
solutions.append({
"@type": "ProblemSolution",
"problem": "Motor dreht nicht / Antrieb defekt",
"symptoms": ["Trommel dreht nicht", "Motor brummt", "Gerät startet nicht", "F21 Fehler", "E02 Fehler", "F34 Fehler"],
"urgencyLevel": "HIGH",
"repairComplexity": "HARD",
"problemKeywords": ["motor defekt", "trommel dreht nicht", "motor brummt", "f21 fehler", "antrieb kaputt"]
})
# 🚪 TÜRSYSTEM - Türschloss, Türdichtung, Türgriff
if any(word in name for word in ['türschloss', 'türgriff', 'türdichtung', 'door lock', 'handle']):
solutions.append({
"@type": "ProblemSolution",
"problem": "Tür schließt nicht / Türproblem",
"symptoms": ["Tür geht nicht zu", "Türschloss defekt", "Wasser tropft aus Tür", "E01 Fehler", "F16 Fehler"],
"urgencyLevel": "MEDIUM",
"repairComplexity": "EASY",
"problemKeywords": ["tür geht nicht zu", "türschloss defekt", "türgriff kaputt", "e01 fehler"]
})
# ⚙️ MECHANIK - Stoßdämpfer, Federn, Lager, Riemen
if any(word in name for word in ['stoßdämpfer', 'feder', 'lager', 'riemen', 'keilriemen']):
solutions.append({
"@type": "ProblemSolution",
"problem": "Mechanik defekt / Geräusche beim Betrieb",
"symptoms": ["Komische Geräusche", "Gerät wackelt", "Vibrationen", "Quietschen", "Schleifen"],
"urgencyLevel": "MEDIUM",
"repairComplexity": "MEDIUM",
"problemKeywords": ["komische geräusche", "gerät wackelt", "quietscht", "schleift", "vibriert"]
})
# 🔌 ELEKTRONIK - Platinen, Sensoren, Timer
if any(word in name for word in ['platine', 'steuerung', 'elektronik', 'sensor', 'timer', 'display']):
solutions.append({
"@type": "ProblemSolution",
"problem": "Elektronik defekt / Steuerungsproblem",
"symptoms": ["Display zeigt Fehler", "Programm startet nicht", "Tasten reagieren nicht", "F-Fehler", "E-Fehler"],
"urgencyLevel": "HIGH",
"repairComplexity": "HARD",
"problemKeywords": ["display defekt", "steuerung kaputt", "f fehler", "e fehler", "platine defekt"]
})
# 🧽 FILTER & REINIGUNG
if any(word in name for word in ['filter', 'sieb', 'flusensieb', 'wasserfilter']):
solutions.append({
"@type": "ProblemSolution",
"problem": "Filter verstopft / Reinigungsproblem",
"symptoms": ["Schlechte Waschleistung", "Filter verstopft", "Geruch", "Wasser trüb"],
"urgencyLevel": "LOW",
"repairComplexity": "EASY",
"problemKeywords": ["filter verstopft", "schlechte waschleistung", "geruch", "flusensieb"]
})
# 💡 BELEUCHTUNG - Lampen, LEDs
if any(word in name for word in ['lampe', 'led', 'birne', 'leuchte', 'beleuchtung']):
solutions.append({
"@type": "ProblemSolution",
"problem": "Beleuchtung defekt / Licht geht nicht",
"symptoms": ["Licht geht nicht an", "LED defekt", "Birne kaputt", "Dunkel im Gerät"],
"urgencyLevel": "LOW",
"repairComplexity": "EASY",
"problemKeywords": ["licht geht nicht", "led defekt", "birne kaputt", "beleuchtung aus"]
})
return solutions
def build_compatibility_schema(self, attributes):
"""Extrahiert Kompatibilitäts-Informationen aus Attributen"""
compatible_brands = []
# Pattern für bekannte Marken (Intelectra-optimiert)
brand_patterns = {
'bsh': ['siemens', 'bosch', 'neff', 'gaggenau', 'constructa'],
'whirlpool': ['whirlpool', 'bauknecht', 'privileg', 'ignis'],
'electrolux': ['electrolux', 'aeg', 'zanussi'],
'miele': ['miele'],
'liebherr': ['liebherr'],
'amica': ['amica', 'hansa']
}
# Suche nach Marken in Attributen
for attr_key, attr_value in attributes.items():
if isinstance(attr_value, str):
for brand_group, brands in brand_patterns.items():
if any(brand in attr_value.lower() for brand in brands):
compatible_brands.extend(brands)
return {
"brands": list(set(compatible_brands)),
"applianceTypes": self.detect_appliance_types(attributes)
}
def detect_appliance_types(self, attributes):
"""Erkennt Gerätetypen aus Attributen"""
types = []
# Pattern Recognition für Gerätetypen
type_keywords = {
"Waschmaschine": ["waschmaschine", "washing", "wäsche"],
"Geschirrspüler": ["geschirrspüler", "dishwasher", "spülmaschine"],
"Kühlschrank": ["kühlschrank", "refrigerator", "kühl"],
"Backofen": ["backofen", "oven", "herd"],
"Trockner": ["trockner", "wäschetrockner", "dryer"]
}
for attr_value in attributes.values():
if isinstance(attr_value, str):
for appliance, keywords in type_keywords.items():
if any(keyword in attr_value.lower() for keyword in keywords):
types.append(appliance)
return list(set(types))
def generate_installation_hints(self, item_data):
"""Generiert intelligente Installations-Hinweise"""
name = item_data.get('name', '').lower()
if 'schlauch' in name:
return {
"difficulty": "Einfach - ohne Fachmann machbar",
"timeRequired": "5-10 Minuten",
"toolsNeeded": ["Zange", "Schraubendreher"],
"safetyNote": "Wasser abstellen vor Montage"
}
elif 'pumpe' in name:
return {
"difficulty": "Mittel - handwerkliches Geschick nötig",
"timeRequired": "30-45 Minuten",
"toolsNeeded": ["Schraubendreher", "Zange", "Multimeter"],
"safetyNote": "Strom abstellen! Gerät vom Netz trennen"
}
elif 'heizstab' in name:
return {
"difficulty": "Schwer - Fachmann empfohlen",
"timeRequired": "60-90 Minuten",
"toolsNeeded": ["Multimeter", "Spezialwerkzeug"],
"safetyNote": "⚠️ HOCHSPANNUNG! Strom komplett abschalten"
}
return {
"difficulty": "Mittlere Schwierigkeit",
"timeRequired": "15-30 Minuten",
"safetyNote": "Sicherheitshinweise beachten"
}
def detect_warning_level(self, warning_name):
"""Intelligente Warnstufen-Erkennung"""
name_lower = warning_name.lower()
if any(word in name_lower for word in ['elektrisch', 'strom', 'spannung']):
return "CRITICAL"
elif any(word in name_lower for word in ['heiß', 'temperatur', 'verbrennung']):
return "HIGH"
elif any(word in name_lower for word in ['quetsch', 'verletzung']):
return "MEDIUM"
else:
return "LOW"
def save_schema(self, schema, item_id):
"""Speichert Schema für späteren Abruf (optional)"""
try:
schema_dir = "/var/www/vhosts/intelectra.de/httpdocs/core/python/logs"
os.makedirs(schema_dir, exist_ok=True)
schema_file = f"{schema_dir}/schema_{item_id}.json"
with open(schema_file, 'w', encoding='utf-8') as f:
json.dump(schema, f, indent=2, ensure_ascii=False)
return True
except Exception as e:
self.log_error(f"Schema save failed: {str(e)}")
return False
def log_error(self, message):
"""Fehler-Logging"""
try:
log_dir = "/var/www/vhosts/intelectra.de/httpdocs/core/python/logs"
os.makedirs(log_dir, exist_ok=True)
log_file = f"{log_dir}/ai_schema.log"
timestamp = datetime.now().isoformat()
with open(log_file, 'a', encoding='utf-8') as f:
f.write(f"{timestamp} ERROR: {message}\n")
except:
pass # Silent fail für Live-Shop
def main():
"""Hauptfunktion - wird von PHP aufgerufen"""
if len(sys.argv) < 2:
print(json.dumps({"error": "No input data provided"}))
sys.exit(1)
try:
# Input von PHP parsen
input_data = json.loads(sys.argv[1])
# Schema Generator initialisieren
generator = AIShoppingSchemaGenerator()
# Schema erzeugen
schema = generator.generate_schema(input_data)
if schema:
# Optional: Schema speichern
generator.save_schema(schema, input_data.get('item_id', 'unknown'))
# Erfolg zurückgeben
result = {
"success": True,
"schema_generated": True,
"item_id": input_data.get('item_id'),
"timestamp": datetime.now().isoformat()
}
else:
result = {"success": False, "error": "Schema generation failed"}
print(json.dumps(result))
except Exception as e:
error_result = {"success": False, "error": str(e)}
print(json.dumps(error_result))
sys.exit(1)
if __name__ == "__main__":
main()
+192
View File
@@ -0,0 +1,192 @@
<?php
/**
* 🕵️ AI Visitor Tracker Integration für Intelectra Shop
* Erkennt KI-Besucher und loggt sie automatisch
*
* USAGE: Include in item.class.php oder header.php
*/
class AIVisitorTracker {
private $flask_dashboard_url = 'http://127.0.0.1:5000';
public function trackVisitor() {
// Visitor-Daten sammeln
$visitor_data = [
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
'url' => $_SERVER['REQUEST_URI'] ?? '',
'ip_address' => $this->getRealIPAddress(),
'referer' => $_SERVER['HTTP_REFERER'] ?? '',
'timestamp' => date('Y-m-d H:i:s')
];
// Async call zum Flask Dashboard (non-blocking)
$this->sendToFlaskDashboard($visitor_data);
}
private function getRealIPAddress() {
// Echte IP ermitteln (auch hinter Proxies)
$ip_headers = [
'HTTP_CF_CONNECTING_IP', // Cloudflare
'HTTP_CLIENT_IP', // Proxy
'HTTP_X_FORWARDED_FOR', // Load Balancer
'HTTP_X_FORWARDED',
'HTTP_X_CLUSTER_CLIENT_IP',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'REMOTE_ADDR' // Standard
];
foreach ($ip_headers as $header) {
if (!empty($_SERVER[$header])) {
$ip = $_SERVER[$header];
// Bei mehreren IPs die erste nehmen
if (strpos($ip, ',') !== false) {
$ip = trim(explode(',', $ip)[0]);
}
// IP validieren
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
return $ip;
}
}
}
return $_SERVER['REMOTE_ADDR'] ?? 'unknown';
}
private function sendToFlaskDashboard($data) {
// Non-blocking cURL request zum Flask Dashboard
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $this->flask_dashboard_url . '/api/detect-visitor',
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'User-Agent: Intelectra-AI-Tracker/1.0'
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 2, // Max 2 Sekunden warten
CURLOPT_CONNECTTIMEOUT => 1, // Max 1 Sekunde für Verbindung
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_SSL_VERIFYPEER => false
]);
// Async ausführen (non-blocking)
$this->execInBackground($ch);
}
private function execInBackground($ch) {
// cURL im Hintergrund ausführen ohne auf Antwort zu warten
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 100); // Sehr kurzer Timeout
@curl_exec($ch); // @ um Fehler zu unterdrücken
curl_close($ch);
}
/**
* Intelligente KI-Erkennung (falls Flask nicht verfügbar)
*/
public function detectAILocally($user_agent) {
$ai_patterns = [
'ChatGPT' => ['GPTBot', 'ChatGPT-User', 'OpenAI', 'gpt-crawler'],
'Claude' => ['Claude-Web', 'Anthropic', 'claude.ai'],
'Gemini' => ['Google-Extended', 'Bard', 'Gemini', 'GoogleOther'],
'Perplexity' => ['PerplexityBot', 'perplexity.ai'],
'Bing AI' => ['BingBot', 'EdgeBot', 'bing.com/chat'],
'Meta AI' => ['FacebookBot', 'facebookexternalhit'],
'You.com' => ['YouBot'],
'SearchGPT' => ['SearchGPT', 'OpenAI-SearchBot']
];
$user_agent_lower = strtolower($user_agent);
foreach ($ai_patterns as $ai_name => $patterns) {
foreach ($patterns as $pattern) {
if (strpos($user_agent_lower, strtolower($pattern)) !== false) {
return $ai_name;
}
}
}
return null;
}
/**
* Log AI-Besuch direkt in MySQL (Fallback)
*/
public function logAIVisitDirectly($ai_name, $visitor_data) {
try {
// DB-Verbindung (hier deine DB-Credentials einsetzen)
$pdo = new PDO(
'mysql:host=localhost;dbname=intelectra_problems;charset=utf8mb4',
'ai_schema_user',
'your_password_here'
);
// Artikel-ID aus URL extrahieren
$article_id = null;
if (preg_match('/\/artikel\/(\d+)/', $visitor_data['url'], $matches)) {
$article_id = intval($matches[1]);
}
$stmt = $pdo->prepare("
INSERT INTO ai_visitor_log
(ai_name, url, article_id, user_agent, ip_address, referer, visited_at)
VALUES (?, ?, ?, ?, ?, ?, NOW())
");
$stmt->execute([
$ai_name,
$visitor_data['url'],
$article_id,
$visitor_data['user_agent'],
$visitor_data['ip_address'],
$visitor_data['referer']
]);
return true;
} catch (Exception $e) {
// Silent fail - Live Shop darf nicht gestört werden
error_log("AI Tracking failed: " . $e->getMessage());
return false;
}
}
/**
* Public API für Integration in Shop
*/
public static function track() {
$tracker = new self();
$tracker->trackVisitor();
}
public static function isAI($user_agent) {
$tracker = new self();
return $tracker->detectAILocally($user_agent);
}
}
// Auto-Track wenn direkt aufgerufen
if (basename(__FILE__) == basename($_SERVER['SCRIPT_NAME'])) {
AIVisitorTracker::track();
}
/**
* INTEGRATION BEISPIELE:
*
* 1. In item.class.php am Ende von buildSingleItem():
* require_once 'ai_tracker_integration.php';
* AIVisitorTracker::track();
*
* 2. In header.php/index.php:
* include_once 'core/python/ai_tracker_integration.php';
* AIVisitorTracker::track();
*
* 3. Als separater Tracker:
* $ai_name = AIVisitorTracker::isAI($_SERVER['HTTP_USER_AGENT']);
* if ($ai_name) {
* echo "<!-- AI erkannt: $ai_name -->";
* }
*/
?>
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/env python3
"""
🔧 Configuration für Enhanced AI Schema Generator
Sichere DB-Konfiguration für Live-Shop
"""
import os
# Database Configuration
# Diese Werte sollten in einer sicheren Umgebung gesetzt werden
DB_CONFIG = {
'host': os.getenv('DB_HOST', 'localhost'),
'database': os.getenv('DB_NAME', 'intelectra_problems'), # Separate DB für Probleme
'user': os.getenv('DB_USER', 'ai_schema_user'),
'password': os.getenv('DB_PASSWORD', ''),
'charset': 'utf8mb4',
'use_unicode': True,
'autocommit': True
}
# Fallback-Modus aktivieren falls DB nicht verfügbar
ENABLE_FALLBACK = True
# Logging Configuration
LOG_DIR = "/var/www/vhosts/intelectra.de/httpdocs/core/python/logs"
SCHEMA_SAVE_DIR = "/var/www/vhosts/intelectra.de/httpdocs/core/python/logs"
# API Configuration
BASE_URL = "https://intelectra.de"
SAFETY_ICON_BASE = "/web/intelectra_shop/themes/theme2/media/images/safety/"
+148
View File
@@ -0,0 +1,148 @@
-- 🕵️ AI Visitor Tracking Database Schema
-- Trackt welche KI wann welche Artikel besucht
-- Haupt-Tabelle: AI Visitor Log
CREATE TABLE ai_visitor_log (
id INT AUTO_INCREMENT PRIMARY KEY,
ai_name VARCHAR(50) NOT NULL, -- 'ChatGPT', 'Claude', 'Gemini', etc.
url VARCHAR(500) NOT NULL, -- Besuchte URL
article_id INT NULL, -- Extrahierte Artikel-ID (falls Artikel-Seite)
user_agent TEXT, -- Kompletter User-Agent String
ip_address VARCHAR(45), -- IP (IPv4/IPv6)
referer VARCHAR(500), -- Referer URL
visited_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- Indizes für Performance
INDEX idx_ai_name (ai_name),
INDEX idx_article_id (article_id),
INDEX idx_visited_at (visited_at),
INDEX idx_ai_article (ai_name, article_id)
);
-- AI Performance Stats (aggregierte Daten)
CREATE TABLE ai_performance_stats (
id INT AUTO_INCREMENT PRIMARY KEY,
ai_name VARCHAR(50) NOT NULL,
article_id INT NOT NULL,
visit_count INT DEFAULT 1,
first_visit TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_visit TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
conversion_count INT DEFAULT 0, -- Spätere Erweiterung für Kaufabschlüsse
UNIQUE KEY unique_ai_article (ai_name, article_id),
INDEX idx_ai_performance (ai_name, visit_count DESC)
);
-- AI Schema Generation Log
CREATE TABLE ai_schema_generation_log (
id INT AUTO_INCREMENT PRIMARY KEY,
article_id INT NOT NULL,
schema_type ENUM('product', 'problem_solution', 'safety') NOT NULL,
generated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
generation_time_ms INT, -- Performance Monitoring
problems_found INT DEFAULT 0, -- Anzahl gefundener Probleme
schema_size_kb DECIMAL(6,2), -- Schema-Größe in KB
success BOOLEAN DEFAULT TRUE,
error_message TEXT NULL,
INDEX idx_article_generation (article_id, generated_at),
INDEX idx_performance (generation_time_ms, generated_at)
);
-- User-Agent Patterns für bessere KI-Erkennung
CREATE TABLE ai_detection_patterns (
id INT AUTO_INCREMENT PRIMARY KEY,
ai_name VARCHAR(50) NOT NULL,
pattern VARCHAR(200) NOT NULL,
pattern_type ENUM('user_agent', 'referer', 'ip_range') DEFAULT 'user_agent',
confidence_score DECIMAL(3,2) DEFAULT 1.0, -- 0.0 - 1.0 Wahrscheinlichkeit
active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_matched TIMESTAMP NULL,
match_count INT DEFAULT 0,
INDEX idx_ai_patterns (ai_name, active),
INDEX idx_pattern_type (pattern_type)
);
-- Initial AI Detection Patterns
INSERT INTO ai_detection_patterns (ai_name, pattern, pattern_type, confidence_score) VALUES
-- ChatGPT/OpenAI
('ChatGPT', 'GPTBot', 'user_agent', 1.0),
('ChatGPT', 'ChatGPT-User', 'user_agent', 1.0),
('ChatGPT', 'OpenAI', 'user_agent', 0.9),
('ChatGPT', 'gpt-crawler', 'user_agent', 0.8),
-- Claude/Anthropic
('Claude', 'Claude-Web', 'user_agent', 1.0),
('Claude', 'Anthropic', 'user_agent', 0.9),
('Claude', 'claude.ai', 'referer', 1.0),
-- Google Gemini/Bard
('Gemini', 'Google-Extended', 'user_agent', 1.0),
('Gemini', 'Bard', 'user_agent', 1.0),
('Gemini', 'Gemini', 'user_agent', 1.0),
('Gemini', 'GoogleOther', 'user_agent', 0.7),
('Gemini', 'bard.google.com', 'referer', 1.0),
-- Perplexity
('Perplexity', 'PerplexityBot', 'user_agent', 1.0),
('Perplexity', 'perplexity.ai', 'referer', 1.0),
-- Microsoft Bing AI
('Bing AI', 'BingBot', 'user_agent', 0.8),
('Bing AI', 'EdgeBot', 'user_agent', 0.9),
('Bing AI', 'bing.com/chat', 'referer', 1.0),
-- Meta AI
('Meta AI', 'FacebookBot', 'user_agent', 0.7),
('Meta AI', 'facebookexternalhit', 'user_agent', 0.8),
-- Weitere aufkommende KIs
('You.com', 'YouBot', 'user_agent', 1.0),
('SearchGPT', 'SearchGPT', 'user_agent', 1.0),
('SearchGPT', 'OpenAI-SearchBot', 'user_agent', 1.0);
-- Trigger für automatische Performance Stats Update
DELIMITER $$
CREATE TRIGGER update_ai_performance_stats
AFTER INSERT ON ai_visitor_log
FOR EACH ROW
BEGIN
IF NEW.article_id IS NOT NULL THEN
INSERT INTO ai_performance_stats (ai_name, article_id, visit_count, first_visit, last_visit)
VALUES (NEW.ai_name, NEW.article_id, 1, NEW.visited_at, NEW.visited_at)
ON DUPLICATE KEY UPDATE
visit_count = visit_count + 1,
last_visit = NEW.visited_at;
END IF;
END$$
DELIMITER ;
-- View für Dashboard: Tägliche AI Stats
CREATE VIEW daily_ai_stats AS
SELECT
DATE(visited_at) as visit_date,
ai_name,
COUNT(*) as total_visits,
COUNT(DISTINCT ip_address) as unique_visitors,
COUNT(DISTINCT article_id) as articles_visited,
AVG(CASE WHEN article_id IS NOT NULL THEN 1 ELSE 0 END) as article_visit_rate
FROM ai_visitor_log
WHERE visited_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY DATE(visited_at), ai_name
ORDER BY visit_date DESC, total_visits DESC;
-- View für Top AI-besuchte Artikel
CREATE VIEW top_ai_articles AS
SELECT
article_id,
SUM(visit_count) as total_ai_visits,
COUNT(DISTINCT ai_name) as different_ais,
GROUP_CONCAT(DISTINCT ai_name ORDER BY visit_count DESC) as top_ais,
MAX(last_visit) as latest_ai_visit
FROM ai_performance_stats
WHERE article_id IS NOT NULL
GROUP BY article_id
ORDER BY total_ai_visits DESC
LIMIT 50;
+274
View File
@@ -0,0 +1,274 @@
-- 🗄️ Problem-FAQ-Database Creation Script - Intelectra AI Schema System
-- Erzeugt dynamische Problem-Solution-Datenbank für KI-Optimierung
-- Haupt-Tabelle: problem_solutions
CREATE TABLE problem_solutions (
id INT AUTO_INCREMENT PRIMARY KEY,
-- Problem-Kategorisierung
problem_category ENUM(
'heating', 'pumping', 'door_system', 'motor_drive',
'electronics', 'mechanical', 'filters', 'lighting',
'water_system', 'drainage'
) NOT NULL,
-- Problem-Definition
problem_title VARCHAR(200) NOT NULL,
problem_description TEXT,
-- Symptome & Erkennungsmerkmale
symptoms JSON NOT NULL, -- ["Geschirr bleibt kalt", "Kein warmes Wasser"]
error_codes JSON, -- ["E15", "F25", "F21"]
keywords JSON NOT NULL, -- ["heizt nicht", "kein warmes wasser", "heizstab"]
alternative_keywords JSON, -- ["temperatur", "warm", "erhitzen"]
-- Problem-Eigenschaften
urgency_level ENUM('LOW', 'MEDIUM', 'HIGH', 'CRITICAL') DEFAULT 'MEDIUM',
repair_complexity ENUM('EASY', 'MEDIUM', 'HARD') DEFAULT 'MEDIUM',
frequency_score INT DEFAULT 0, -- Häufigkeit des Problems (für Ranking)
-- Lösungs-Informationen
typical_parts JSON, -- [{"category": "heizstab", "keywords": ["heating", "thermostat"]}]
installation_time_min INT, -- Minuten
installation_time_max INT, -- Minuten
tools_needed JSON, -- ["Schraubendreher", "Multimeter", "Zange"]
safety_notes TEXT,
difficulty_description VARCHAR(100), -- "Mittel - handwerkliches Geschick nötig"
-- Meta-Daten
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
active BOOLEAN DEFAULT TRUE
);
-- Erweiterte Tabelle: problem_appliance_mapping
CREATE TABLE problem_appliance_mapping (
id INT AUTO_INCREMENT PRIMARY KEY,
problem_id INT,
appliance_type ENUM(
'waschmaschine', 'geschirrspuler', 'kuhlschrank',
'backofen', 'dunstabzug', 'mikrowelle', 'trockner'
),
brand_compatibility JSON, -- ["bosch", "siemens", "miele"]
model_patterns JSON, -- ["SMI*", "WM*", "GSV*"]
FOREIGN KEY (problem_id) REFERENCES problem_solutions(id)
);
-- Keyword-Optimierung: problem_keywords
CREATE TABLE problem_keywords (
id INT AUTO_INCREMENT PRIMARY KEY,
problem_id INT,
keyword VARCHAR(100),
keyword_type ENUM('primary', 'secondary', 'symptom', 'error_code'),
weight DECIMAL(3,2) DEFAULT 1.0, -- Gewichtung für Relevanz
language CHAR(2) DEFAULT 'de',
FOREIGN KEY (problem_id) REFERENCES problem_solutions(id),
INDEX idx_keyword (keyword),
INDEX idx_type (keyword_type)
);
-- Usage Analytics & Learning
CREATE TABLE problem_usage_stats (
id INT AUTO_INCREMENT PRIMARY KEY,
problem_id INT,
item_id INT,
generated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ai_model VARCHAR(50), -- 'chatgpt', 'gemini', 'claude'
user_feedback ENUM('helpful', 'not_helpful', 'partially_helpful'),
FOREIGN KEY (problem_id) REFERENCES problem_solutions(id)
);
-- Initial Seed Data: Top 20 häufigste Ersatzteil-Probleme
-- Problem 1: Heizung defekt (Sehr häufig - 85%)
INSERT INTO problem_solutions VALUES (
1,
'heating',
'Geschirrspüler heizt nicht',
'Das Gerät spült zwar, aber das Wasser wird nicht warm. Geschirr bleibt verschmutzt und kalt.',
'["Geschirr bleibt kalt", "Kein warmes Wasser", "Schlechtes Spülergebnis", "Wasser lauwarm"]',
'["E15", "F25", "Er:15"]',
'["heizt nicht", "kein warmes wasser", "heizstab", "thermostat", "ntc"]',
'["temperatur", "warm", "erhitzen", "heizelement", "heizpumpe"]',
'HIGH',
'MEDIUM',
85, -- Sehr häufiges Problem
'[{"category": "heizstab", "keywords": ["heizstab", "heating", "thermostat"]},
{"category": "ntc", "keywords": ["ntc", "temperaturfühler", "sensor"]}]',
45, 90,
'["Schraubendreher", "Multimeter", "Zange"]',
'⚠️ STROM ABSCHALTEN! Gerät vom Netz trennen vor Reparatur.',
'Mittel - handwerkliches Geschick nötig'
);
-- Problem 2: Pumpe defekt (Sehr häufig - 92%)
INSERT INTO problem_solutions VALUES (
2,
'pumping',
'Wasser läuft nicht ab / Pumpe defekt',
'Das Gerät pumpt das Wasser nicht ab, Wasser steht in der Maschine.',
'["Wasser steht", "Gerät pumpt nicht", "Ablauf verstopft", "Pumpe brummt", "Seltsame Geräusche"]',
'["E20", "E03", "F03", "Er:03"]',
'["pumpe defekt", "wasser läuft nicht ab", "ablaufpumpe", "laugenpumpe"]',
'["drainage", "pump", "water", "ablauf", "entwässerung"]',
'HIGH',
'MEDIUM',
92, -- Sehr häufig
'[{"category": "pumpe", "keywords": ["pumpe", "pump", "ablaufpumpe", "laugenpumpe"]}]',
30, 60,
'["Schraubendreher", "Zange", "Eimer", "Handschuhe"]',
'Wasser abstellen! Restwasser ablassen vor Ausbau.',
'Mittel - Wasserkontakt möglich'
);
-- Problem 3: Türschloss defekt (Häufig - 78%)
INSERT INTO problem_solutions VALUES (
3,
'door_system',
'Tür schließt nicht richtig / Türschloss defekt',
'Die Gerätetür lässt sich nicht richtig schließen oder das Schloss hakt.',
'["Tür geht nicht zu", "Türschloss hakt", "Gerät startet nicht", "Türgriff locker"]',
'["E01", "Er:01", "F01"]',
'["türschloss defekt", "tür geht nicht zu", "türgriff kaputt", "schloss hakt"]',
'["door lock", "türschließung", "verschluss", "riegel"]',
'MEDIUM',
'EASY',
78,
'[{"category": "türschloss", "keywords": ["türschloss", "door lock", "türgriff"]}]',
15, 30,
'["Schraubendreher", "Zange"]',
'Gerät ausschalten vor Reparatur.',
'Einfach - DIY möglich'
);
-- Problem 4: Motor/Antrieb defekt (Häufig - 65%)
INSERT INTO problem_solutions VALUES (
4,
'motor_drive',
'Trommel dreht nicht / Motor defekt',
'Der Antriebsmotor funktioniert nicht mehr, Trommel dreht sich nicht.',
'["Trommel dreht nicht", "Motor brummt nur", "Gerät macht komische Geräusche", "Kein Schleudern"]',
'["F21", "E02", "Er:02", "F02"]',
'["motor defekt", "trommel dreht nicht", "antrieb kaputt", "motor brummt"]',
'["drive motor", "antriebsmotor", "drehmotor", "trommelmotor"]',
'HIGH',
'HARD',
65,
'[{"category": "motor", "keywords": ["motor", "antrieb", "antriebsmotor"]}]',
90, 180,
'["Multimeter", "Schraubendreher", "Zange", "Spezialwerkzeug"]',
'⚠️ STROM ABSCHALTEN! Schweres Teil - Hilfe holen!',
'Schwer - Fachmann empfohlen'
);
-- Problem 5: Wasserschlauch undicht (Häufig - 71%)
INSERT INTO problem_solutions VALUES (
5,
'water_system',
'Wasserschlauch undicht / Aquastop defekt',
'Zulauf- oder Ablaufschlauch ist undicht oder Aquastop löst aus.',
'["Wasser tropft", "Schlauch undicht", "Aquastop piepst", "Pfütze unter Gerät"]',
'["E10", "Er:10", "F10"]',
'["schlauch undicht", "wasser tropft", "aquastop defekt", "zulaufschlauch"]',
'["water hose", "wasserschlauch", "zulauf", "aquastop"]',
'HIGH',
'EASY',
71,
'[{"category": "schlauch", "keywords": ["schlauch", "hose", "aquastop", "zulauf"]}]',
10, 25,
'["Zange", "Schraubendreher"]',
'Wasserzufuhr abstellen vor Reparatur!',
'Einfach - DIY möglich'
);
-- Weitere Top-Probleme...
-- Problem 6: Filter verstopft
INSERT INTO problem_solutions VALUES (
6, 'filters', 'Filter/Flusensieb verstopft',
'Filter oder Flusensieb ist verstopft und beeinträchtigt die Leistung.',
'["Schlechte Waschleistung", "Geruch", "Wasser läuft schlecht ab", "Filter stinkt"]',
'["E18", "Er:18"]',
'["filter verstopft", "flusensieb", "sieb verstopft", "schlechte waschleistung"]',
'["filter", "lint filter", "sieb", "flusen"]',
'MEDIUM', 'EASY', 88,
'[{"category": "filter", "keywords": ["filter", "sieb", "flusensieb"]}]',
5, 15,
'["Handschuhe", "Eimer"]',
'Filter regelmäßig reinigen zur Vorbeugung.',
'Einfach - regelmäßige Wartung'
);
-- Problem 7: Türdichtung defekt
INSERT INTO problem_solutions VALUES (
7, 'door_system', 'Türdichtung undicht/beschädigt',
'Türdichtung ist porös oder beschädigt, Wasser tritt aus.',
'["Wasser läuft aus Tür", "Dichtung porös", "Schimmel an Dichtung", "Gummi rissig"]',
NULL,
'["türdichtung defekt", "dichtung undicht", "wasser läuft aus", "gummi kaputt"]',
'["door seal", "türdichtung", "dichtgummi", "manschette"]',
'MEDIUM', 'MEDIUM', 67,
'[{"category": "dichtung", "keywords": ["dichtung", "seal", "türdichtung", "manschette"]}]',
30, 60,
'["Schraubendreher", "Spezialkleber"]',
'Gerät komplett trocknen vor Montage.',
'Mittel - Geduld erforderlich'
);
-- Problem 8: Thermostat defekt
INSERT INTO problem_solutions VALUES (
8, 'heating', 'Thermostat/Temperaturfühler defekt',
'Temperaturfühler oder Thermostat misst falsche Werte.',
'["Falsche Temperatur", "Überhitzung", "Zu kalt", "Temperatur schwankt"]',
'["E25", "F25", "Er:25"]',
'["thermostat defekt", "temperaturfühler", "ntc defekt", "temperatur falsch"]',
'["thermostat", "temperature sensor", "ntc", "fühler"]',
'MEDIUM', 'MEDIUM', 58,
'[{"category": "thermostat", "keywords": ["thermostat", "ntc", "temperaturfühler"]}]',
30, 45,
'["Multimeter", "Schraubendreher"]',
'Temperatur-Test vor Einbau durchführen.',
'Mittel - Messgerät nötig'
);
-- Weitere Keywords für bessere Suche
INSERT INTO problem_keywords (problem_id, keyword, keyword_type, weight) VALUES
(1, 'heizt nicht', 'primary', 2.0),
(1, 'kalt', 'symptom', 1.5),
(1, 'e15', 'error_code', 2.0),
(2, 'pumpt nicht', 'primary', 2.0),
(2, 'wasser steht', 'symptom', 1.8),
(2, 'e20', 'error_code', 2.0),
(3, 'tür zu', 'primary', 1.8),
(3, 'schloss', 'secondary', 1.5),
(4, 'dreht nicht', 'primary', 2.0),
(4, 'motor', 'primary', 1.9),
(5, 'tropft', 'symptom', 1.7),
(5, 'aquastop', 'primary', 1.9);
-- Appliance Mappings für bessere Zuordnung
INSERT INTO problem_appliance_mapping (problem_id, appliance_type, brand_compatibility, model_patterns) VALUES
(1, 'geschirrspuler', '["bosch", "siemens", "neff", "gaggenau"]', '["SMI*", "SMV*", "SMU*"]'),
(2, 'waschmaschine', '["bosch", "siemens", "miele"]', '["WM*", "WA*", "WS*"]'),
(2, 'geschirrspuler', '["bosch", "siemens"]', '["SMI*", "SMV*"]'),
(3, 'waschmaschine', '["bosch", "siemens", "miele", "amica"]', '["WM*", "WA*"]'),
(4, 'waschmaschine', '["bosch", "siemens", "miele"]', '["WM*", "WA*"]'),
(5, 'waschmaschine', '["bosch", "siemens", "miele", "amica"]', '["WM*", "WA*"]'),
(5, 'geschirrspuler', '["bosch", "siemens"]', '["SMI*", "SMV*"]');
+417
View File
@@ -0,0 +1,417 @@
#!/usr/bin/env python3
"""
🤖 Enhanced AI Shopping Schema Generator - Intelectra
Erzeugt KI-optimierte JSON-LD Schemas mit dynamischer Problem-DB-Abfrage
SICHER: Läuft komplett isoliert, keine Live-Shop Auswirkungen!
"""
import json
import sys
import re
import mysql.connector
from datetime import datetime
import os
from config import DB_CONFIG, ENABLE_FALLBACK, BASE_URL, SAFETY_ICON_BASE, LOG_DIR, SCHEMA_SAVE_DIR
class EnhancedAISchemaGenerator:
def __init__(self):
self.base_url = BASE_URL
self.safety_icon_base = SAFETY_ICON_BASE
self.db_connection = None
# DB-Verbindung herstellen (sichere Fallback-Behandlung)
if ENABLE_FALLBACK:
try:
self.connect_to_database()
except Exception as e:
self.log_error(f"DB connection failed: {str(e)} - Using fallback mode")
def connect_to_database(self):
"""Sichere DB-Verbindung mit Config-basierter Konfiguration"""
try:
self.db_connection = mysql.connector.connect(**DB_CONFIG)
except mysql.connector.Error as err:
self.log_error(f"MySQL connection error: {err}")
self.db_connection = None
def generate_schema(self, item_data):
"""Erzeugt KI-optimiertes Schema für einen Artikel"""
try:
schema = {
"@context": "https://schema.org",
"@type": "Product",
"name": item_data.get('name', ''),
"identifier": f"intelectra-{item_data.get('item_id', '')}",
"category": "Elektro-Ersatzteil",
"url": f"{self.base_url}/artikel/{item_data.get('item_id', '')}",
# Timestamp für Monitoring
"_meta": {
"generated": datetime.now().isoformat(),
"generator": "Enhanced AI Schema v2.0 - Database Powered",
"source": "intelectra_live_shop",
"database_enabled": self.db_connection is not None
}
}
# Sicherheitshinweise hinzufügen (wenn vorhanden)
if item_data.get('warnings'):
schema["safetyConsiderations"] = self.build_safety_schema(item_data['warnings'])
# 🚀 NEUE DATABASE-POWERED Problem-Solution-Mapping!
schema["solves"] = self.build_dynamic_problem_solutions(item_data)
# Kompatibilitäts-Informationen
if item_data.get('attributes'):
schema["compatibleWith"] = self.build_compatibility_schema(item_data['attributes'])
# Installations-Hinweise
schema["installationHints"] = self.generate_installation_hints(item_data)
return schema
except Exception as e:
self.log_error(f"Schema generation failed: {str(e)}")
return None
def build_dynamic_problem_solutions(self, item_data):
"""🚀 NEUE DATABASE-POWERED Problem-Solution Engine"""
if not self.db_connection:
# Fallback auf alte hardcoded Methode
return self.build_fallback_problem_solutions(item_data)
try:
problems = self.get_problems_for_item(item_data)
solutions = []
for problem in problems:
solution = {
"@type": "ProblemSolution",
"problem": problem['problem_title'],
"description": problem['problem_description'],
"symptoms": json.loads(problem['symptoms']),
"errorCodes": json.loads(problem['error_codes'] or '[]'),
"urgencyLevel": problem['urgency_level'],
"repairComplexity": problem['repair_complexity'],
"estimatedTime": f"{problem['installation_time_min']}-{problem['installation_time_max']} Minuten",
"toolsRequired": json.loads(problem['tools_needed'] or '[]'),
"safetyInstructions": problem['safety_notes'],
"difficultyLevel": problem['difficulty_description'],
"problemKeywords": json.loads(problem['keywords']),
"frequencyScore": problem['frequency_score'], # Für KI-Ranking
"dataSource": "dynamic_database"
}
solutions.append(solution)
return solutions
except Exception as e:
self.log_error(f"Database problem query failed: {str(e)}")
return self.build_fallback_problem_solutions(item_data)
def get_problems_for_item(self, item_data):
"""Intelligente Problem-Zuordnung basierend auf Item-Daten"""
if not self.db_connection:
return []
try:
cursor = self.db_connection.cursor(dictionary=True)
# 1. Kategorie-Erkennung
category = self.detect_category(item_data['name'], item_data.get('attributes', {}))
# 2. Keyword-Matching
item_keywords = self.extract_keywords(item_data['name'])
# 3. DB-Abfrage mit Ranking
query = """
SELECT ps.*,
COALESCE(SUM(pk.weight), 0) as relevance_score
FROM problem_solutions ps
LEFT JOIN problem_keywords pk ON ps.id = pk.problem_id
WHERE (ps.problem_category = %s
OR JSON_OVERLAPS(ps.keywords, %s)
OR pk.keyword IN ({placeholders}))
AND ps.active = TRUE
GROUP BY ps.id
ORDER BY relevance_score DESC, ps.frequency_score DESC
LIMIT 5
""".format(placeholders=','.join(['%s'] * len(item_keywords)))
params = [category, json.dumps(item_keywords)] + item_keywords
cursor.execute(query, params)
problems = cursor.fetchall()
cursor.close()
return problems
except Exception as e:
self.log_error(f"Database query error: {str(e)}")
return []
def detect_category(self, item_name, attributes):
"""Intelligente Kategorie-Erkennung"""
name_lower = item_name.lower()
category_patterns = {
'heating': ['heizstab', 'thermostat', 'ntc', 'temperaturfühler', 'heizung'],
'pumping': ['pumpe', 'pump', 'ablaufpumpe', 'laugenpumpe', 'umwälzpumpe'],
'motor_drive': ['motor', 'antrieb', 'antriebsmotor'],
'door_system': ['türschloss', 'türgriff', 'türdichtung', 'door'],
'electronics': ['platine', 'steuerung', 'elektronik', 'display', 'timer'],
'mechanical': ['stoßdämpfer', 'feder', 'lager', 'riemen'],
'water_system': ['schlauch', 'ventil', 'aquastop', 'wasserzulauf'],
'filters': ['filter', 'sieb', 'flusensieb'],
'lighting': ['lampe', 'led', 'birne', 'leuchte']
}
for category, keywords in category_patterns.items():
if any(keyword in name_lower for keyword in keywords):
return category
return 'mechanical' # Default
def extract_keywords(self, item_name):
"""Extrahiert relevante Keywords aus Item-Name"""
name_lower = item_name.lower()
# Basis-Keywords extrahieren
keywords = []
# Wichtige Einzelwörter
important_words = ['pumpe', 'motor', 'heizstab', 'schlauch', 'filter',
'türschloss', 'dichtung', 'thermostat', 'sensor']
for word in important_words:
if word in name_lower:
keywords.append(word)
# Synonyme und Variationen
if 'pump' in name_lower:
keywords.extend(['pumpe', 'pump'])
if 'heating' in name_lower:
keywords.extend(['heizstab', 'heizung'])
if 'door' in name_lower:
keywords.extend(['tür', 'türschloss'])
return list(set(keywords))
def build_fallback_problem_solutions(self, item_data):
"""Fallback auf alte hardcoded Methode wenn DB nicht verfügbar"""
name = item_data.get('name', '').lower()
solutions = []
# Vereinfachte Fallback-Logic (nur Top-Probleme)
if any(word in name for word in ['pumpe', 'pump']):
solutions.append({
"@type": "ProblemSolution",
"problem": "Wasser läuft nicht ab / Pumpe defekt",
"symptoms": ["Gerät pumpt nicht", "Wasser steht", "E20 Fehler"],
"urgencyLevel": "HIGH",
"repairComplexity": "MEDIUM",
"dataSource": "fallback_hardcoded"
})
if any(word in name for word in ['heizstab', 'heizung']):
solutions.append({
"@type": "ProblemSolution",
"problem": "Gerät heizt nicht",
"symptoms": ["Kein warmes Wasser", "E15 Fehler"],
"urgencyLevel": "HIGH",
"repairComplexity": "MEDIUM",
"dataSource": "fallback_hardcoded"
})
return solutions
def build_safety_schema(self, warnings):
"""Konvertiert Sicherheitshinweise in KI-optimiertes Format"""
safety_considerations = []
for warning in warnings:
consideration = {
"@type": "SafetyConsideration",
"name": warning.get('name', ''),
"description": warning.get('beschreibung', ''),
"warningLevel": self.detect_warning_level(warning.get('name', '')),
"iconPath": f"{self.safety_icon_base}{warning.get('final_bilddateiname', '')}"
}
# Intelligente Kategorisierung
if "elektrisch" in warning.get('name', '').lower():
consideration["category"] = "electrical_hazard"
consideration["preventiveMeasures"] = ["Netzstecker ziehen", "Spannungsfreiheit prüfen"]
elif "quetsch" in warning.get('name', '').lower():
consideration["category"] = "mechanical_hazard"
consideration["preventiveMeasures"] = ["Schutzhandschuhe tragen", "Vorsichtig arbeiten"]
safety_considerations.append(consideration)
return safety_considerations
def build_compatibility_schema(self, attributes):
"""Extrahiert Kompatibilitäts-Informationen aus Attributen"""
compatible_brands = []
# Pattern für bekannte Marken
brand_patterns = {
'siemens': ['siemens', 'bosch', 'neff', 'gaggenau'],
'miele': ['miele'],
'amica': ['amica', 'whirlpool', 'bauknecht', 'privileg'],
'liebherr': ['liebherr']
}
# Suche nach Marken in Attributen
for attr_key, attr_value in attributes.items():
if isinstance(attr_value, str):
for brand_group, brands in brand_patterns.items():
if any(brand in attr_value.lower() for brand in brands):
compatible_brands.extend(brands)
return {
"brands": list(set(compatible_brands)),
"applianceTypes": self.detect_appliance_types(attributes)
}
def detect_appliance_types(self, attributes):
"""Erkennt Gerätetypen aus Attributen"""
types = []
type_keywords = {
"Waschmaschine": ["waschmaschine", "washing", "wäsche"],
"Geschirrspüler": ["geschirrspüler", "dishwasher", "spülmaschine"],
"Kühlschrank": ["kühlschrank", "refrigerator", "kühl"],
"Backofen": ["backofen", "oven", "herd"]
}
for attr_value in attributes.values():
if isinstance(attr_value, str):
for appliance, keywords in type_keywords.items():
if any(keyword in attr_value.lower() for keyword in keywords):
types.append(appliance)
return list(set(types))
def generate_installation_hints(self, item_data):
"""Generiert intelligente Installations-Hinweise"""
name = item_data.get('name', '').lower()
if 'schlauch' in name:
return {
"difficulty": "Einfach - ohne Fachmann machbar",
"timeRequired": "5-10 Minuten",
"toolsNeeded": ["Zange", "Schraubendreher"],
"safetyNote": "Wasser abstellen vor Montage"
}
elif 'pumpe' in name:
return {
"difficulty": "Mittel - handwerkliches Geschick nötig",
"timeRequired": "30-45 Minuten",
"toolsNeeded": ["Schraubendreher", "Zange", "Multimeter"],
"safetyNote": "Strom abstellen! Gerät vom Netz trennen"
}
elif 'heizstab' in name:
return {
"difficulty": "Schwer - Fachmann empfohlen",
"timeRequired": "60-90 Minuten",
"toolsNeeded": ["Multimeter", "Spezialwerkzeug"],
"safetyNote": "⚠️ HOCHSPANNUNG! Strom komplett abschalten"
}
return {
"difficulty": "Mittlere Schwierigkeit",
"timeRequired": "15-30 Minuten",
"safetyNote": "Sicherheitshinweise beachten"
}
def detect_warning_level(self, warning_name):
"""Intelligente Warnstufen-Erkennung"""
name_lower = warning_name.lower()
if any(word in name_lower for word in ['elektrisch', 'strom', 'spannung']):
return "CRITICAL"
elif any(word in name_lower for word in ['heiß', 'temperatur', 'verbrennung']):
return "HIGH"
elif any(word in name_lower for word in ['quetsch', 'verletzung']):
return "MEDIUM"
else:
return "LOW"
def save_schema(self, schema, item_id):
"""Speichert Schema für späteren Abruf (optional)"""
try:
schema_file = f"{SCHEMA_SAVE_DIR}/enhanced_schema_{item_id}.json"
os.makedirs(SCHEMA_SAVE_DIR, exist_ok=True)
with open(schema_file, 'w', encoding='utf-8') as f:
json.dump(schema, f, indent=2, ensure_ascii=False)
return True
except Exception as e:
self.log_error(f"Schema save failed: {str(e)}")
return False
def log_error(self, message):
"""Fehler-Logging"""
try:
log_file = f"{LOG_DIR}/enhanced_ai_schema.log"
timestamp = datetime.now().isoformat()
os.makedirs(LOG_DIR, exist_ok=True)
with open(log_file, 'a', encoding='utf-8') as f:
f.write(f"{timestamp} ERROR: {message}\n")
except:
pass # Silent fail für Live-Shop
def __del__(self):
"""DB-Verbindung sauber schließen"""
if self.db_connection:
try:
self.db_connection.close()
except:
pass
def main():
"""Hauptfunktion - wird von PHP aufgerufen"""
if len(sys.argv) < 2:
print(json.dumps({"error": "No input data provided"}))
sys.exit(1)
try:
# Input von PHP parsen
input_data = json.loads(sys.argv[1])
# Enhanced Schema Generator initialisieren
generator = EnhancedAISchemaGenerator()
# Schema erzeugen
schema = generator.generate_schema(input_data)
if schema:
# Optional: Schema speichern
generator.save_schema(schema, input_data.get('item_id', 'unknown'))
# Erfolg zurückgeben
result = {
"success": True,
"schema_generated": True,
"item_id": input_data.get('item_id'),
"timestamp": datetime.now().isoformat(),
"database_powered": generator.db_connection is not None,
"problems_found": len(schema.get("solves", []))
}
else:
result = {"success": False, "error": "Schema generation failed"}
print(json.dumps(result))
except Exception as e:
error_result = {"success": False, "error": str(e)}
print(json.dumps(error_result))
sys.exit(1)
if __name__ == "__main__":
main()
+123
View File
@@ -0,0 +1,123 @@
#!/usr/bin/env python3
"""
🗄️ Database Setup Utility für Problem-FAQ System
ACHTUNG: Nur ausführen wenn DB-Zugang verfügbar!
"""
import mysql.connector
import json
import sys
from config import DB_CONFIG
def create_problem_database():
"""Erstellt die Problem-Datenbank und Tabellen"""
try:
# Verbindung ohne spezifische Datenbank
temp_config = DB_CONFIG.copy()
temp_config.pop('database', None)
connection = mysql.connector.connect(**temp_config)
cursor = connection.cursor()
# Datenbank erstellen
cursor.execute(f"CREATE DATABASE IF NOT EXISTS {DB_CONFIG['database']} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci")
cursor.execute(f"USE {DB_CONFIG['database']}")
print(f"✅ Datenbank '{DB_CONFIG['database']}' erstellt/ausgewählt")
# SQL-Script ausführen
with open('/var/www/vhosts/intelectra.de/httpdocs/core/python/create_problem_database.sql', 'r', encoding='utf-8') as f:
sql_script = f.read()
# Script in einzelne Statements aufteilen
statements = [stmt.strip() for stmt in sql_script.split(';') if stmt.strip()]
for statement in statements:
if statement.upper().startswith(('CREATE', 'INSERT')):
try:
cursor.execute(statement)
print(f"✅ SQL Statement ausgeführt: {statement[:50]}...")
except mysql.connector.Error as err:
print(f"⚠️ Warning: {err} für Statement: {statement[:50]}...")
connection.commit()
cursor.close()
connection.close()
print("\n🎉 Database Setup erfolgreich abgeschlossen!")
return True
except mysql.connector.Error as err:
print(f"❌ Database Error: {err}")
return False
except Exception as e:
print(f"💥 Setup Error: {str(e)}")
return False
def test_database_connection():
"""Testet die Datenbankverbindung"""
try:
connection = mysql.connector.connect(**DB_CONFIG)
cursor = connection.cursor()
# Test-Query
cursor.execute("SELECT COUNT(*) FROM problem_solutions WHERE active = TRUE")
count = cursor.fetchone()[0]
cursor.close()
connection.close()
print(f"✅ Database Connection OK - {count} aktive Probleme gefunden")
return True
except Exception as e:
print(f"❌ Database Connection Failed: {str(e)}")
return False
def show_sample_problems():
"""Zeigt Beispiel-Probleme aus der Datenbank"""
try:
connection = mysql.connector.connect(**DB_CONFIG)
cursor = connection.cursor(dictionary=True)
cursor.execute("""
SELECT problem_title, problem_category, urgency_level, frequency_score
FROM problem_solutions
WHERE active = TRUE
ORDER BY frequency_score DESC
LIMIT 5
""")
problems = cursor.fetchall()
print("\n📊 Top 5 Probleme in der Datenbank:")
print("-" * 50)
for i, problem in enumerate(problems, 1):
print(f"{i}. {problem['problem_title']}")
print(f" Kategorie: {problem['problem_category']}")
print(f" Urgency: {problem['urgency_level']}")
print(f" Häufigkeit: {problem['frequency_score']}%")
print()
cursor.close()
connection.close()
except Exception as e:
print(f"❌ Error showing problems: {str(e)}")
if __name__ == "__main__":
print("🗄️ Problem-FAQ Database Setup")
print("=" * 40)
if len(sys.argv) > 1 and sys.argv[1] == "--create":
print("🔨 Creating database and tables...")
if create_problem_database():
test_database_connection()
show_sample_problems()
else:
print("🧪 Testing existing database connection...")
if test_database_connection():
show_sample_problems()
else:
print("\n💡 Tipp: Verwende --create um die Datenbank zu erstellen")
print(" Beispiel: python3 setup_database.py --create")
+329
View File
@@ -0,0 +1,329 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🤖 Intelectra AI Control Center</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #fff;
min-height: 100vh;
}
.header {
background: rgba(0,0,0,0.2);
padding: 1rem;
text-align: center;
backdrop-filter: blur(10px);
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 2rem;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-bottom: 2rem;
}
.card {
background: rgba(255,255,255,0.1);
backdrop-filter: blur(10px);
border-radius: 15px;
padding: 1.5rem;
border: 1px solid rgba(255,255,255,0.2);
box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37);
}
.card h3 {
margin-bottom: 1rem;
font-size: 1.2rem;
display: flex;
align-items: center;
gap: 0.5rem;
}
.ai-stat {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.5rem 0;
border-bottom: 1px solid rgba(255,255,255,0.1);
}
.ai-stat:last-child {
border-bottom: none;
}
.ai-name {
font-weight: bold;
color: #4ade80;
}
.ai-count {
background: rgba(255,255,255,0.2);
padding: 0.2rem 0.8rem;
border-radius: 20px;
font-size: 0.9rem;
}
.article-item {
background: rgba(0,0,0,0.1);
padding: 1rem;
border-radius: 10px;
margin-bottom: 0.5rem;
}
.article-id {
font-weight: bold;
color: #fbbf24;
}
.chart-container {
height: 200px;
background: rgba(255,255,255,0.05);
border-radius: 10px;
padding: 1rem;
display: flex;
align-items: end;
justify-content: space-around;
}
.chart-bar {
background: linear-gradient(to top, #4ade80, #22d3ee);
border-radius: 4px 4px 0 0;
min-width: 20px;
position: relative;
transition: all 0.3s ease;
}
.chart-bar:hover {
transform: scale(1.1);
}
.chart-bar::after {
content: attr(data-value);
position: absolute;
top: -25px;
left: 50%;
transform: translateX(-50%);
font-size: 0.8rem;
font-weight: bold;
}
.nav-menu {
background: rgba(255,255,255,0.1);
padding: 1rem;
border-radius: 10px;
margin-bottom: 2rem;
text-align: center;
}
.nav-menu a {
color: #fff;
text-decoration: none;
padding: 0.5rem 1rem;
margin: 0 0.5rem;
border-radius: 20px;
background: rgba(255,255,255,0.1);
transition: all 0.3s ease;
}
.nav-menu a:hover {
background: rgba(255,255,255,0.2);
transform: translateY(-2px);
}
.status-indicator {
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 0.5rem;
}
.status-online { background: #4ade80; }
.status-offline { background: #ef4444; }
.live-counter {
font-size: 2rem;
font-weight: bold;
text-align: center;
margin: 1rem 0;
color: #4ade80;
}
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.5; }
100% { opacity: 1; }
}
.pulse {
animation: pulse 2s infinite;
}
</style>
</head>
<body>
<div class="header">
<h1>🤖 Intelectra AI Control Center</h1>
<p>KI-Tracking & Schema Management Dashboard</p>
</div>
<div class="container">
<div class="nav-menu">
<a href="/">📊 Dashboard</a>
<a href="/faq-management">🗄️ FAQ Management</a>
<a href="/add-problem">➕ Problem hinzufügen</a>
<a href="/schema-preview/12345">👁️ Schema Preview</a>
</div>
<div class="grid">
<!-- Live AI Activity -->
<div class="card">
<h3>🔥 Live AI Activity</h3>
<div class="live-counter pulse" id="live-counter">0</div>
<p style="text-align: center; opacity: 0.8;">KI-Besuche heute</p>
<div class="status-indicator status-online"></div>
<span>Tracking aktiv</span>
</div>
<!-- AI Visits -->
<div class="card">
<h3>🤖 KI-Besucher (7 Tage)</h3>
{% if stats.ai_visits %}
{% for ai in stats.ai_visits %}
<div class="ai-stat">
<span class="ai-name">{{ ai.ai_name }}</span>
<div>
<span class="ai-count">{{ ai.visit_count }} Besuche</span>
<small style="opacity: 0.7; margin-left: 0.5rem;">
{{ ai.unique_visitors }} Unique
</small>
</div>
</div>
{% endfor %}
{% else %}
<p style="opacity: 0.7;">Noch keine KI-Besuche erkannt</p>
{% endif %}
</div>
<!-- Top Articles -->
<div class="card">
<h3>📈 Top KI-Artikel</h3>
{% if stats.top_articles %}
{% for article in stats.top_articles %}
<div class="article-item">
<div class="article-id">Artikel #{{ article.article_id }}</div>
<div style="font-size: 0.9rem; opacity: 0.8;">
{{ article.visit_count }} Besuche von: {{ article.visiting_ais }}
</div>
</div>
{% endfor %}
{% else %}
<p style="opacity: 0.7;">Noch keine Artikel-Besuche</p>
{% endif %}
</div>
<!-- Hourly Distribution -->
<div class="card">
<h3>⏰ Tagesverteilung</h3>
<div class="chart-container">
{% if stats.hourly_distribution %}
{% for hour_data in stats.hourly_distribution %}
{% set max_visits = stats.hourly_distribution|map(attribute='visits')|max %}
{% set bar_height = (hour_data.visits / max_visits * 150)|round|int %}
<div class="chart-bar"
style="height: {{ bar_height }}px"
data-value="{{ hour_data.visits }}"
title="{{ hour_data.hour }}:00 - {{ hour_data.visits }} Besuche">
</div>
{% endfor %}
{% else %}
<p style="opacity: 0.7; align-self: center;">Noch keine Daten</p>
{% endif %}
</div>
</div>
<!-- System Status -->
<div class="card">
<h3>⚙️ System Status</h3>
<div class="ai-stat">
<span>AI Schema Generator</span>
<span class="ai-count">✅ Aktiv</span>
</div>
<div class="ai-stat">
<span>Problem Database</span>
<span class="ai-count">✅ Online</span>
</div>
<div class="ai-stat">
<span>KI Tracking</span>
<span class="ai-count">✅ Läuft</span>
</div>
<div class="ai-stat">
<span>Flask Dashboard</span>
<span class="ai-count">🟡 Dev Mode</span>
</div>
</div>
<!-- Quick Actions -->
<div class="card">
<h3>⚡ Quick Actions</h3>
<div style="display: flex; flex-direction: column; gap: 0.5rem;">
<button onclick="refreshStats()" style="background: rgba(255,255,255,0.2); border: none; color: #fff; padding: 0.8rem; border-radius: 8px; cursor: pointer;">
🔄 Stats aktualisieren
</button>
<button onclick="exportData()" style="background: rgba(255,255,255,0.2); border: none; color: #fff; padding: 0.8rem; border-radius: 8px; cursor: pointer;">
📥 Daten exportieren
</button>
<button onclick="clearCache()" style="background: rgba(255,255,255,0.2); border: none; color: #fff; padding: 0.8rem; border-radius: 8px; cursor: pointer;">
🗑️ Cache leeren
</button>
</div>
</div>
</div>
</div>
<script>
// Live Updates alle 30 Sekunden
setInterval(updateLiveStats, 30000);
function updateLiveStats() {
fetch('/api/ai-visits')
.then(response => response.json())
.then(data => {
// Live Counter updaten
const totalToday = data.ai_visits.reduce((sum, ai) => sum + ai.visit_count, 0);
document.getElementById('live-counter').textContent = totalToday;
})
.catch(error => console.error('Live update failed:', error));
}
function refreshStats() {
window.location.reload();
}
function exportData() {
window.open('/api/export-stats', '_blank');
}
function clearCache() {
if (confirm('Cache wirklich leeren?')) {
fetch('/api/clear-cache', { method: 'POST' })
.then(() => alert('Cache geleert!'));
}
}
// Initial load
updateLiveStats();
</script>
</body>
</html>
+176
View File
@@ -0,0 +1,176 @@
#!/usr/bin/env python3
"""
🧪 Test Script für Enhanced AI Schema Generator mit DB-Integration
SICHER: Testet ohne Live-Shop zu beeinträchtigen
"""
import json
import subprocess
import sys
import os
def test_enhanced_schema_generation():
"""Testet Enhanced Schema-Generierung mit verschiedenen Artikeltypen"""
# Test-Daten für verschiedene Problemkategorien
test_cases = [
{
"name": "🚰 PUMPE - Ablaufpumpe Test",
"data": {
"item_id": "TEST_PUMP_001",
"name": "Bosch Ablaufpumpe für Waschmaschine WM14N140",
"warnings": [
{
"name": ".WARNUNG! Gefahr eines elektrischen Schlags",
"beschreibung": "Schalten Sie das Gerät aus vor Reparatur.",
"final_bilddateiname": "ISO_7010_W012.svg"
}
],
"attributes": {
"attribute_1": "Pumpe für Waschmaschine",
"attribute_2": "Kompatibel mit Bosch, Siemens",
"attribute_3": "Laugenpumpe"
}
}
},
{
"name": "🔥 HEIZUNG - Heizstab Test",
"data": {
"item_id": "TEST_HEAT_001",
"name": "Siemens Heizstab mit Thermostat für Geschirrspüler",
"warnings": [
{
"name": ".WARNUNG! Gefahr eines elektrischen Schlags",
"beschreibung": "Hochspannung! Strom abschalten.",
"final_bilddateiname": "ISO_7010_W012.svg"
}
],
"attributes": {
"attribute_1": "Heizelement für Spülmaschine",
"attribute_2": "Kompatibel mit Siemens, Bosch",
"attribute_3": "Mit NTC-Sensor"
}
}
},
{
"name": "🚪 TÜR - Türschloss Test",
"data": {
"item_id": "TEST_DOOR_001",
"name": "Miele Türschloss für Waschmaschine W1 Serie",
"warnings": [],
"attributes": {
"attribute_1": "Türverriegelung",
"attribute_2": "Kompatibel mit Miele",
"attribute_3": "Mechanisches Schloss"
}
}
}
]
print("🧪 Enhanced AI Schema Generator Test Suite")
print("=" * 60)
for test_case in test_cases:
print(f"\n🔧 {test_case['name']}")
print("-" * 40)
try:
# Schema Generator aufrufen
script_path = "/var/www/vhosts/intelectra.de/httpdocs/core/python/enhanced_ai_schema_generator.py"
json_input = json.dumps(test_case['data'])
result = subprocess.run([
"python3", script_path, json_input
], capture_output=True, text=True, timeout=30)
if result.returncode == 0:
response = json.loads(result.stdout)
print("✅ Status:", "SUCCESS" if response.get('success') else "FAILED")
print("📊 Schema generiert:", response.get('schema_generated', False))
print("🗄️ Database powered:", response.get('database_powered', False))
print("🔍 Probleme gefunden:", response.get('problems_found', 0))
print("🆔 Item ID:", response.get('item_id'))
# Schema-Datei prüfen und analysieren
schema_file = f"/var/www/vhosts/intelectra.de/httpdocs/core/python/logs/enhanced_schema_{test_case['data']['item_id']}.json"
try:
with open(schema_file, 'r', encoding='utf-8') as f:
schema = json.load(f)
print("\n📋 Schema Details:")
print(f" - Generator: {schema.get('_meta', {}).get('generator', 'Unknown')}")
print(f" - DB Enabled: {schema.get('_meta', {}).get('database_enabled', False)}")
print(f" - Sicherheitshinweise: {len(schema.get('safetyConsiderations', []))}")
print(f" - Problem-Lösungen: {len(schema.get('solves', []))}")
print(f" - Kompatible Marken: {schema.get('compatibleWith', {}).get('brands', [])}")
# Problem-Details anzeigen
problems = schema.get('solves', [])
if problems:
print("\n🔧 Gefundene Probleme:")
for i, problem in enumerate(problems[:3], 1): # Nur erste 3
print(f" {i}. {problem.get('problem', 'N/A')}")
print(f" Urgency: {problem.get('urgencyLevel', 'N/A')}")
print(f" Source: {problem.get('dataSource', 'N/A')}")
except FileNotFoundError:
print("⚠️ Schema-Datei nicht gefunden")
else:
print("❌ Fehler:", result.stderr)
print("Output:", result.stdout)
except Exception as e:
print(f"💥 Test fehlgeschlagen: {str(e)}")
print("\n" + "=" * 60)
print("🎯 Test Suite abgeschlossen!")
# Log-Datei checken
log_file = "/var/www/vhosts/intelectra.de/httpdocs/core/python/logs/enhanced_ai_schema.log"
if os.path.exists(log_file):
print(f"\n📝 Log-Datei gefunden: {log_file}")
try:
with open(log_file, 'r') as f:
lines = f.readlines()[-5:] # Letzte 5 Zeilen
if lines:
print("Letzte Log-Einträge:")
for line in lines:
print(f" {line.strip()}")
except:
print(" (Log-Datei konnte nicht gelesen werden)")
def test_database_fallback():
"""Testet Fallback-Verhalten wenn DB nicht verfügbar"""
print("\n🔄 Database Fallback Test")
print("-" * 30)
# Test ohne DB-Verbindung (sollte Fallback verwenden)
test_data = {
"item_id": "TEST_FALLBACK_001",
"name": "Generic Pumpe für Test",
"attributes": {"test": "fallback"}
}
try:
script_path = "/var/www/vhosts/intelectra.de/httpdocs/core/python/enhanced_ai_schema_generator.py"
json_input = json.dumps(test_data)
result = subprocess.run([
"python3", script_path, json_input
], capture_output=True, text=True, timeout=30)
if result.returncode == 0:
response = json.loads(result.stdout)
print("✅ Fallback funktioniert:", response.get('success', False))
print("🗄️ Database powered:", response.get('database_powered', False))
else:
print("❌ Fallback failed")
except Exception as e:
print(f"💥 Fallback test error: {str(e)}")
if __name__ == "__main__":
test_enhanced_schema_generation()
test_database_fallback()
+78
View File
@@ -0,0 +1,78 @@
#!/usr/bin/env python3
"""
🧪 Test Script für AI Schema Generator
SICHER: Testet ohne Live-Shop zu beeinträchtigen
"""
import json
import subprocess
import sys
def test_schema_generation():
"""Testet Schema-Generierung mit Beispiel-Daten"""
# Test-Daten (wie sie von PHP kommen würden)
test_data = {
"item_id": "283272",
"name": "universelle Zusatzpumpe für bessere Förderhöhe / für Zwischeneinbau",
"warnings": [
{
"name": ".WARNUNG! Gefahr eines elektrischen Schlags",
"beschreibung": "Schalten Sie das Gerät aus und ziehen Sie den Netzstecker aus der Steckdose, bevor Sie mit Reparatur- oder Wartungsarbeiten beginnen.",
"final_bilddateiname": "ISO_7010_W012.svg"
},
{
"name": ".Quetschgefahr",
"beschreibung": "Warnung, Quetschgefahr!",
"final_bilddateiname": "ISO_7010_W019.svg"
}
],
"attributes": {
"attribute_1": "Pumpe für Haushaltsgeräte",
"attribute_2": "Kompatibel mit Siemens, Bosch",
"attribute_3": "Ablaufpumpe"
}
}
try:
# Schema Generator aufrufen
script_path = "/var/www/vhosts/intelectra.de/httpdocs/core/python/ai_shopping_schema_generator.py"
json_input = json.dumps(test_data)
result = subprocess.run([
"python3", script_path, json_input
], capture_output=True, text=True, timeout=30)
print("🧪 AI Schema Generator Test")
print("=" * 50)
if result.returncode == 0:
response = json.loads(result.stdout)
print("✅ Status:", "SUCCESS" if response.get('success') else "FAILED")
print("📊 Schema generiert:", response.get('schema_generated', False))
print("🆔 Item ID:", response.get('item_id'))
print("⏰ Timestamp:", response.get('timestamp'))
# Schema-Datei prüfen
schema_file = f"/var/www/vhosts/intelectra.de/httpdocs/core/python/logs/schema_{test_data['item_id']}.json"
try:
with open(schema_file, 'r', encoding='utf-8') as f:
schema = json.load(f)
print("\n📋 Generiertes Schema:")
print(f" - Name: {schema.get('name')}")
print(f" - Sicherheitshinweise: {len(schema.get('safetyConsiderations', []))}")
print(f" - Problem-Lösungen: {len(schema.get('solves', []))}")
print(f" - Kompatibilität: {schema.get('compatibleWith', {}).get('brands', [])}")
except FileNotFoundError:
print("⚠️ Schema-Datei nicht gefunden")
else:
print("❌ Fehler:", result.stderr)
print("Output:", result.stdout)
except Exception as e:
print(f"💥 Test fehlgeschlagen: {str(e)}")
if __name__ == "__main__":
test_schema_generation()