diff --git a/services/admin_bot.py b/services/admin_bot.py
index 8a3f44e..8475f83 100644
--- a/services/admin_bot.py
+++ b/services/admin_bot.py
@@ -45,17 +45,17 @@ def clamp_for_telegram(text: str, has_media: bool) -> str:
def get_persian_main_menu(is_paused: bool = False):
return [
- [Button.text("📋 Copy (محتوا)", resize=True), Button.text("🧠 AI (هوش مصنوعی)", resize=True)],
- [Button.text("🤖 Bots (کانالها و رباتها)", resize=True), Button.text("📊 Monitor (مانیتورینگ)", resize=True)],
- [Button.text("⚙️ System (سیستم)", resize=True), Button.text("🏠 منوی اصلی", resize=True)]
+ [Button.text("📋 مدیریت محتوا (Copy)", resize=True), Button.text("🧠 هوش مصنوعی (AI)", resize=True)],
+ [Button.text("🤖 کانالها و وب (Bots)", resize=True), Button.text("📊 مانیتورینگ (Monitor)", resize=True)],
+ [Button.text("⚙️ مدیریت سیستم (System)", resize=True)]
]
def get_persian_inline_hub_menu():
return [
- [Button.inline("📋 Copy (محتوا)", data="hub_copy"), Button.inline("🧠 AI (هوش مصنوعی)", data="ai_menu")],
- [Button.inline("🤖 Bots (کانالها و وب)", data="hub_bots"), Button.inline("📊 Monitor (مانیتورینگ)", data="hub_monitor")],
- [Button.inline("⚙️ System (سیستم)", data="hub_system")]
+ [Button.inline("📋 مدیریت محتوا (Copy)", data="hub_copy"), Button.inline("🧠 هوش مصنوعی (AI)", data="ai_menu")],
+ [Button.inline("🤖 کانالها و وب (Bots)", data="hub_bots"), Button.inline("📊 مانیتورینگ (Monitor)", data="hub_monitor")],
+ [Button.inline("⚙️ مدیریت سیستم (System)", data="hub_system")]
]
@@ -1071,17 +1071,47 @@ class AdminBotService:
return text, buttons
+ async def _render_queues_status(self) -> Tuple[str, List[List[Button]]]:
+ targets = await self.repo.get_active_targets()
+ total_queued = await self.queue.get_total_queued_posts() if self.queue else 0
+ lines = [
+ "📬 وضعیت صفهای انتشار کانالهای مقصد:\n",
+ f"• 📦 مجموع کل پستها در تمام صفها: {total_queued} پست\n"
+ ]
+ buttons = []
+ if targets:
+ for t in targets:
+ qsize = await self.queue.get_target_queue_size(t.id) if self.queue else 0
+ order_m = "ترتیبی" if getattr(t, "dispatch_order", "order") == "order" else "تصادفی"
+ lines.append(f"• 🎯 {t.title}: {qsize} پست در صف ({order_m})")
+ buttons.append([Button.inline(f"🎯 {t.title} ({qsize} پست)", data=f"trg_view:{t.id}")])
+ else:
+ lines.append("هیچ کانال مقصدی ثبت نشده است.")
+
+ buttons.append([
+ Button.inline("🔄 بروزرسانی وضعیت صفها", data="hub_queues"),
+ Button.inline("🔙 بازگشت به منوی محتوا", data="hub_copy")
+ ])
+ return "\n".join(lines), buttons
+
async def _render_copy_hub(self) -> Tuple[str, List[List[Button]]]:
unreviewed = await self.repo.get_unreviewed_posts(limit=50)
+ total_queued = await self.queue.get_total_queued_posts() if self.queue else 0
text = (
- "📋 بخش کپی و محتوا (Copy Hub):\n\n"
- f"• 📨 پستهای منتظر بررسی: {len(unreviewed)} پست\n\n"
+ "📋 بخش مدیریت محتوا و صفها (Copy Hub):\n\n"
+ f"• 📨 پستهای منتظر بررسی: {len(unreviewed)} پست\n"
+ f"• 📬 پستهای در صف انتشار: {total_queued} پست\n\n"
"از گزینههای زیر برای مدیریت جریان محتوا و انتشار استفاده کنید:"
)
buttons = [
- [Button.inline(f"📨 ارسال پستهای بررسینشده ({len(unreviewed)})", data="hub_pending")],
- [Button.inline("➕ افزودن مبدا / مقصد جدید", data="hub_add")],
- [Button.inline("📂 دستهبندی موضوعی کانالها", data="hub_cats")],
+ [
+ Button.inline(f"📨 ارسال پستهای بررسینشده ({len(unreviewed)})", data="hub_pending"),
+ Button.inline(f"📬 وضعیت صفهای انتشار ({total_queued})", data="hub_queues")
+ ],
+ [
+ Button.inline("➕ افزودن مبدا / مقصد جدید", data="hub_add"),
+ Button.inline("📂 دستهبندی موضوعی کانالها", data="hub_cats")
+ ],
[Button.inline("🔙 بازگشت به منوی اصلی", data="back_to_main")]
]
return text, buttons
@@ -1091,7 +1121,7 @@ class AdminBotService:
targets = await self.repo.get_active_targets()
websites = await self.repo.get_active_source_websites()
text = (
- f"🤖 بخش کانالها و رباتها (Bots Hub):\n\n"
+ f"🤖 بخش کانالها، وبسایتها و رباتها (Bots Hub):\n\n"
f"• 📡 کانالهای مبدا: {len(sources)} کانال\n"
f"• 🎯 کانالهای مقصد: {len(targets)} کانال\n"
f"• 🌐 وبسایتهای مبدا: {len(websites)} وبسایت\n\n"
@@ -1104,7 +1134,11 @@ class AdminBotService:
],
[
Button.inline(f"🌐 وبسایتهای مبدا ({len(websites)})", data="list_web"),
- Button.inline("🔑 کد لاگین یوزربات", data="hub_req_code")
+ Button.inline("🔑 احراز هویت یوزربات", data="hub_req_code")
+ ],
+ [
+ Button.inline("➕ افزودن منبع / کانال جدید", data="hub_add"),
+ Button.inline("📂 مدیریت دستهبندیها", data="list_cat")
],
[Button.inline("🔙 بازگشت به منوی اصلی", data="back_to_main")]
]
@@ -1398,35 +1432,35 @@ class AdminBotService:
await event.reply(welcome_text, parse_mode="html", buttons=menu)
# --- 5 Primary Category Hubs: Copy, AI, Bots, System, Monitor ---
- @self.client.on(events.NewMessage(pattern=r"(?i)^(/copy|📋 copy \(محتوا\)|📋 copy|copy)$"))
+ @self.client.on(events.NewMessage(pattern=r"(?i)^(/copy|📋 مدیریت محتوا \(copy\)|📋 copy \(محتوا\)|📋 مدیریت محتوا|📋 copy|copy)$"))
async def cmd_copy_hub(event: events.NewMessage.Event):
if not self.is_admin(event.sender_id):
return
text, buttons = await self._render_copy_hub()
await event.reply(text, parse_mode="html", buttons=buttons)
- @self.client.on(events.NewMessage(pattern=r"(?i)^(/ai|🧠 ai \(هوش مصنوعی\)|🧠 ai|ai)$"))
+ @self.client.on(events.NewMessage(pattern=r"(?i)^(/ai|🧠 هوش مصنوعی \(ai\)|🧠 ai \(هوش مصنوعی\)|🧠 هوش مصنوعی|🧠 ai|ai)$"))
async def cmd_ai_hub(event: events.NewMessage.Event):
if not self.is_admin(event.sender_id):
return
text, buttons = await self._render_ai_menu()
await event.reply(text, parse_mode="html", buttons=buttons)
- @self.client.on(events.NewMessage(pattern=r"(?i)^(/bots|🤖 bots \(کانالها و رباتها\)|🤖 bots|bots)$"))
+ @self.client.on(events.NewMessage(pattern=r"(?i)^(/bots|🤖 کانالها و وب \(bots\)|🤖 bots \(کانالها و رباتها\)|🤖 کانالها و وب|🤖 bots|bots)$"))
async def cmd_bots_hub(event: events.NewMessage.Event):
if not self.is_admin(event.sender_id):
return
text, buttons = await self._render_bots_hub()
await event.reply(text, parse_mode="html", buttons=buttons)
- @self.client.on(events.NewMessage(pattern=r"(?i)^(/system|⚙️ system \(سیستم\)|⚙️ system|system)$"))
+ @self.client.on(events.NewMessage(pattern=r"(?i)^(/system|⚙️ مدیریت سیستم \(system\)|⚙️ system \(سیستم\)|⚙️ مدیریت سیستم|⚙️ system|system)$"))
async def cmd_system_hub(event: events.NewMessage.Event):
if not self.is_admin(event.sender_id):
return
text, buttons = await self._render_system_hub()
await event.reply(text, parse_mode="html", buttons=buttons)
- @self.client.on(events.NewMessage(pattern=r"(?i)^(/monitor|📊 monitor \(مانیتورینگ\)|📊 monitor|monitor)$"))
+ @self.client.on(events.NewMessage(pattern=r"(?i)^(/monitor|📊 مانیتورینگ \(monitor\)|📊 monitor \(مانیتورینگ\)|📊 مانیتورینگ|📊 monitor|monitor)$"))
async def cmd_monitor_hub(event: events.NewMessage.Event):
if not self.is_admin(event.sender_id):
return
@@ -1684,11 +1718,11 @@ class AdminBotService:
# Ignore main menu commands
if text in ["/start", "/menu", "منو", "منوی اصلی", "🏠 منوی اصلی",
- "/copy", "📋 copy (محتوا)", "📋 Copy (محتوا)", "📋 کپی", "Copy",
- "/ai", "🧠 ai (هوش مصنوعی)", "🧠 AI (هوش مصنوعی)", "🧠 تنظیمات AI", "🧠 تنظیمات و لاگهای AI", "AI",
- "/bots", "🤖 bots (کانالها و رباتها)", "🤖 Bots (کانالها و رباتها)", "🤖 کانالها و رباتها", "Bots",
- "/system", "⚙️ system (سیستم)", "⚙️ System (سیستم)", "⚙️ مدیریت سیستم", "System",
- "/monitor", "📊 monitor (مانیتورینگ)", "📊 Monitor (مانیتورینگ)", "📊 مانیتورینگ", "Monitor",
+ "/copy", "📋 مدیریت محتوا (Copy)", "📋 مدیریت محتوا", "📋 copy (محتوا)", "📋 Copy (محتوا)", "📋 کپی", "Copy",
+ "/ai", "🧠 هوش مصنوعی (AI)", "🧠 هوش مصنوعی", "🧠 ai (هوش مصنوعی)", "🧠 AI (هوش مصنوعی)", "🧠 تنظیمات AI", "🧠 تنظیمات و لاگهای AI", "AI",
+ "/bots", "🤖 کانالها و وب (Bots)", "🤖 کانالها و وب", "🤖 bots (کانالها و رباتها)", "🤖 Bots (کانالها و رباتها)", "🤖 کانالها و رباتها", "Bots",
+ "/system", "⚙️ مدیریت سیستم (System)", "⚙️ مدیریت سیستم", "⚙️ system (سیستم)", "⚙️ System (سیستم)", "System",
+ "/monitor", "📊 مانیتورینگ (Monitor)", "📊 مانیتورینگ", "📊 monitor (مانیتورینگ)", "📊 Monitor (مانیتورینگ)", "Monitor",
"/stats", "/report", "📊 آمار ناوگان", "📊 آمار و وضعیت ناوگان", "📊 گزارش و آمار سیستم",
"/sources", "📡 کانالهای مبدا", "/targets", "🎯 کانالهای مقصد",
"/websites", "/sites", "🌐 وبسایتهای مبدا",
@@ -2833,6 +2867,11 @@ class AdminBotService:
except Exception:
pass
+ elif data == "hub_queues":
+ text, buttons = await self._render_queues_status()
+ await event.edit(text, parse_mode="html", buttons=buttons)
+ await event.answer()
+
elif data == "hub_cats":
text, buttons = await self._render_categories_menu()
await event.edit(text, parse_mode="html", buttons=buttons or None)