Spaces:
Sleeping
Sleeping
| """ | |
| أدوات مساعدة للبوت: | |
| - تقسيم الرسائل الطويلة (Telegram بحد 4096 حرف) | |
| - تنسيق الردود | |
| - تعريف الأوامر | |
| """ | |
| import re | |
| from typing import List | |
| # الحد الأقصى لرسالة تيليجرام | |
| TG_MAX_MSG = 4096 | |
| # حد آمن مع هامش للتنسيق | |
| SAFE_MSG_LIMIT = 3500 | |
| def split_message(text: str, limit: int = SAFE_MSG_LIMIT) -> List[str]: | |
| """ | |
| تقسيم نص طويل إلى عدة رسائل. | |
| يحترم حدود الكود والـ Markdown. | |
| """ | |
| if len(text) <= limit: | |
| return [text] | |
| parts: List[str] = [] | |
| current = "" | |
| # نمط لتقسيم على الأسطر الفارغة أولاً، ثم الأسطر العادية | |
| lines = text.split("\n") | |
| for line in lines: | |
| # إذا السطر نفسه أطول من الحد - قسمه على المسافات | |
| if len(line) > limit: | |
| chunks = _split_long_line(line, limit) | |
| for chunk in chunks: | |
| if len(current) + len(chunk) + 1 > limit: | |
| if current: | |
| parts.append(current.rstrip()) | |
| current = chunk | |
| else: | |
| current = (current + "\n" + chunk) if current else chunk | |
| continue | |
| if len(current) + len(line) + 1 > limit: | |
| if current: | |
| parts.append(current.rstrip()) | |
| current = line | |
| else: | |
| current = (current + "\n" + line) if current else line | |
| if current: | |
| parts.append(current.rstrip()) | |
| return parts | |
| def _split_long_line(line: str, limit: int) -> List[str]: | |
| """تقسيم سطر طويل - على المسافات إن وجدت، وإلا على الحدود الصلبة""" | |
| if len(line) <= limit: | |
| return [line] | |
| # إذا يوجد مسافات، نقسم على المسافات | |
| if " " in line: | |
| words = line.split(" ") | |
| chunks = [] | |
| current = "" | |
| for w in words: | |
| if len(current) + len(w) + 1 > limit: | |
| if current: | |
| chunks.append(current) | |
| # إذا الكلمة نفسها أطول من limit - قسمها بالقوة | |
| while len(w) > limit: | |
| chunks.append(w[:limit]) | |
| w = w[limit:] | |
| current = w | |
| else: | |
| current = (current + " " + w) if current else w | |
| if current: | |
| chunks.append(current) | |
| return chunks | |
| # لا توجد مسافات - تقسيم صلب على حدود الحد | |
| return [line[i:i+limit] for i in range(0, len(line), limit)] | |
| def format_github_repos(repos: list) -> str: | |
| """تنسيق قائمة repos كرسالة تيليجرام""" | |
| if not repos: | |
| return "لا توجد repos." | |
| lines = ["📋 ** Repositories **\n"] | |
| for r in repos[:15]: | |
| visibility = "🔒" if r.get("private") else "🌐" | |
| lines.append( | |
| f"{visibility} `{r['name']}`\n" | |
| f" {r.get('description', '—')} | ⭐ {r.get('stars', 0)} | {r.get('language', '—')}\n" | |
| ) | |
| return "\n".join(lines) | |
| def format_github_files(files: list) -> str: | |
| """تنسيق محتويات repo""" | |
| if not files: | |
| return "المجلد فارغ." | |
| lines = ["📁 **المحتويات**\n"] | |
| for f in files: | |
| icon = "📄" if f.get("type") == "file" else "📂" | |
| lines.append(f"{icon} `{f['name']}` ({f.get('size', 0)} bytes)") | |
| return "\n".join(lines) | |
| def format_error(msg: str) -> str: | |
| """تنسيق رسالة خطأ""" | |
| return f"❌ **خطأ**\n\n{msg}" | |
| def format_success(msg: str) -> str: | |
| """تنسيق رسالة نجاح""" | |
| return f"✅ {msg}" | |
| def escape_markdown(text: str) -> str: | |
| """تجاهل أحرف Markdown الخاصة (للنصوص العادية)""" | |
| escape_chars = r"_*[]()~`>#+-=|{}." | |
| return re.sub(f"([{re.escape(escape_chars)}])", r"\\\1", text) | |
| # قائمة أوامر البوت | |
| BOT_COMMANDS_AR = [ | |
| ("start", "ابدأ المحادثة / عرض الترحيب"), | |
| ("help", "عرض كل الأوامر المتاحة"), | |
| ("reset", "مسح ذاكرتي عن محادثاتك السابقة"), | |
| ("id", "عرض معرّفك الرقمي في تيليجرام"), | |
| ("stats", "إحصائيات الاستخدام (للمالك)"), | |
| ("usage", "استهلاكك اليومي من التوكنات"), | |
| ("providers", "عرض حالة مزودي LLM (للمالك)"), | |
| ("model", "عرض/تغيير النموذج المستخدم"), | |
| ("models", "عرض النماذج المتاحة"), | |
| ("lang", "تغيير لغة الرد (ar/en)"), | |
| ("github", "أوامر GitHub - استخدم /github help"), | |
| ("mystatus", "عرض وضعك (مالك/مشرف/مستخدم)"), | |
| # القدرات المتقدمة | |
| ("code", "تنفيذ كود Python"), | |
| ("pdf", "إنشاء PDF من نص"), | |
| ("docx", "إنشاء Word من نص"), | |
| ("xlsx", "إنشاء Excel من CSV"), | |
| ("chart", "إنشاء مخطط (bar/line/pie/...)"), | |
| ("search", "بحث في الويب (DuckDuckGo + Wiki)"), | |
| ("read", "قراءة محتوى رابط: /read <url>"), | |
| ("vision", "تحليل صورة (رد على صورة)"), | |
| ] | |
| HELP_TEXT = """ | |
| 🤖 **مساعد Z.ai - الأوامر المتاحة** | |
| **أوامر عامة:** | |
| • `/start` - بدء المحادثة وعرض الترحيب | |
| • `/help` - عرض هذه القائمة | |
| • `/reset` - مسح ذاكرة محادثاتك السابقة | |
| • `/id` - عرض معرّفك الرقمي | |
| • `/mystatus` - عرض وضعك في البوت | |
| • `/lang ar` أو `/lang en` - تغيير لغة الردود | |
| • `/model` - عرض النموذج الحالي | |
| • `/models` - عرض النماذج المتاحة | |
| **أوامر GitHub (للمالك والمشرفين فقط):** | |
| • `/github me` - معلومات حسابك | |
| • `/github repos` - سرد repos | |
| • `/github create <name> <desc>` - إنشاء repo جديد | |
| • `/github delete <owner/repo>` - حذف repo | |
| • `/github files <owner/repo> [path]` - سرد الملفات | |
| • `/github read <owner/repo> <path>` - قراءة ملف | |
| • `/github write <owner/repo> <path> <content>` - كتابة ملف | |
| • `/github branches <owner/repo>` - سرد الفروع | |
| • `/github commits <owner/repo>` - آخر commits | |
| • `/github issue <owner/repo> <title> | <body>` - فتح issue | |
| • `/github issues <owner/repo>` - سرد issues | |
| • `/github fork <owner/repo>` - fork | |
| **القدرات المتقدمة:** | |
| • `/code` - تنفيذ كود Python (أرسل الكود في السطر التالي) | |
| • `/pdf` - إنشاء PDF من نص (أو: `/pdf عنوان|محتوى`) | |
| • `/docx` - إنشاء Word من نص | |
| • `/xlsx` - إنشاء Excel من CSV (سطر لكل صف، فواصل بين الأعمدة) | |
| • `/chart نوع|عنوان|labels|values` - مخطط (bar/line/pie/scatter/histogram) | |
| • `/search <استعلام>` - بحث في DuckDuckGo + Wikipedia | |
| • `/read <url>` - استخراج محتوى صفحة ويب | |
| • `/vision <سؤال>` - تحليل صورة (رد على صورة موجودة) | |
| • إرسال صورة مباشرة - تحليل تلقائي | |
| **للمالك فقط:** | |
| • `/stats` - إحصائيات الاستخدام | |
| 💡 **ملاحظة:** للمالك أولوية قصوى في المعالجة - رسائلك تُعالَج قبل غيرك. | |
| 🔑 **Load Balancing:** إذا أضفت مفاتيح Z.ai متعددة (ZAI_API_KEYS_EXTRA) ستُستخدم بالتناوب لتجاوز حدود المعدل. | |
| """ | |
| WELCOME_OWNER_TEXT = """ | |
| 👋 أهلاً بك يا مالك! | |
| أنا مساعدك الشخصي مدعوم بنماذج Z.ai (GLM). لديك الأولوية القصوى في المعالجة. | |
| استطيع: | |
| • 💬 المحادثة والإجابة على الأسئلة | |
| • 📦 إدارة repos GitHub الكاملة | |
| • 🧠 تذكر سياق محادثاتنا السابقة | |
| أرسل `/help` لعرض كل الأوامر. | |
| """ | |
| WELCOME_USER_TEXT = """ | |
| 👋 أهلاً {first_name}! | |
| أنا مساعد Z.ai المدعوم بنماذج GLM. أستطيع مساعدتك في الأسئلة والمحادثة. | |
| أرسل `/help` لعرض الأوامر المتاحة. | |
| """ | |