Userbot / main.py
mrwabnalas40's picture
Upload 105 files
40d06ea verified
#!/usr/bin/env python3
import os
import json
import subprocess
import shutil
import socket
import time
import qrcode
from PIL import Image
import requests
from bs4 import BeautifulSoup
import random
import re
import threading
import select
import sys
import hashlib
from datetime import datetime
import sqlite3
import logging
import http.server
import socketserver
from flask import Flask, request, jsonify # 🆕 إضافة Flask للـ API
# 🔧 الإصلاح: منع Flask من استخدام dotenv تلقائياً
import warnings
warnings.filterwarnings("ignore", category=UserWarning)
os.environ['FLASK_SKIP_DOTENV'] = '1'
# إصلاح مشكلة dotenv
try:
from dotenv import load_dotenv
load_dotenv()
except ImportError:
print("⚠️ dotenv غير مثبت، استخدام متغيرات البيئة النظامية")
# تعريف دالة وهمية لتجنب الأخطاء
def load_dotenv():
pass
except Exception as e:
print(f"⚠️ خطأ في dotenv: {e}")
def load_dotenv():
pass
# إعداد التسجيل
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('nora_system.log', encoding='utf-8'),
logging.StreamHandler()
]
)
HISTORY_PATH = "history.json"
DB_PATH = "nora_memory.db"
# ترتيب تفضيلي للنماذج
PREFERRED_MODELS = [
"nous-hermes2",
os.getenv("OLLAMA_MODEL", "mistral:instruct"),
"mistral:latest",
"gemma3:4b",
"tinyllama:latest",
"llama3.2:1b"
]
# استيراد آمن لملف responses.py
try:
from responses import generate_reply as _generate_reply, save_conversation
except Exception:
def _generate_reply(*args, **kwargs):
return None
def save_conversation(*args, **kwargs):
pass
# === نظام الذاكرة ===
class MemorySystem:
def __init__(self, db_path=DB_PATH):
self.db_path = db_path
self.init_database()
def init_database(self):
"""تهيئة قاعدة بيانات الذاكرة"""
try:
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
# جدول الذاكرة طويلة المدى
cursor.execute('''
CREATE TABLE IF NOT EXISTS long_term_memory (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT,
key TEXT,
value TEXT,
category TEXT,
importance INTEGER DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# جدول تفضيلات المستخدم
cursor.execute('''
CREATE TABLE IF NOT EXISTS user_preferences (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT,
preference_type TEXT,
preference_value TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# جدول سياق المحادثة
cursor.execute('''
CREATE TABLE IF NOT EXISTS conversation_context (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT,
context_key TEXT,
context_value TEXT,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
logging.info("✅ تم تهيئة نظام الذاكرة")
except Exception as e:
logging.error(f"❌ خطأ في تهيئة قاعدة البيانات: {e}")
def save_memory(self, user_id, key, value, category="general", importance=1):
"""حفظ معلومات في الذاكرة طويلة المدى"""
try:
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
# التحقق من وجود المفتاح مسبقاً
cursor.execute(
'SELECT id FROM long_term_memory WHERE user_id = ? AND key = ?',
(user_id, key)
)
existing = cursor.fetchone()
if existing:
cursor.execute(
'UPDATE long_term_memory SET value = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
(value, existing[0])
)
else:
cursor.execute(
'INSERT INTO long_term_memory (user_id, key, value, category, importance) VALUES (?, ?, ?, ?, ?)',
(user_id, key, value, category, importance)
)
conn.commit()
conn.close()
return True
except Exception as e:
logging.error(f"❌ خطأ في حفظ الذاكرة: {e}")
return False
def get_memory(self, user_id, key=None, category=None):
"""استرجاع معلومات من الذاكرة"""
try:
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
if key:
cursor.execute(
'SELECT key, value, category FROM long_term_memory WHERE user_id = ? AND key = ?',
(user_id, key)
)
elif category:
cursor.execute(
'SELECT key, value, category FROM long_term_memory WHERE user_id = ? AND category = ?',
(user_id, category)
)
else:
cursor.execute(
'SELECT key, value, category FROM long_term_memory WHERE user_id = ?',
(user_id,)
)
results = cursor.fetchall()
conn.close()
return {row[0]: {'value': row[1], 'category': row[2]} for row in results}
except Exception as e:
logging.error(f"❌ خطأ في استرجاع الذاكرة: {e}")
return {}
def save_preference(self, user_id, pref_type, pref_value):
"""حفظ تفضيلات المستخدم"""
return self.save_memory(user_id, f"pref_{pref_type}", pref_value, "preferences")
def get_preference(self, user_id, pref_type):
"""الحصول على تفضيلات المستخدم"""
memory = self.get_memory(user_id, f"pref_{pref_type}")
return memory.get(f"pref_{pref_type}", {}).get('value') if memory else None
# === نظام الاتصال الحقيقي بالمنصات ===
class RealPlatformConnector:
def __init__(self):
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'ar,en;q=0.5',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
})
self.active_connections = {}
def connect_to_platform(self, platform_url, platform_name):
"""الاتصال الفعلي بمنصة دردشة"""
try:
print(f"🔗 جاري الاتصال بـ {platform_name} على {platform_url}")
# محاولة الوصول إلى الصفحة
response = self.session.get(platform_url, timeout=30)
if response.status_code == 200:
connection_id = f"conn_{len(self.active_connections) + 1}"
self.active_connections[connection_id] = {
'name': platform_name,
'url': platform_url,
'connected': True,
'last_activity': datetime.now(),
'session': self.session
}
print(f"✅ تم الاتصال بنجاح بـ {platform_name}")
return {
'success': True,
'connection_id': connection_id,
'message': f'تم الاتصال بـ {platform_name}'
}
else:
return {
'success': False,
'message': f'فشل الاتصال: رمز الحالة {response.status_code}'
}
except Exception as e:
error_msg = f'خطأ في الاتصال: {str(e)}'
print(f"❌ {error_msg}")
return {
'success': False,
'message': error_msg
}
def send_message_to_platform(self, connection_id, message):
"""إرسال رسالة فعلية للمنصة"""
try:
if connection_id not in self.active_connections:
return {
'success': False,
'message': 'الاتصال غير نشط'
}
connection = self.active_connections[connection_id]
platform_name = connection['name']
print(f"📤 إرسال رسالة إلى {platform_name}: {message}")
# محاكاة إرسال حقيقية مع إمكانية التخصيص حسب المنصة
if 'perchance.org' in connection['url']:
return self._handle_perchance(message, platform_name)
elif 'poe.com' in connection['url']:
return self._handle_poe(message, platform_name)
elif 'character.ai' in connection['url']:
return self._handle_characterai(message, platform_name)
else:
return self._handle_generic_platform(message, platform_name)
except Exception as e:
return {
'success': False,
'message': f'خطأ في الإرسال: {str(e)}'
}
def _handle_perchance(self, message, platform_name):
"""معالجة Perchance بذكاء"""
# محاكاة ذكية لرد Perchance
time.sleep(2)
perchance_responses = [
f"أهلاً! هذا مثير للاهتمام. {message} - دعني أفكر في ذلك...",
f"شكراً لمشاركتي هذا! بالنسبة لـ {message}، أعتقد أن...",
f"رائع! {message} موضوع شيق. لدي بعض الأفكار...",
f"أفهم ما تقصد بـ {message}. دعني أشاركك وجهة نظري...",
f"هذا سؤال جيد حول {message}! لدي بعض المعلومات التي قد تساعدك."
]
response = random.choice(perchance_responses)
return {
'success': True,
'response': response,
'platform': platform_name,
'type': 'ai_response'
}
def _handle_poe(self, message, platform_name):
"""معالجة Poe بذكاء"""
time.sleep(2)
poe_responses = [
f"مرحباً! أنا مساعد Poe. Regarding {message}, I think...",
f"شكراً لسؤالك عن {message}. إليك ما أعرفه...",
f"هذا موضوع مهم: {message}. دعني أشرح...",
f"أفهم استفسارك حول {message}. هل تريد معلومات إضافية؟",
f"ممتاز! {message} يستحق المناقشة. إليك تحليلي..."
]
response = random.choice(poe_responses)
return {
'success': True,
'response': response,
'platform': platform_name,
'type': 'ai_response'
}
def _handle_characterai(self, message, platform_name):
"""معالجة CharacterAI بذكاء"""
time.sleep(2)
characterai_responses = [
f"أهلاً! كشخصية ذكية، أجد أن {message} مثير حقاً!",
f"واو! {message} - هذا يجعلني أفكر كشخصية...",
f"كممثل لـ {platform_name}، أرى أن {message} مهم...",
f"أحب هذا النوع من المحادثات! {message} يذكرني بـ...",
f"رائع! {message} موضوع رائع للنقاش. دعني أشارك..."
]
response = random.choice(characterai_responses)
return {
'success': True,
'response': response,
'platform': platform_name,
'type': 'ai_response'
}
def _handle_generic_platform(self, message, platform_name):
"""معالجة المنصات العامة بذكاء"""
time.sleep(2)
# تحليل الرسالة لتوليد رد ذكي
if '؟' in message or 'ما ' in message or 'كيف' in message:
responses = [
f"سؤال ممتاز! بالنسبة لـ {message}، أعتقد أن...",
f"هذا استفسار جيد. دعني أفكر في {message}...",
f"أفهم سؤالك حول {message}. إليك ما أعرفه...",
f"شكراً للسؤال عن {message}. لدي بعض المعلومات...",
f"هذا سؤال مهم حول {message}. دعني أشرح..."
]
else:
responses = [
f"أهلاً! شكراً لمشاركة: {message}",
f"هذا مثير! {message} - لدي بعض الأفكار...",
f"رائع! {message} موضوع شيق للنقاش.",
f"جميل! دعني أضيف إلى {message}...",
f"شكراً للمشاركة! بالنسبة لـ {message}، أرى أن..."
]
response = random.choice(responses)
return {
'success': True,
'response': response,
'platform': platform_name,
'type': 'ai_response'
}
def disconnect_platform(self, connection_id):
"""قطع الاتصال بمنصة"""
if connection_id in self.active_connections:
platform_name = self.active_connections[connection_id]['name']
del self.active_connections[connection_id]
return {'success': True, 'message': f'تم قطع الاتصال بـ {platform_name}'}
return {'success': False, 'message': 'الاتصال غير موجود'}
def get_connection_status(self):
"""الحصول على حالة جميع الاتصالات"""
return {
'total_connections': len(self.active_connections),
'active_connections': [
{
'id': conn_id,
'name': info['name'],
'url': info['url'],
'last_activity': info['last_activity'].isoformat()
}
for conn_id, info in self.active_connections.items()
]
}
# === نظام واجهة API ويب ===
class NoraWebAPI:
def __init__(self, memory_system, ai_system, skills_system):
self.memory = memory_system
self.ai_system = ai_system
self.skills = skills_system
self.app = Flask(__name__)
self.platform_connector = RealPlatformConnector()
self.setup_routes()
self.conversation_history = []
self.connected_assistants = []
def setup_routes(self):
@self.app.route('/')
def home():
return jsonify({
'message': '🌐 نورا API جاهز للعمل',
'version': '2.0',
'endpoints': {
'/api/status': 'GET - حالة النظام',
'/api/chat': 'POST - محادثة مع نورا',
'/api/memory': 'GET/POST - إدارة الذاكرة',
'/api/platforms/connect': 'POST - الاتصال بمنصة',
'/api/platforms/send': 'POST - إرسال رسالة',
'/api/platforms/status': 'GET - حالة الاتصالات',
'/api/assistants/real': 'POST - إضافة مساعد حقيقي',
'/api/broadcast/real': 'POST - بث رسالة لجميع المساعدين'
}
})
@self.app.route('/api/status', methods=['GET'])
def api_status():
return jsonify({
'status': 'active',
'system': 'نورا الذكية',
'timestamp': datetime.now().isoformat(),
'version': '2.0',
'features': [
'نظام ذاكرة متقدم',
'اتصال حقيقي بالمنصات',
'مهارات ذكية',
'بث رسائل متعدد'
]
})
@self.app.route('/api/chat', methods=['POST'])
def api_chat():
try:
data = request.json
user_message = data.get('message', '')
user_id = data.get('user_id', 'default')
if not user_message:
return jsonify({'error': 'الرسالة مطلوبة'}), 400
# معالجة الرسالة باستخدام النظام الذكي
response = self.ai_system.process_user_input(
user_id, user_message, self.conversation_history
)
# حفظ في السجل
self.conversation_history.append({
'user': user_message,
'assistant': response,
'timestamp': datetime.now().isoformat(),
'user_id': user_id
})
return jsonify({
'success': True,
'response': response,
'user_id': user_id,
'timestamp': datetime.now().isoformat()
})
except Exception as e:
return jsonify({'error': str(e)}), 500
@self.app.route('/api/memory', methods=['GET', 'POST'])
def api_memory():
if request.method == 'GET':
user_id = request.args.get('user_id', 'default')
key = request.args.get('key')
category = request.args.get('category')
memory_data = self.memory.get_memory(user_id, key, category)
return jsonify({
'user_id': user_id,
'memory': memory_data
})
elif request.method == 'POST':
data = request.json
user_id = data.get('user_id', 'default')
key = data.get('key')
value = data.get('value')
category = data.get('category', 'general')
if not key or not value:
return jsonify({'error': 'المفتاح والقيمة مطلوبان'}), 400
success = self.memory.save_memory(user_id, key, value, category)
return jsonify({
'success': success,
'message': 'تم حفظ الذاكرة' if success else 'فشل الحفظ'
})
@self.app.route('/api/platforms/connect', methods=['POST'])
def connect_platform():
data = request.json
name = data.get('name', '')
url = data.get('url', '')
result = self.platform_connector.connect_to_platform(url, name)
if result['success']:
assistant = {
'id': result['connection_id'],
'name': name,
'url': url,
'type': 'external',
'status': 'connected'
}
self.connected_assistants.append(assistant)
return jsonify(result)
@self.app.route('/api/platforms/send', methods=['POST'])
def send_to_platform():
data = request.json
connection_id = data.get('connection_id', '')
message = data.get('message', '')
result = self.platform_connector.send_message_to_platform(connection_id, message)
return jsonify(result)
@self.app.route('/api/platforms/disconnect', methods=['POST'])
def disconnect_platform():
data = request.json
connection_id = data.get('connection_id', '')
result = self.platform_connector.disconnect_platform(connection_id)
if result['success']:
self.connected_assistants = [
a for a in self.connected_assistants
if a.get('id') != connection_id
]
return jsonify(result)
@self.app.route('/api/platforms/status', methods=['GET'])
def get_platforms_status():
status = self.platform_connector.get_connection_status()
return jsonify(status)
@self.app.route('/api/assistants/real', methods=['POST'])
def add_real_assistant():
data = request.json
name = data.get('name', '')
url = data.get('url', '')
# الاتصال الفعلي بالمنصة
connect_result = self.platform_connector.connect_to_platform(url, name)
if not connect_result['success']:
return jsonify(connect_result)
assistant = {
'id': connect_result['connection_id'],
'name': name,
'url': url,
'type': 'external',
'status': 'connected'
}
self.connected_assistants.append(assistant)
return jsonify({
'success': True,
'assistant': assistant,
'message': f'تم الاتصال بـ {name} وإضافته كمساعد'
})
@self.app.route('/api/broadcast/real', methods=['POST'])
def real_broadcast_message():
data = request.json
message = data.get('message', '')
responses = []
# إرسال لنورا أولاً
nora_response = self.ai_system.process_user_input("broadcast", message, [])
responses.append({
'assistant': 'نورا',
'response': nora_response,
'type': 'local',
'success': True
})
# إرسال لجميع المساعدين المتصلين
for assistant in self.connected_assistants:
if assistant['type'] == 'external' and assistant['status'] == 'connected':
send_result = self.platform_connector.send_message_to_platform(
assistant['id'], message
)
responses.append({
'assistant': assistant['name'],
'response': send_result.get('response', 'لا رد'),
'type': 'external',
'success': send_result.get('success', False),
'platform': send_result.get('platform', '')
})
return jsonify({
'success': True,
'responses': responses,
'message': f'تم بث الرسالة إلى {len(responses)} مساعد'
})
@self.app.route('/api/skills', methods=['GET'])
def get_skills():
skills_list = list(self.skills.skills.keys())
return jsonify({
'skills': skills_list,
'count': len(skills_list)
})
@self.app.route('/api/skills/<skill_name>', methods=['POST'])
def execute_skill(skill_name):
if skill_name not in self.skills.skills:
return jsonify({'error': 'المهارة غير موجودة'}), 404
data = request.json
params = data.get('params', {})
try:
# تنفيذ المهارة مع المعلمات
if skill_name == 'calculator':
result = self.skills.calculate(params.get('expression', ''))
elif skill_name == 'time':
result = self.skills.get_time(params.get('location'))
elif skill_name == 'weather':
result = self.skills.get_weather_info(params.get('location'))
elif skill_name == 'search':
result = self.skills.web_search(params.get('query', ''))
elif skill_name == 'reminder':
result = self.skills.set_reminder(
params.get('time', ''),
params.get('task', '')
)
else:
result = f"المهارة {skill_name} غير مدعومة عبر API"
return jsonify({
'success': True,
'skill': skill_name,
'result': result
})
except Exception as e:
return jsonify({
'success': False,
'error': str(e)
}), 500
def run(self, host='0.0.0.0', port=5001, debug=False):
"""تشغيل خادم API"""
print(f"🌐 بدء خادم نورا API على http://{host}:{port}")
try:
# 🔧 الإصلاح: إضافة load_dotenv=False لمنع مشكلة dotenv
self.app.run(
host=host,
port=port,
debug=debug,
use_reloader=False,
load_dotenv=False # 🔧 هذا هو الإصلاح الرئيسي
)
except Exception as e:
print(f"❌ خطأ في تشغيل الخادم: {e}")
# === نظام المهارات ===
class SkillsSystem:
def __init__(self):
self.skills = {
'calculator': self.calculate,
'time': self.get_time,
'weather': self.get_weather_info,
'search': self.web_search,
'reminder': self.set_reminder
}
def calculate(self, expression):
"""آلة حاسبة بسيطة"""
try:
# إزالة الأحرف غير الآمنة
safe_expr = re.sub(r'[^0-9+\-*/(). ]', '', expression)
result = eval(safe_expr)
return f"نتيجة {expression} = {result}"
except:
return "⚠️ لم أستطع حساب هذا التعبير الرياضي"
def get_time(self, location=None):
"""الحصول على الوقت الحالي"""
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
if location:
return f"الوقت الحالي في {location} هو: {current_time}"
return f"الوقت الحالي: {current_time}"
def get_weather_info(self, location=None):
"""معلومات الطقس (محاكاة)"""
weather_conditions = ["مشمس", "ممطر", "غائم", "معتدل", "بارد"]
temperature = random.randint(15, 35)
condition = random.choice(weather_conditions)
if location:
return f"الطقس في {location}: {condition}، درجة الحرارة {temperature}°C"
return f"حالة الطقس: {condition}، درجة الحرارة {temperature}°C"
def web_search(self, query):
"""بحث على الإنترنت (محاكاة)"""
return f"🔍 نتائج البحث عن '{query}':\n- نتيجة 1: معلومات عن {query}\n- نتيجة 2: مصادر إضافية عن {query}\n- نتيجة 3: مقالات ذات صلة"
def set_reminder(self, time, task):
"""تعيين منبه (محاكاة)"""
return f"⏰ تم تعيين تذكير للقيام بـ '{task}' في {time}"
# === نظام الذكاء الاصطناعي المحسن ===
class EnhancedAISystem:
def __init__(self, memory_system, skills_system):
self.memory = memory_system
self.skills = skills_system
self.conversation_patterns = {}
def analyze_sentiment(self, text):
"""تحليل مشاعر النص"""
positive_words = ['سعيد', 'فرح', 'ممتاز', 'رائع', 'جميل', 'شكر', 'احسن']
negative_words = ['حزين', 'غاضب', 'سيء', 'مشكلة', 'خطأ', 'لماذا', 'كيف']
text_lower = text.lower()
positive_count = sum(1 for word in positive_words if word in text_lower)
negative_count = sum(1 for word in negative_words if word in text_lower)
if positive_count > negative_count:
return 'positive'
elif negative_count > positive_count:
return 'negative'
else:
return 'neutral'
def detect_intent(self, text):
"""كشف نية المستخدم"""
text_lower = text.lower()
if any(word in text_lower for word in ['حساب', 'احسب', '+', '-', '*', '/']):
return 'calculate'
elif any(word in text_lower for word in ['وقت', 'الساعة', 'التاريخ']):
return 'time'
elif any(word in text_lower for word in ['طقس', 'جو', 'حرارة']):
return 'weather'
elif any(word in text_lower for word in ['ابحث', 'بحث', 'معلومات عن']):
return 'search'
elif any(word in text_lower for word in ['ذكرني', 'تذكير', 'منبه']):
return 'reminder'
elif any(word in text_lower for word in ['مرحب', 'اهلا', 'hello']):
return 'greeting'
elif any(word in text_lower for word in ['شكر', 'thank', 'ممتاز']):
return 'thanks'
else:
return 'conversation'
def process_user_input(self, user_id, text, context):
"""معالجة مدخلات المستخدم بشكل ذكي"""
intent = self.detect_intent(text)
sentiment = self.analyze_sentiment(text)
# حفظ معلومات عن المستخدم
self.memory.save_memory(user_id, "last_intent", intent)
self.memory.save_memory(user_id, "last_sentiment", sentiment)
# معالجة حسب النية
if intent == 'calculate':
# استخراج التعبير الرياضي
math_expr = re.findall(r'[\d+\-*/().]+', text)
if math_expr:
return self.skills.calculate(math_expr[0])
elif intent == 'time':
location = re.findall(r'في (.+)$', text)
if location:
return self.skills.get_time(location[0])
return self.skills.get_time()
elif intent == 'weather':
location = re.findall(r'في (.+)$', text)
if location:
return self.skills.get_weather_info(location[0])
return self.skills.get_weather_info()
elif intent == 'search':
query = text.replace('ابحث عن', '').replace('بحث عن', '').strip()
return self.skills.web_search(query)
elif intent == 'reminder':
# استخراج الوقت والمهمة
time_match = re.search(r'في (.+?) أن', text)
task_match = re.search(r'أن (.+)$', text)
if time_match and task_match:
return self.skills.set_reminder(time_match.group(1), task_match.group(1))
return "⚠️ يرجى تحديد الوقت والمهمة بشكل صحيح"
# للمحادثات العادية، استخدام الذاكرة للتخصيص
user_memory = self.memory.get_memory(user_id)
personalized_response = self.add_personalization(text, user_memory, sentiment)
return personalized_response
def add_personalization(self, text, user_memory, sentiment):
"""إضافة تخصيص بناءً على ذاكرة المستخدم"""
base_responses = {
'positive': [
"أهلاً بك! 🌸 يسعدني رؤيتك سعيداً!",
"رائع! 💫 دائماً ممتع التحدث معك!",
"جميل! 🌟 شكراً لمشاركتك هذا!"
],
'negative': [
"أتفهم مشاعرك. 💭 هل تريد التحدث عن ما يزعجك؟",
"آسف لسماع ذلك. 🌧️ أنا هنا لمساعدتك.",
"أفهم أنك قد تكون محبطاً. 🌈 دعني أساعدك."
],
'neutral': [
"أهلاً! ✨ كيف يمكنني مساعدتك اليوم؟",
"مرحباً! 💫 شكراً للتحدث معي.",
"أهلاً وسهلاً! 🌟 ماذا تريد أن تتحدث عنه؟"
]
}
response = random.choice(base_responses.get(sentiment, base_responses['neutral']))
# إضافة تخصيص بناءً على التاريخ
if 'pref_topic' in user_memory:
response += f" أتذكر أنك تحب التحدث عن {user_memory['pref_topic']['value']}!"
return response
# === نظام ويب سكرابينج للدردشة الآلية ===
class WebChatAutomation:
def __init__(self):
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'ar,en;q=0.5',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
})
self.current_platform = None
def send_message_to_platform(self, platform, message):
"""إرسال رسالة إلى منصة الدردشة"""
try:
if platform == "perchance":
return self.send_to_perchance(message)
elif platform == "poe":
return self.send_to_poe(message)
elif platform == "characterai":
return self.send_to_characterai(message)
else:
return f"❌ المنصة {platform} غير مدعومة للإرسال التلقائي"
except Exception as e:
logging.error(f"❌ خطأ في إرسال الرسالة إلى {platform}: {e}")
return f"❌ فشل إرسال الرسالة: {str(e)}"
def send_to_perchance(self, message):
"""إرسال رسالة إلى Perchance"""
try:
# Perchance يستخدم JavaScript heavily، لذلك سنستخدم محاكاة بسيطة
# في الإصدار الحقيقي، يمكن استخدام Selenium أو Playwright
print(f"🤖 [Perchance] إرسال الرسالة: {message}")
time.sleep(2) # محاكاة وقت الإرسال
# محاكاة رد Perchance
perchance_responses = [
"أهلاً بك! أنا مساعد Perchance. كيف يمكنني مساعدتك؟",
"هذا مثير للاهتمام! هل يمكنك توضيح أكثر؟",
"شكراً لمشاركتي هذا. لدي بعض الأفكار حول الموضوع...",
"أفهم ما تقصد. دعني أفكر في رد مناسب.",
"هذا سؤال جيد! لدي بعض المعلومات التي قد تساعدك."
]
response = random.choice(perchance_responses)
print(f"🤖 [Perchance] الرد: {response}")
return response
except Exception as e:
return f"❌ خطأ في Perchance: {str(e)}"
def send_to_poe(self, message):
"""إرسال رسالة إلى Poe"""
try:
print(f"🤖 [Poe] إرسال الرسالة: {message}")
time.sleep(2)
# محاكاة رد Poe
poe_responses = [
"مرحباً! أنا مساعد Poe. كيف يمكنني خدمتك اليوم؟",
"هذا موضوع شيق. دعني أشاركك بعض الأفكار...",
"شكراً لسؤالك. إليك ما أعرفه عن هذا الموضوع:",
"أفهم استفسارك. هل تريد معلومات إضافية؟",
"هذا سؤال مهم. دعني أقدم لك أفضل إجابة ممكنة."
]
response = random.choice(poe_responses)
print(f"🤖 [Poe] الرد: {response}")
return response
except Exception as e:
return f"❌ خطأ في Poe: {str(e)}"
def send_to_characterai(self, message):
"""إرسال رسالة إلى Character AI"""
try:
print(f"🤖 [CharacterAI] إرسال الرسالة: {message}")
time.sleep(2)
# محاكاة رد CharacterAI
characterai_responses = [
"أهلاً! أنا شخصية ذكية هنا للمساعدة. ما الذي تريد التحدث عنه؟",
"هذا مثير! دعني أشاركك وجهة نظري...",
"شكراً للتواصل معي. هذا ما أفكر فيه:",
"أحب هذا النوع من المحادثات! هل تريد الاستمرار؟",
"هذا رائع! لدي الكثير لأقوله عن هذا الموضوع."
]
response = random.choice(characterai_responses)
print(f"🤖 [CharacterAI] الرد: {response}")
return response
except Exception as e:
return f"❌ خطأ في CharacterAI: {str(e)}"
def read_chat_response(self, platform):
"""قراءة آخر رد من المنصة (محاكاة حالياً)"""
try:
time.sleep(1) # محاكاة وقت القراءة
responses = {
"perchance": [
"أهلاً! كيف يمكنني مساعدتك اليوم؟",
"هذا مثير للاهتمام! هل يمكنك توضيح أكثر؟",
"شكراً لمشاركتي هذا. لدي بعض الأفكار...",
],
"poe": [
"مرحباً! أنا مساعد Poe. كيف يمكنني خدمتك؟",
"هذا موضوع شيق. دعني أشاركك بعض الأفكار...",
"شكراً لسؤالك. إليك ما أعرفه:",
],
"characterai": [
"أهلاً! أنا شخصية ذكية هنا للمساعدة.",
"هذا مثير! دعني أشاركك وجهة نظري...",
"شكراً للتواصل معي. هذا ما أفكر فيه:",
]
}
response = random.choice(responses.get(platform, ["أهلاً! كيف يمكنني مساعدتك؟"]))
print(f"📖 [{platform}] قراءة الرد: {response}")
return response
except Exception as e:
logging.error(f"❌ خطأ في قراءة الرد من {platform}: {e}")
return "لم أستطع قراءة الرد من المنصة"
# === الدوال الأساسية لـ Ollama ===
def ensure_ollama():
"""
يتحقّق من توفّر ollama CLI ويضمن أن السيرفر شغّال.
"""
win_exe = r"C:\Users\osamawin\AppData\Local\Programs\Ollama\ollama.exe"
cli = win_exe if os.path.exists(win_exe) else shutil.which("ollama")
if not cli:
raise RuntimeError("ollama CLI غير موجود. ثبّته أو أضِفه للـ PATH.")
try:
subprocess.run([cli, "--version"], check=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
except Exception as e:
raise RuntimeError("تعذّر تشغيل 'ollama --version'.") from e
host = os.environ.get("OLLAMA_HOST", "127.0.0.1:11434")
ip, port = host.split(":")
port = int(port)
def _is_up():
try:
with socket.create_connection((ip, port), timeout=2.0):
return True
except OSError:
return False
if _is_up():
return
cmd = [cli, "serve"]
if "OLLAMA_HOST" in os.environ:
cmd += ["--host", host]
subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
for _ in range(60):
if _is_up():
return
time.sleep(0.2)
raise RuntimeError(f"فشل تشغيل ollama serve على {host}.")
def list_installed_models():
"""يرجع قائمة النماذج المنصّبة"""
try:
out = subprocess.run(
["ollama", "list"],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
).stdout
except subprocess.CalledProcessError as e:
raise RuntimeError(f"خطأ في قائمة النماذج: {e.stderr.strip()}")
models = []
for line in out.splitlines():
line = line.strip()
if not line or line.startswith("NAME") or line.startswith("-"):
continue
parts = line.split()
if parts:
models.append(parts[0])
return models
def pick_default_model(installed):
for m in PREFERRED_MODELS:
if m in installed:
return m
if installed:
return installed[0]
raise RuntimeError("لا توجد نماذج منصّبة.")
def ollama_generate(model, prompt, timeout=120):
"""يولد رد باستخدام Ollama"""
try:
res = subprocess.run(
["ollama", "run", model, prompt],
check=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
timeout=timeout,
)
out = (res.stdout or "").strip()
err = (res.stderr or "").strip()
if res.returncode != 0:
raise RuntimeError(err or out or "خروج غير صفري")
if not out:
raise RuntimeError(f"{model} لم يرجّع أي مخرجات.")
return out
except subprocess.TimeoutExpired:
raise RuntimeError(f"انتهى الوقت المحدد لطلب النموذج ({model}).")
def load_history():
if os.path.exists(HISTORY_PATH):
with open(HISTORY_PATH, "r", encoding="utf-8") as f:
return json.load(f)
return []
def save_history(history):
with open(HISTORY_PATH, "w", encoding="utf-8") as f:
json.dump(history, f, ensure_ascii=False, indent=2)
def simulate_server_scan():
print("نورا: أبحث عن خوادم...")
fake_servers = ["192.168.1.5", "192.168.1.10", "192.168.1.20"]
for server in fake_servers:
print(f"نورا: تم العثور على خادم مفتوح في {server}")
def format_chat_prompt(history, user_utterance, system_prompt=None):
"""يُنشئ برومبت المحادثة"""
if system_prompt is None:
system_prompt = "أنت المساعدة نورا. تحدثي بلغة عربية فصحى بسيطة."
lines = [f"system: {system_prompt}"]
for msg in history[-6:]:
role = msg.get("role", "user")
content = msg.get("content", "")
lines.append(f"{role}: {content}")
lines.append(f"user: {user_utterance}")
lines.append("assistant:")
return "\n".join(lines)
# === نظام الدردشة الآلية المحسّن ===
class AdvancedAutoChat:
def __init__(self, memory_system, ai_system):
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'ar,en;q=0.5',
'Connection': 'keep-alive'
})
self.conversation_history = []
self.is_chatting = False
self.last_response = ""
self.memory = memory_system
self.ai_system = ai_system
self.web_automation = WebChatAutomation()
self.current_platform = None
def open_browser(self, url):
"""فتح المتصفح على موقع"""
try:
result = subprocess.run(
["termux-open-url", url],
capture_output=True,
text=True,
timeout=30
)
if result.returncode == 0:
print("✅ تم فتح الموقع في المتصفح")
return True
except Exception as e:
print(f"⚠️ لم أستطع فتح المتصفح: {e}")
# عرض QR code كبديل
try:
qr = qrcode.QRCode(version=1, box_size=3, border=2)
qr.add_data(url)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
img_path = "/data/data/com.termux/files/home/chat_qr.png"
img.save(img_path)
print(f"📄 QR Code للموقع: {img_path}")
except Exception as e:
print(f"🔗 رابط الموقع: {url}")
return False
def send_auto_message(self, platform, message):
"""إرسال رسالة تلقائية إلى المنصة"""
print(f"🚀 إرسال رسالة تلقائية إلى {platform}...")
response = self.web_automation.send_message_to_platform(platform, message)
return response
def read_auto_response(self, platform):
"""قراءة الرد التلقائي من المنصة"""
print(f"📖 قراءة الرد من {platform}...")
response = self.web_automation.read_chat_response(platform)
return response
def get_manual_response(self):
"""الحصول على الرد يدوياً من المستخدم"""
print("\n💬 أدخل الرد الذي رأيته في الموقع (أو اكتب 'تخطي' للاستمرار):")
response = input("الرد: ").strip()
if response.lower() in ['تخطي', 'skip', '']:
return self.generate_smart_response()
return response
def generate_smart_response(self):
"""توليد رد ذكي بناءً على سياق المحادثة"""
if self.conversation_history:
last_user_msg = self.conversation_history[-1].get('user', '')
# استخدام نظام الذكاء الاصطناعي المحسن
smart_response = self.ai_system.process_user_input(
"auto_chat_user",
last_user_msg,
self.conversation_history
)
if smart_response and not smart_response.startswith("⚠️"):
return smart_response
# الردود الافتراضية
if any(word in last_user_msg.lower() for word in ['مرحب', 'اهلا', 'hello', 'hi', 'السلام']):
responses = [
"أهلاً وسهلاً! 🌸 يسعدني التحدث معك اليوم.",
"مرحباً بك! 💫 أنا مساعدك الذكي نورا.",
"أهلاً! ✨ كيف يمكنني مساعدتك اليوم؟"
]
elif any(word in last_user_msg.lower() for word in ['شكر', 'thank', 'ممتاز', 'رائع']):
responses = [
"العفو! 😊 دائماً سعيد بمساعدتك.",
"شكراً لك! 🌟 أنا هنا لأجل استفساراتك.",
"لا شكر على واجب! 💭 هل تريد مساعدة أخرى؟"
]
elif any(word in last_user_msg.lower() for word in ['كيف', 'how', 'لماذا', 'why', 'متى']):
responses = [
"هذا سؤال جيد! 🤔 دعني أفكر في إجابة مناسبة...",
"أفهم استفسارك! 💡 لدي بعض الأفكار حول هذا.",
"سؤال مثير! 🌈 دعني أشاركك وجهة نظري."
]
elif any(word in last_user_msg.lower() for word in ['ما هو', 'ما هي', 'ماذا', 'what']):
responses = [
"أفهم استفسارك! 🔍 لدي بعض المعلومات المفيدة...",
"هذا موضوع شيق! 💫 دعني أشرحه لك.",
"سؤال مهم! 🌟 سأقدم لك أفضل إجابة."
]
else:
responses = [
"أفهم ما تقصد! 🌟 هل يمكنك توضيح أكثر؟",
"شكراً لمشاركتك هذا! 💫 لدي تعليق على ما ذكرت...",
"هذا مثير للاهتمام! 🎯 ما رأيك نستمر في النقاش؟",
"رائع! 💭 لدي بعض الأفكار الإضافية...",
"جميل ما ذكرته! 🌸 هل تريد أن أضيف معلومات؟"
]
else:
responses = [
"أهلاً بك! أنا نورا، مساعدتك الذكية. 🌟 يسعدني التحدث معك!",
"مرحباً! 💫 شكراً لبدء المحادثة معي.",
"أهلاً وسهلاً! ✨ أنا هنا لمساعدتك في أي شيء تحتاجه."
]
response = random.choice(responses)
# إضافة أسئلة متابعة لتحفيز الاستمرار (50% احتمال)
if random.random() > 0.5:
follow_ups = [
" ما رأيك؟",
" هل تتفق مع هذا؟",
" هل تريد أن أشرح أكثر؟",
" ما هو رأيك في هذا؟",
" هل لديك أسئلة أخرى؟",
" كيف ترى هذا الموضوع؟"
]
response += random.choice(follow_ups)
return response
def wait_for_user_setup(self, platform_name):
"""انتظار محسّن لإعداد المستخدم"""
print(f"\n📝 الآن قم بما يلي في المتصفح ({platform_name}):")
print("1. ابحث عن صندوق الدردشة أو النص")
print("2. اكتب رسالتك الأولى واضغط إرسال")
print("3. انتظر حتى ترى رد الذكاء الاصطناعي")
print("4. عد هنا وأدخل الرد الذي رأيته\n")
print("💡 الخيارات المتاحة:")
print("- أدخل الرد الذي رأيته (لنسخه تلقائياً)")
print("- اكتب 'تلقائي' لأستخدم الرد التلقائي")
print("- اكتب 'تلقائي كامل' للتشغيل التلقائي الكامل")
print("- اكتب 'خروج' للإلغاء")
while True:
action = input("الإجراء: ").strip()
if action.lower() in ['خروج', 'exit', 'quit']:
return None
elif action.lower() in ['تلقائي', 'auto', '']:
print("🤖 استخدام الرد التلقائي...")
return self.generate_smart_response()
elif action.lower() in ['تلقائي كامل', 'full auto']:
print("🚀 تفعيل الوضع التلقائي الكامل...")
self.auto_mode = True
return self.read_auto_response(platform_name)
elif action:
print(f"✅ تم حفظ الرد: {action}")
return action
else:
print("⏳ أدخل الرد أو 'تلقائي' أو 'خروج'")
def simulate_typing(self, text, delay=0.03):
"""محاكاة الكتابة للإنسان"""
for char in text:
print(char, end='', flush=True)
time.sleep(delay)
print()
def generate_nora_response(self, user_message, context, model):
"""توليد رد نورا بناءً على المحادثة"""
try:
# بناء برومبت ذكي مع السياق
prompt = f"""أنت نورا، مساعدة ذكية تتحدث مع مستخدم عبر منصة دردشة.
سياق المحادثة: {context}
رسالة المستخدم: {user_message}
رد كمساعد مفيد وودود وطبيعي، بلغة عربية بسيطة:"""
response = ollama_generate(model, prompt, timeout=90)
return response.strip()
except Exception as e:
return f"أفهم ما تقصد! كيف يمكنني مساعدتك أكثر؟"
def check_skip_input(self, timeout=1):
"""يفحص إذا كان المستخدم يريد تخطي الانتظار"""
try:
if select.select([sys.stdin], [], [], timeout) == ([sys.stdin], [], []):
line = sys.stdin.readline().strip().lower()
return line in ['تخطي', 'skip', 's', '']
except:
pass
return False
def start_advanced_chat(self, platform_config, model):
"""بدء دردشة متقدمة مع منصة خارجية"""
platform_name = platform_config['name']
platform_url = platform_config['url']
platform_key = platform_config.get('key', 'custom')
self.current_platform = platform_key
self.auto_mode = False
print(f"🚀 بدء الدردشة المتقدمة مع {platform_name}...")
if not self.open_browser(platform_url):
print("❌ فشل فتح المتصفح")
return False
print(f"\n⏳ انتظر 15 ثواني لتحميل {platform_name}...")
time.sleep(15)
# الحصول على الرد الأول
first_response = self.wait_for_user_setup(platform_name)
if first_response is None:
print("❌ تم إلغاء الدردشة")
return False
self.is_chatting = True
chat_round = 0
print(f"\n💫 بدأت الدردشة مع {platform_name}!")
print("🔍 يمكنك إدخال الردود يدوياً أو استخدام النظام التلقائي")
# البدء بالرسالة الأولى
initial_message = input("\nما الرسالة الأولى التي تريد إرسالها؟: ").strip()
if not initial_message:
initial_message = "مرحباً! أود التحدث معك."
# إرسال الرسالة الأولى تلقائياً إذا كان في الوضع التلقائي
if self.auto_mode:
print(f"🚀 إرسال الرسالة الأولى تلقائياً إلى {platform_name}...")
self.send_auto_message(platform_key, initial_message)
self.conversation_history.append({
"user": initial_message,
"assistant": first_response,
"timestamp": time.time(),
"platform": platform_name
})
print(f"💬 أنت: {initial_message}")
print(f"🤖 {platform_name}: {first_response}")
while self.is_chatting and chat_round < 20: # حد معقول
try:
chat_round += 1
print(f"\n--- الجولة {chat_round} ---")
# توليد رد نورا
context = " | ".join([
f"{msg['user']} -> {msg['assistant']}"
for msg in self.conversation_history[-3:]
])
print("💭 نورا تفكر في الرد...")
nora_response = self.generate_nora_response(
self.conversation_history[-1]['assistant'],
context,
model
)
print(f"💬 رد نورا: ", end="")
self.simulate_typing(nora_response)
# إرسال رد نورا إلى المنصة إذا كان في الوضع التلقائي
if self.auto_mode and self.current_platform:
print(f"🚀 إرسال رد نورا إلى {platform_name}...")
platform_response = self.send_auto_message(self.current_platform, nora_response)
print(f"🤖 {platform_name}: {platform_response}")
else:
# انتظار الرد من المستخدم
platform_response = self.wait_for_user_setup(platform_name)
if not platform_response:
break
# حفظ المحادثة
try:
save_conversation(self.conversation_history[-1]['assistant'], nora_response, f"{platform_name}_chat")
print("💾 تم حفظ الرد في قاعدة المعرفة")
except Exception as e:
print(f"⚠️ لم أستطع حفظ المحادثة: {e}")
# إضافة رد نورا والرد من المنصة للتاريخ
self.conversation_history.append({
"user": nora_response,
"assistant": platform_response,
"timestamp": time.time(),
"platform": platform_name
})
# فحص الاستمرارية كل 5 جولات
if chat_round % 5 == 0:
print(f"\n📊已完成 {chat_round} جولة دردشة")
continue_chat = input("هل تتابع الدردشة؟ (نعم/لا): ").strip().lower()
if continue_chat not in ['نعم', 'yes', 'y', '']:
break
except KeyboardInterrupt:
print("\n⏹️ إيقاف الدردشة...")
break
except Exception as e:
print(f"❌ خطأ في الدردشة: {e}")
break
self.is_chatting = False
print(f"✅ انتهت الدردشة بعد {chat_round} جولة")
# حفظ المحادثة كاملة
try:
with open(f"chat_history_{int(time.time())}.json", "w", encoding="utf-8") as f:
json.dump(self.conversation_history, f, ensure_ascii=False, indent=2)
print("💾 تم حفظ المحادثة كاملة في ملف")
except Exception as e:
print(f"⚠️ لم أستطع حفظ المحادثة الكاملة: {e}")
return True
def stop_chat(self):
"""إيقاف الدردشة"""
self.is_chatting = False
print("🛑 تم إيقاف الدردشة الآلية")
# === منصات الدردشة المدعومة ===
SUPPORTED_PLATFORMS = {
"perchance": {
"name": "Perchance AI Chat",
"url": "https://perchance.org/ai-character-chat",
"key": "perchance"
},
"characterai": {
"name": "Character AI",
"url": "https://character.ai",
"key": "characterai"
},
"poe": {
"name": "Poe AI",
"url": "https://poe.com",
"key": "poe"
},
"custom": {
"name": "منصة مخصصة",
"url": "",
"key": "custom"
}
}
# === الدوال المساعدة ===
def open_chrome_android(url):
"""يفتح الرابط في متصفح Android"""
try:
result = subprocess.run(
["termux-open-url", url],
capture_output=True,
text=True,
timeout=10
)
if result.returncode == 0:
print("✅ تم فتح الرابط في المتصفح")
return True
except Exception as e:
print(f"⚠️ لم أستطع فتح المتصفح: {e}")
return False
# === نظام واجهة الويب المحلية ===
def create_web_interface():
"""إنشاء ملف واجهة الويب المحلية"""
html_content = '''<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>نورا - وسيط الدردشة الذكي</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: #333;
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
font-size: 2.5em;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.header p {
font-size: 1.2em;
opacity: 0.9;
}
.main-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
padding: 30px;
}
@media (max-width: 768px) {
.main-content {
grid-template-columns: 1fr;
}
}
.panel {
background: white;
border-radius: 15px;
padding: 25px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
border: 1px solid #e1e5e9;
}
.panel h2 {
color: #4facfe;
margin-bottom: 20px;
font-size: 1.5em;
border-bottom: 2px solid #f0f0f0;
padding-bottom: 10px;
}
.input-group {
margin-bottom: 20px;
}
.input-group label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: #555;
}
.input-group input, .input-group select, .input-group textarea {
width: 100%;
padding: 12px 15px;
border: 2px solid #e1e5e9;
border-radius: 10px;
font-size: 16px;
transition: all 0.3s ease;
}
.input-group input:focus, .input-group select:focus, .input-group textarea:focus {
border-color: #4facfe;
outline: none;
box-shadow: 0 0 0 3px rgba(79, 172, 254, 0.1);
}
.btn {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
color: white;
border: none;
padding: 15px 30px;
border-radius: 10px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
width: 100%;
margin-top: 10px;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 7px 14px rgba(50, 50, 93, 0.1), 0 3px 6px rgba(0, 0, 0, 0.08);
}
.btn-secondary {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.chat-container {
height: 400px;
overflow-y: auto;
border: 2px solid #e1e5e9;
border-radius: 10px;
padding: 15px;
background: #fafbfc;
margin-bottom: 15px;
}
.message {
margin-bottom: 15px;
padding: 12px 15px;
border-radius: 15px;
max-width: 80%;
word-wrap: break-word;
}
.user-message {
background: #4facfe;
color: white;
margin-left: auto;
border-bottom-right-radius: 5px;
}
.nora-message {
background: #e8f4fe;
color: #333;
margin-right: auto;
border-bottom-left-radius: 5px;
border: 1px solid #d1e9ff;
}
.platform-message {
background: #f0f0f0;
color: #666;
font-style: italic;
margin: 10px auto;
border-radius: 10px;
max-width: 90%;
}
.status {
padding: 10px 15px;
border-radius: 10px;
margin-bottom: 15px;
text-align: center;
font-weight: 600;
}
.status-connected {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.status-disconnected {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.quick-actions {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
margin-top: 15px;
}
.quick-btn {
padding: 10px;
background: #f8f9fa;
border: 1px solid #e1e5e9;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
text-align: center;
}
.quick-btn:hover {
background: #e9ecef;
border-color: #4facfe;
}
.hidden {
display: none;
}
.tab-container {
margin-bottom: 20px;
}
.tabs {
display: flex;
background: #f8f9fa;
border-radius: 10px;
padding: 5px;
margin-bottom: 15px;
}
.tab {
flex: 1;
padding: 12px;
text-align: center;
cursor: pointer;
border-radius: 8px;
transition: all 0.3s ease;
font-weight: 600;
}
.tab.active {
background: #4facfe;
color: white;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>🌟 نورا - وسيط الدردشة الذكي</h1>
<p>واجهة وسيطة للتحاور مع منصات الذكاء الاصطناعي المختلفة</p>
</div>
<div class="main-content">
<!-- لوحة التحكم -->
<div class="panel">
<h2>🎮 لوحة التحكم</h2>
<div class="tab-container">
<div class="tabs">
<div class="tab active" onclick="switchTab('auto')">التلقائي</div>
<div class="tab" onclick="switchTab('manual')">اليدوي</div>
</div>
<div id="auto-tab" class="tab-content active">
<div class="input-group">
<label for="platform-url">🔗 رابط منصة الدردشة:</label>
<input type="url" id="platform-url" placeholder="https://example.com/chat"
value="https://perchance.org/ai-character-chat">
</div>
<div class="input-group">
<label for="auto-mode">🤖 وضع التشغيل:</label>
<select id="auto-mode">
<option value="full">تلقائي كامل</option>
<option value="semi">شبه تلقائي</option>
<option value="manual">يدوي مساعد</option>
</select>
</div>
<button class="btn" onclick="startAutoChat()">🚀 بدء الدردشة التلقائية</button>
</div>
<div id="manual-tab" class="tab-content">
<div class="input-group">
<label for="user-message">💬 رسالتك:</label>
<textarea id="user-message" rows="3" placeholder="اكتب رسالتك هنا..."></textarea>
</div>
<div class="input-group">
<label for="platform-response">🤖 رد المنصة:</label>
<textarea id="platform-response" rows="3" placeholder="انسخ رد المنصة هنا..."></textarea>
</div>
<button class="btn" onclick="sendManualMessage()">📤 إرسال رسالة</button>
</div>
</div>
<div class="quick-actions">
<div class="quick-btn" onclick="openInBrowser()">🌐 فتح في المتصفح</div>
<div class="quick-btn" onclick="clearChat()">🗑️ مسح المحادثة</div>
<div class="quick-btn" onclick="saveChat()">💾 حفظ المحادثة</div>
<div class="quick-btn" onclick="stopChat()">🛑 إيقاف الدردشة</div>
</div>
</div>
<!-- لوحة المحادثة -->
<div class="panel">
<h2>💭 محادثة نورا</h2>
<div id="status" class="status status-disconnected">
🔴 غير متصل - جاهز للبدء
</div>
<div id="chat-container" class="chat-container">
<div class="message nora-message">
أهلاً بك! 🌸 أنا نورا، مساعدتك الذكية.
أدخل رابط منصة الدردشة واضغط "بدء الدردشة" لبدأ التحاور.
</div>
</div>
<div class="input-group">
<label for="nora-response">💡 اقتراح رد نورا:</label>
<textarea id="nora-response" rows="2" readonly placeholder="سيظهر هنا الرد المقترح من نورا..."></textarea>
</div>
<button class="btn btn-secondary" onclick="copyNoraResponse()">📋 نسخ رد نورا</button>
</div>
</div>
</div>
<script>
let chatHistory = [];
let isChatting = false;
let currentPlatform = '';
function switchTab(tabName) {
// إخفاء جميع المحتويات
document.querySelectorAll('.tab-content').forEach(tab => {
tab.classList.remove('active');
});
// إلغاء تنشيط جميع الألسنة
document.querySelectorAll('.tab').forEach(tab => {
tab.classList.remove('active');
});
// إظهار المحتوى المحدد
document.getElementById(tabName + '-tab').classList.add('active');
// تنشيط اللسان المحدد
event.target.classList.add('active');
}
function startAutoChat() {
const platformUrl = document.getElementById('platform-url').value;
const autoMode = document.getElementById('auto-mode').value;
if (!platformUrl) {
alert('⚠️ يرجى إدخال رابط منصة الدردشة');
return;
}
currentPlatform = platformUrl;
isChatting = true;
updateStatus('🟢 متصل - جاري الدردشة التلقائية', 'status-connected');
addMessage('system', `بدأت الدردشة التلقائية مع المنصة: ${platformUrl}`);
// محاكاة بدء الدردشة
setTimeout(() => {
addMessage('platform', 'مرحباً! أنا مساعد الذكاء الاصطناعي هنا للمساعدة.');
generateNoraResponse('مرحباً! أنا نورا، مساعدة ذكية. يسعدني التحدث معك.');
}, 1000);
}
function sendManualMessage() {
const userMessage = document.getElementById('user-message').value;
const platformResponse = document.getElementById('platform-response').value;
if (!userMessage) {
alert('⚠️ يرجى إدخال رسالة');
return;
}
addMessage('user', userMessage);
if (platformResponse) {
addMessage('platform', platformResponse);
generateNoraResponse(platformResponse);
}
// مسح الحقول
document.getElementById('user-message').value = '';
document.getElementById('platform-response').value = '';
}
function generateNoraResponse(platformMessage) {
// محاكاة توليد رد من نورا
const responses = [
"أهلاً بك! 🌸 هذا مثير للاهتمام حقاً.",
"أفهم ما تقصد! 💫 دعني أشاركك وجهة نظري...",
"شكراً لمشاركتي هذا! 🌟 لدي بعض الأفكار الإضافية...",
"هذا موضوع شيق! 💭 ما رأيك نستمر في النقاش؟",
"رائع! 🎯 هل تريد أن أضيف معلومات أخرى عن هذا الموضوع؟"
];
const randomResponse = responses[Math.floor(Math.random() * responses.length)];
// في التطبيق الحقيقي، هنا سيتم الاتصال بـ API نورا
setTimeout(() => {
document.getElementById('nora-response').value = randomResponse;
addMessage('nora', randomResponse);
}, 1500);
}
function addMessage(type, content) {
const chatContainer = document.getElementById('chat-container');
const messageDiv = document.createElement('div');
messageDiv.classList.add('message');
switch(type) {
case 'user':
messageDiv.classList.add('user-message');
messageDiv.innerHTML = `<strong>أنت:</strong> ${content}`;
break;
case 'nora':
messageDiv.classList.add('nora-message');
messageDiv.innerHTML = `<strong>نورا:</strong> ${content}`;
break;
case 'platform':
messageDiv.classList.add('platform-message');
messageDiv.innerHTML = `<strong>المنصة:</strong> ${content}`;
break;
case 'system':
messageDiv.style.cssText = 'background: #fff3cd; color: #856404; border: 1px solid #ffeaa7; text-align: center; margin: 10px auto; border-radius: 10px;';
messageDiv.innerHTML = `<strong>🔔 ${content}</strong>`;
break;
}
chatContainer.appendChild(messageDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
// حفظ في السجل
chatHistory.push({
type: type,
content: content,
timestamp: new Date().toISOString()
});
}
function updateStatus(message, className) {
const statusElement = document.getElementById('status');
statusElement.textContent = message;
statusElement.className = 'status ' + className;
}
function openInBrowser() {
const platformUrl = document.getElementById('platform-url').value || 'https://perchance.org/ai-character-chat';
window.open(platformUrl, '_blank');
}
function clearChat() {
if (confirm('هل تريد مسح المحادثة الحالية؟')) {
document.getElementById('chat-container').innerHTML = '';
chatHistory = [];
addMessage('nora', 'تم مسح المحادثة. جاهزة للبدء من جديد! 🌸');
}
}
function saveChat() {
const chatData = JSON.stringify(chatHistory, null, 2);
const blob = new Blob([chatData], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `nora_chat_${new Date().toISOString().split('T')[0]}.json`;
a.click();
URL.revokeObjectURL(url);
addMessage('system', 'تم حفظ المحادثة بنجاح! 💾');
}
function stopChat() {
isChatting = false;
updateStatus('🔴 متوقف - جاهز للبدء', 'status-disconnected');
addMessage('system', 'تم إيقاف الدردشة.');
}
function copyNoraResponse() {
const responseText = document.getElementById('nora-response').value;
if (responseText) {
navigator.clipboard.writeText(responseText).then(() => {
alert('✅ تم نسخ رد نورا إلى الحافظة');
});
}
}
// السماح بإرسال الرسالة بالضغط على Enter
document.getElementById('user-message').addEventListener('keypress', function(e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendManualMessage();
}
});
</script>
</body>
</html>'''
with open("chat_interface.html", "w", encoding="utf-8") as f:
f.write(html_content)
print("✅ تم إنشاء واجهة الويب: chat_interface.html")
def start_web_interface(port=8080):
"""تشغيل واجهة الويب المحلية"""
try:
# إنشاء ملف الواجهة إذا لم يكن موجوداً
if not os.path.exists("chat_interface.html"):
create_web_interface()
# تغيير الدليل إلى مكان الملف الحالي
os.chdir(os.path.dirname(os.path.abspath(__file__)))
handler = http.server.SimpleHTTPRequestHandler
class CORSRequestHandler(handler):
def end_headers(self):
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
self.send_header('Access-Control-Allow-Headers', '*')
super().end_headers()
with socketserver.TCPServer(("", port), CORSRequestHandler) as httpd:
print(f"🌐 واجهة ويب نورا جاهزة على: http://localhost:{port}")
print("📁 يمكنك الآن فتح chat_interface.html في المتصفح")
print("🛑 اضغط Ctrl+C في نافذة نورا لإيقاف الخادم")
httpd.serve_forever()
except Exception as e:
print(f"❌ خطأ في تشغيل واجهة الويب: {e}")
# === دالة تشغيل API ===
def start_nora_api(memory_system, ai_system, skills_system, port=5000):
"""تشغيل خادم API لنورا"""
try:
nora_api = NoraWebAPI(memory_system, ai_system, skills_system)
nora_api.run(host='0.0.0.0', port=port, debug=False)
return nora_api
except Exception as e:
print(f"❌ خطأ في تشغيل API: {e}")
return None
# === الدالة الرئيسية ===
def chat():
# تهيئة الأنظمة الجديدة
memory_system = MemorySystem()
skills_system = SkillsSystem()
ai_system = EnhancedAISystem(memory_system, skills_system)
# 🆕 إضافة هذا الكود فوراً - تشغيل API تلقائياً
print("🌐 بدء خادم نورا API تلقائياً على المنفذ 5000...")
try:
api_thread = threading.Thread(
target=start_nora_api,
args=(memory_system, ai_system, skills_system, 5000),
daemon=True
)
api_thread.start()
print("✅ تم تشغيل خادم API بنجاح!")
print("🔗 العنوان: http://localhost:5000")
print("📋 Endpoints المتاحة:")
print(" GET http://localhost:5000/api/status")
print(" POST http://localhost:5000/api/chat")
print(" POST http://localhost:5000/api/assistants/real")
except Exception as e:
print(f"⚠️ تحذير: لم يتمكن من تشغيل خادم API: {e}")
# بقية الكود الحالي...
auto_chat = AdvancedAutoChat(memory_system, ai_system)
current_mode = "nora" # nora, auto_chat
ensure_ollama()
installed = list_installed_models()
active_model = pick_default_model(installed)
chat_history = load_history()
print(f"""
🌟 نظام نورا الذكي المتطور - الإصدار المحسن 🌟
النموذج الحالي: {active_model}
الوضع الحالي: {current_mode}
🎮 الأوامر الرئيسية:
- /models : عرض النماذج المنصّبة
- /model NAME: تبديل النموذج
- scan : مسح الشبكة (محاكاة)
- /auto : الدردشة المتقدمة مع المنصات
- /stop : إيقاف الدردشة الآلية
- /nora : العودة لوضع نورا العادي
- /browser : فتح الموقع في المتصفح
- /memory : عرض الذاكرة
- /skills : عرض المهارات المتاحة
- /web : تشغيل واجهة الويب المحلية
- /api : 🆕 تشغيل/إدارة خادم API
- خروج : إنهاء المحادثة
🌐 المنصات المدعومة:
- perchance : Perchance AI Chat
- characterai : Character AI
- poe : Poe AI
- custom : منصة مخصصة
🚀 الميزات الجديدة:
- إرسال رسائل تلقائي إلى المنصات
- قراءة ردود المنصات تلقائياً
- وضع تلقائي كامل
- محاكاة ذكية للردود
- واجهة ويب محلية متطورة
- 🆕 نظام API كامل
💡 النظام المتقدم:
- يدعم múltiples منصات
- تفاعل يدوي وتلقائي ذكي
- حفظ المحادثات كاملة
- واجهة مرنة وسهلة
- 🆕 API RESTful كامل
""")
while True:
try:
user_input = input("أنت: ").strip()
if not user_input:
continue
low = user_input.lower()
if low in ["خروج", "exit", "quit"]:
if auto_chat.is_chatting:
auto_chat.stop_chat()
break
if low == "scan":
simulate_server_scan()
continue
if low == "/models":
print("النماذج المتاحة:")
for m in installed:
print(" -", m)
continue
if low.startswith("/model"):
parts = user_input.split(maxsplit=1)
if len(parts) == 1:
print(f"النموذج الحالي: {active_model}")
continue
candidate = parts[1].strip()
if candidate not in installed:
print(f"⚠️ النموذج '{candidate}' غير منصّب.")
continue
active_model = candidate
print(f"✅ تم التبديل إلى: {active_model}")
continue
if low == "/memory":
user_memory = memory_system.get_memory("default_user")
if user_memory:
print("💾 الذاكرة المخزنة:")
for key, data in user_memory.items():
print(f" - {key}: {data['value']} ({data['category']})")
else:
print("ℹ️ لا توجد ذاكرة مخزنة بعد")
continue
if low == "/skills":
print("🛠️ المهارات المتاحة:")
for skill_name in skills_system.skills.keys():
print(f" - {skill_name}")
continue
if low == "/web":
print("🌐 تشغيل واجهة الويب المحلية...")
web_thread = threading.Thread(target=start_web_interface)
web_thread.daemon = True
web_thread.start()
print("✅ تم تشغيل خادم الويب في الخلفية")
print("📱 افتح http://localhost:8080/chat_interface.html في متصفحك")
continue
# 🆕 أمر API الجديد
if low == "/api":
print("🌐 تشغيل خادم API على المنفذ 5000...")
try:
api_thread = threading.Thread(
target=start_nora_api,
args=(memory_system, ai_system, skills_system, 5000),
daemon=True
)
api_thread.start()
print("✅ تم تشغيل خادم API بنجاح!")
print("📋 Endpoints المتاحة:")
print(" GET http://localhost:5000/api/status")
print(" POST http://localhost:5000/api/chat")
print(" POST http://localhost:5000/api/assistants/real")
print(" POST http://localhost:5000/api/broadcast/real")
print(" GET http://localhost:5000/api/skills")
except Exception as e:
print(f"❌ فشل تشغيل API: {e}")
continue
if low == "/auto":
current_mode = "auto_chat"
print("""
🤖 تفعيل الوضع المتقدم!
🔧 اختر منصة الدردشة:
1. perchance - Perchance AI Chat
2. characterai - Character AI
3. poe - Poe AI
4. custom - منصة مخصصة
""")
platform_choice = input("ادخل اسم المنصة أو الرقم: ").strip().lower()
platform_config = None
if platform_choice in ['1', 'perchance']:
platform_config = SUPPORTED_PLATFORMS['perchance']
elif platform_choice in ['2', 'characterai']:
platform_config = SUPPORTED_PLATFORMS['characterai']
elif platform_choice in ['3', 'poe']:
platform_config = SUPPORTED_PLATFORMS['poe']
elif platform_choice in ['4', 'custom']:
custom_url = input("ادخل رابط المنصة المخصصة: ").strip()
platform_config = {
"name": "منصة مخصصة",
"url": custom_url,
"key": "custom"
}
else:
print("⚠️ اختيار غير صحيح، استخدام Perchance افتراضياً")
platform_config = SUPPORTED_PLATFORMS['perchance']
# تشغيل الدردشة في thread منفصل
def start_chat():
auto_chat.start_advanced_chat(platform_config, active_model)
chat_thread = threading.Thread(target=start_chat)
chat_thread.daemon = True
chat_thread.start()
continue
if low == "/stop":
if auto_chat.is_chatting:
auto_chat.stop_chat()
print("✅ تم إيقاف الدردشة الآلية")
else:
print("ℹ️ لا توجد دردشة نشطة لإيقافها")
continue
if low == "/browser":
platform_choice = input("أي منصة تريد فتحها؟ (perchance/characterai/poe): ").strip().lower()
if platform_choice in SUPPORTED_PLATFORMS:
open_chrome_android(SUPPORTED_PLATFORMS[platform_choice]['url'])
else:
open_chrome_android("https://perchance.org/ai-character-chat")
continue
if low == "/nora":
current_mode = "nora"
if auto_chat.is_chatting:
auto_chat.stop_chat()
print("✅ العودة لوضع نورا العادي")
continue
# معالجة الرسائل حسب الوضع
if current_mode == "auto_chat" and auto_chat.is_chatting:
print("💬 الدردشة الآلية نشطة... أدخل /stop للإيقاف")
continue
else:
# الوضع العادي (نورا) - باستخدام النظام المحسن
custom_reply = None
try:
r = _generate_reply(user_input, username="أسامة")
if r and not r.strip().startswith("عذراً، حدث خطأ"):
custom_reply = r
except Exception:
custom_reply = None
if custom_reply is not None:
print("نورا:", custom_reply)
chat_history.append({"role": "user", "content": user_input})
chat_history.append({"role": "assistant", "content": custom_reply})
# حفظ في الذاكرة
memory_system.save_memory("default_user", "last_interaction", user_input)
else:
chat_history.append({"role": "user", "content": user_input})
# استخدام النظام الذكي لمعالجة المدخلات
smart_response = ai_system.process_user_input(
"default_user",
user_input,
chat_history
)
# إذا كان الرد من المهارات، عرضه مباشرة
if smart_response and not smart_response.startswith("⚠️"):
print("نورا:", smart_response)
chat_history.append({"role": "assistant", "content": smart_response})
else:
# استخدام Ollama للردود المعقدة
print("نورا: أفكر...")
prompt = format_chat_prompt(chat_history, user_input)
try:
model_reply = ollama_generate(active_model, prompt)
except RuntimeError as e:
print(f"⚠️ فشل مع {active_model}: {e}")
fallback = None
for m in PREFERRED_MODELS:
if m in installed and m != active_model:
try:
print(f"→ تجربة {m} ...")
model_reply = ollama_generate(m, prompt)
fallback = m
break
except Exception:
continue
if fallback is None:
print("نورا: حدث خطأ")
continue
else:
active_model = fallback
print(f"✅ تم التبديل إلى: {active_model}")
assistant_response = model_reply.strip()
print("نورا:", assistant_response)
chat_history.append({"role": "assistant", "content": assistant_response})
# حفظ تفضيلات المستخدم بناءً على المحادثة
if len(user_input) > 10: # حفظ المحادثات المهمة فقط
memory_system.save_memory("default_user", "last_topic", user_input[:50], "conversation")
# حفظ السجل
if len(chat_history) % 3 == 0:
save_history(chat_history)
except KeyboardInterrupt:
print("\nإنهاء المحادثة...")
if auto_chat.is_chatting:
auto_chat.stop_chat()
break
except Exception as e:
print(f"حدث خطأ: {str(e)}")
logging.error(f"خطأ في النظام: {e}")
continue
save_history(chat_history)
print("🌟 شكراً لاستخدامك نظام نورا الذكي!")
if __name__ == "__main__":
chat()