import gradio as gr import sqlite3 import hashlib import html import re from datetime import datetime, timedelta DB_NAME = "testimonials.db" # ================================================== # Database # ================================================== def get_connection(): return sqlite3.connect(DB_NAME, check_same_thread=False) def init_db(): conn = get_connection() c = conn.cursor() c.execute(""" CREATE TABLE IF NOT EXISTS testimonials ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, role TEXT, content TEXT NOT NULL, sentiment TEXT, rating INTEGER DEFAULT 5, timestamp TEXT NOT NULL, likes INTEGER DEFAULT 0, is_highlighted INTEGER DEFAULT 0, ip_hash TEXT ) """) conn.commit() conn.close() # ================================================== # Utilities # ================================================== def clean_text(text): if not text: return "" text = text.strip() text = re.sub(r"\s+", " ", text) return text def contains_bad_words(text): bad_words = [ "يلعن", "تبن", "سافل", "كلب", "خنزير", "عاهرة" ] normalized = re.sub(r"\s+", "", text.lower()) return any(word in normalized for word in bad_words) def escape_safe(text): return html.escape(text) def get_ip_hash(request: gr.Request): try: client_ip = request.client.host return hashlib.sha256( client_ip.encode() ).hexdigest()[:16] except: return "unknown" def detect_sentiment(text): positive_words = [ "رائع", "ممتاز", "جميل", "احترافي", "مفيد", "مذهل" ] negative_words = [ "سيء", "ضعيف", "فاشل", "سيئة" ] text = text.lower() positive_score = sum( word in text for word in positive_words ) negative_score = sum( word in text for word in negative_words ) if positive_score > negative_score: return "إيجابي 😊" elif negative_score > positive_score: return "سلبي 😕" return "محايد 😐" def format_time(timestamp): try: dt = datetime.fromisoformat(timestamp) now = datetime.now() diff = now - dt if diff.days > 7: return dt.strftime("%Y/%m/%d") elif diff.days > 0: return f"منذ {diff.days} يوم" elif diff.seconds >= 3600: hours = diff.seconds // 3600 return f"منذ {hours} ساعة" elif diff.seconds >= 60: minutes = diff.seconds // 60 return f"منذ {minutes} دقيقة" return "الآن" except: return "غير معروف" # ================================================== # Add Testimonial # ================================================== def add_testimonial( name, role, content, rating, request: gr.Request ): content = clean_text(content) if not content: return ( "❌ الرجاء كتابة رأيك", "", "", update_display() ) if len(content) > 800: return ( "❌ الحد الأقصى 800 حرف", "", "", update_display() ) if contains_bad_words(content): return ( "❌ يوجد كلمات غير مناسبة", "", "", update_display() ) ip_hash = get_ip_hash(request) conn = get_connection() c = conn.cursor() # Anti spam one_hour_ago = ( datetime.now() - timedelta(hours=1) ).isoformat() c.execute(""" SELECT COUNT(*) FROM testimonials WHERE ip_hash = ? AND timestamp >= ? """, (ip_hash, one_hour_ago)) count = c.fetchone()[0] if count >= 3: conn.close() return ( "❌ وصلت الحد المسموح حالياً", "", "", update_display() ) name = clean_text(name) role = clean_text(role) if not name: name = "مجهول" sentiment = detect_sentiment(content) c.execute(""" INSERT INTO testimonials ( name, role, content, sentiment, rating, timestamp, likes, is_highlighted, ip_hash ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) """, ( name, role, content, sentiment, int(rating), datetime.now().isoformat(), 0, 0, ip_hash )) conn.commit() conn.close() return ( "✅ تم نشر رأيك بنجاح", "", "", update_display() ) # ================================================== # Fetch Testimonials # ================================================== def get_testimonials( filter_type="all", sort_by="newest" ): conn = get_connection() c = conn.cursor() query = """ SELECT id, name, role, content, sentiment, rating, timestamp, likes, is_highlighted FROM testimonials """ conditions = [] if filter_type == "highlight": conditions.append( "is_highlighted = 1" ) elif filter_type == "liked": conditions.append( "likes > 0" ) if conditions: query += " WHERE " + " AND ".join(conditions) if sort_by == "likes": query += """ ORDER BY likes DESC, timestamp DESC """ else: query += """ ORDER BY timestamp DESC """ c.execute(query) rows = c.fetchall() conn.close() return rows # ================================================== # Render Card # ================================================== def render_card(row): ( testimonial_id, name, role, content, sentiment, rating, timestamp, likes, is_highlighted ) = row name = escape_safe(name) role = escape_safe(role) content = escape_safe(content) stars = "⭐" * int(rating) highlight_style = "" if is_highlighted: highlight_style = """ border-right:5px solid #f59e0b; background:#fffbeb; """ role_html = "" if role: role_html = f""" {role} """ return f"""
منصة آراء مباشرة وشفافة