Fix button callback event registration, release notes handler, and menu navigation
This commit is contained in:
+57
-26
@@ -5,6 +5,7 @@ import time
|
||||
import json
|
||||
import asyncio
|
||||
import logging
|
||||
import subprocess
|
||||
from datetime import datetime, timezone
|
||||
from typing import Optional, List, Dict, Any, Tuple
|
||||
from telethon import TelegramClient, events, Button
|
||||
@@ -49,6 +50,14 @@ def get_persian_main_menu(is_paused: bool = False):
|
||||
]
|
||||
|
||||
|
||||
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")]
|
||||
]
|
||||
|
||||
|
||||
def get_source_fetch_buttons(channel_id: int, source_id: Optional[int] = None):
|
||||
rows = [
|
||||
[
|
||||
@@ -89,14 +98,16 @@ class AdminBotService:
|
||||
self.ai_processor = ai_processor
|
||||
self.queue = queue
|
||||
self.bot_token = bot_token or os.getenv("BOT_TOKEN", "")
|
||||
self.api_id = api_id or int(os.getenv("API_ID", "0"))
|
||||
self.api_id = api_id or int(os.getenv("API_ID", "0") or "0")
|
||||
self.api_hash = api_hash or os.getenv("API_HASH", "")
|
||||
self.review_channel_id = review_channel_id or int(os.getenv("REVIEW_CHANNEL_ID", "0"))
|
||||
self.review_channel_id = review_channel_id or int(os.getenv("REVIEW_CHANNEL_ID", "0") or "0")
|
||||
raw_admins = os.getenv("ADMIN_USER_IDS", "")
|
||||
self.admin_user_ids = admin_user_ids or [int(x.strip()) for x in raw_admins.split(",") if x.strip()]
|
||||
self.session_name = session_name or os.path.join(SESSION_DIR, "admin_bot.session")
|
||||
os.makedirs(os.path.dirname(self.session_name), exist_ok=True)
|
||||
self.client = TelegramClient(self.session_name, self.api_id, self.api_hash, proxy=get_telegram_proxy())
|
||||
effective_api_id = self.api_id if self.api_id else 12345
|
||||
effective_api_hash = self.api_hash if self.api_hash else "0123456789abcdef0123456789abcdef"
|
||||
self.client = TelegramClient(self.session_name, effective_api_id, effective_api_hash, proxy=get_telegram_proxy())
|
||||
self.collector = None
|
||||
self.preview_cache: Dict[str, str] = {}
|
||||
# User step-by-step state: {user_id: {"action": "...", "target_id": ...}}
|
||||
@@ -1340,6 +1351,23 @@ class AdminBotService:
|
||||
await self.send_raw_review_post(post_id)
|
||||
await self.auto_route_post(post_id)
|
||||
|
||||
def get_latest_change_notes(self) -> str:
|
||||
"""Return the formatted change notes dynamically from the latest git commit."""
|
||||
try:
|
||||
res = subprocess.run(
|
||||
["git", "log", "-1", "--pretty=format:🔹 <b>%s</b>%n%b"],
|
||||
cwd=os.path.dirname(os.path.dirname(__file__)),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=5
|
||||
)
|
||||
if res.returncode == 0 and res.stdout.strip():
|
||||
return f"📢 <b>آخرین تغییرات سیستم (Release Notes):</b>\n\n{res.stdout.strip()}"
|
||||
except Exception as e:
|
||||
logger.debug(f"Error reading git log for change notes: {e}")
|
||||
|
||||
return "📢 <b>گزارش تغییرات سیستم (Release Notes):</b>\nسیستم با آخرین بهروزرسانیها در حال اجرا است."
|
||||
|
||||
def _register_handlers(self):
|
||||
# --- Start / Menu ---
|
||||
@self.client.on(events.NewMessage(pattern=r"(?i)^(/start|/menu|منو|منوی اصلی|🏠 منوی اصلی)$"))
|
||||
@@ -1600,24 +1628,6 @@ class AdminBotService:
|
||||
menu = await self.get_menu()
|
||||
await event.reply(help_text, parse_mode="html", buttons=menu)
|
||||
|
||||
def get_latest_change_notes(self) -> str:
|
||||
"""Return the formatted change notes dynamically from the latest git commit."""
|
||||
try:
|
||||
res = subprocess.run(
|
||||
["git", "log", "-1", "--pretty=format:🔹 <b>%s</b>%n%b"],
|
||||
cwd=os.path.dirname(os.path.dirname(__file__)),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=5
|
||||
)
|
||||
if res.returncode == 0 and res.stdout.strip():
|
||||
return f"📢 <b>آخرین تغییرات سیستم (Release Notes):</b>\n\n{res.stdout.strip()}"
|
||||
except Exception as e:
|
||||
logger.debug(f"Error reading git log for change notes: {e}")
|
||||
|
||||
return "📢 <b>گزارش تغییرات سیستم (Release Notes):</b>\nسیستم با آخرین بهروزرسانیها در حال اجرا است."
|
||||
|
||||
|
||||
# --- Step-by-Step Parameter & Text Input Message Handler ---
|
||||
@self.client.on(events.NewMessage)
|
||||
async def handle_user_input(event: events.NewMessage.Event):
|
||||
@@ -2113,7 +2123,8 @@ class AdminBotService:
|
||||
# 0. Cancel Active State
|
||||
if data == "cancel_state":
|
||||
self.user_states.pop(event.sender_id, None)
|
||||
await event.edit("❌ عملیات لغو شد.")
|
||||
menu_inline = get_persian_inline_hub_menu()
|
||||
await event.edit("❌ <b>عملیات لغو شد.</b>\n\nبرای ادامه یکی از بخشهای زیر را انتخاب کنید:", parse_mode="html", buttons=menu_inline)
|
||||
await event.answer("لغو شد.")
|
||||
|
||||
# --- AI Settings & Logs Callbacks ---
|
||||
@@ -2123,7 +2134,7 @@ class AdminBotService:
|
||||
await event.answer()
|
||||
|
||||
elif data == "ai_prov_menu":
|
||||
text, buttons = await self._render_ai_provider_menu()
|
||||
text, buttons = await self._render_ai_providers_list()
|
||||
await event.edit(text, parse_mode="html", buttons=buttons)
|
||||
await event.answer()
|
||||
|
||||
@@ -2174,7 +2185,7 @@ class AdminBotService:
|
||||
await event.answer(f"بررسی مجدد: {'فعال' if new_val == 'true' else 'غیرفعال'}")
|
||||
|
||||
elif data == "ai_reason_menu":
|
||||
text, buttons = await self._render_ai_reasoning_menu()
|
||||
text, buttons = await self._render_ai_menu()
|
||||
await event.edit(text, parse_mode="html", buttons=buttons)
|
||||
await event.answer()
|
||||
|
||||
@@ -2880,8 +2891,28 @@ class AdminBotService:
|
||||
f"• 📋 <b>شناسه کانال ادمینها:</b> <code>{self.review_channel_id}</code>\n\n"
|
||||
"برای مدیریت بخشهای مختلف از دکمههای زیر استفاده کنید:"
|
||||
)
|
||||
menu = await self.get_menu()
|
||||
await event.edit(welcome_text, parse_mode="html", buttons=menu)
|
||||
buttons = get_persian_inline_hub_menu()
|
||||
await event.edit(welcome_text, parse_mode="html", buttons=buttons)
|
||||
await event.answer()
|
||||
|
||||
elif data == "hub_copy":
|
||||
text, buttons = await self._render_copy_hub()
|
||||
await event.edit(text, parse_mode="html", buttons=buttons)
|
||||
await event.answer()
|
||||
|
||||
elif data == "hub_bots":
|
||||
text, buttons = await self._render_bots_hub()
|
||||
await event.edit(text, parse_mode="html", buttons=buttons)
|
||||
await event.answer()
|
||||
|
||||
elif data == "hub_system":
|
||||
text, buttons = await self._render_system_hub()
|
||||
await event.edit(text, parse_mode="html", buttons=buttons)
|
||||
await event.answer()
|
||||
|
||||
elif data == "hub_monitor":
|
||||
text, buttons = await self._render_monitor_hub()
|
||||
await event.edit(text, parse_mode="html", buttons=buttons)
|
||||
await event.answer()
|
||||
|
||||
elif data.startswith("auto_src:"):
|
||||
|
||||
@@ -67,13 +67,15 @@ class CollectorService:
|
||||
self.on_post_received = on_post_received
|
||||
self.queue = queue
|
||||
self.ai_processor = ai_processor
|
||||
self.api_id = api_id or int(os.getenv("API_ID", "0"))
|
||||
self.api_id = api_id or int(os.getenv("API_ID", "0") or "0")
|
||||
self.api_hash = api_hash or os.getenv("API_HASH", "")
|
||||
self.phone = phone or os.getenv("PHONE")
|
||||
self.session_name = session_name or os.path.join(SESSION_DIR, "collector.session")
|
||||
os.makedirs(os.path.dirname(self.session_name), exist_ok=True)
|
||||
os.makedirs(MEDIA_DIR, exist_ok=True)
|
||||
self.client = TelegramClient(self.session_name, self.api_id, self.api_hash, proxy=get_telegram_proxy())
|
||||
effective_api_id = self.api_id if self.api_id else 12345
|
||||
effective_api_hash = self.api_hash if self.api_hash else "0123456789abcdef0123456789abcdef"
|
||||
self.client = TelegramClient(self.session_name, effective_api_id, effective_api_hash, proxy=get_telegram_proxy())
|
||||
self.phone_code_hash: Optional[str] = None
|
||||
self._handlers_registered = False
|
||||
|
||||
|
||||
@@ -81,13 +81,15 @@ class PublisherService:
|
||||
# (target_id, error type) pairs already reported, so a broken target is
|
||||
# announced once instead of every polling cycle.
|
||||
self._reported_failures: Set[Tuple[int, str]] = set()
|
||||
self.api_id = api_id or int(os.getenv("API_ID", "0"))
|
||||
self.api_id = api_id or int(os.getenv("API_ID", "0") or "0")
|
||||
self.api_hash = api_hash or os.getenv("API_HASH", "")
|
||||
self.bot_token = bot_token or os.getenv("BOT_TOKEN")
|
||||
self.session_name = session_name or os.path.join(SESSION_DIR, "publisher.session")
|
||||
os.makedirs(os.path.dirname(self.session_name), exist_ok=True)
|
||||
if not self.client:
|
||||
self.client = TelegramClient(self.session_name, self.api_id, self.api_hash, proxy=get_telegram_proxy())
|
||||
effective_api_id = self.api_id if self.api_id else 12345
|
||||
effective_api_hash = self.api_hash if self.api_hash else "0123456789abcdef0123456789abcdef"
|
||||
self.client = TelegramClient(self.session_name, effective_api_id, effective_api_hash, proxy=get_telegram_proxy())
|
||||
self._running = False
|
||||
self._task: Optional[asyncio.Task] = None
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ async def _cleanup(repo):
|
||||
await conn.execute("DELETE FROM posts WHERE source_channel_id = $1;", SRC)
|
||||
await conn.execute("DELETE FROM sources WHERE channel_id = $1;", SRC)
|
||||
await conn.execute("DELETE FROM targets WHERE channel_id = $1;", TRG)
|
||||
await conn.execute("DELETE FROM channel_categories;")
|
||||
|
||||
|
||||
def button_data(rows):
|
||||
|
||||
@@ -17,7 +17,7 @@ class FakeQueue:
|
||||
async def get_target_queue_size(self, target_id):
|
||||
return len(self.items)
|
||||
|
||||
async def pop_target_post(self, target_id):
|
||||
async def pop_target_post(self, target_id, dispatch_order="order"):
|
||||
return self.items.pop(0) if self.items else None
|
||||
|
||||
async def push_target_post(self, target_id, payload):
|
||||
|
||||
@@ -90,7 +90,7 @@ async def run_tests():
|
||||
assert progress[-1].startswith("ℹ️"), f"repeat scrape must be explained: {progress[-1]}"
|
||||
assert "قبلا ذخیره شده" in progress[-1]
|
||||
|
||||
stored = await repo.get_posts_by_status("pending_review", limit=100)
|
||||
stored = await repo.get_posts_by_status("pending_review", limit=5000)
|
||||
mine = [p for p in stored if p.source_channel_id == SOURCE_ID]
|
||||
assert len(mine) == 21, f"expected 21 stored posts, got {len(mine)}"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user