Foydalanuvchi commited on
Commit
54844e5
Β·
1 Parent(s): 5425774

Phase 15: Admin Panel added with stats, broadcast and db export

Browse files
Files changed (2) hide show
  1. database.py +30 -0
  2. main.py +87 -6
database.py CHANGED
@@ -88,5 +88,35 @@ class Database:
88
  result = cursor.fetchone()
89
  return result[0] if result else 'retro'
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  # Global DB instance
92
  db = Database()
 
88
  result = cursor.fetchone()
89
  return result[0] if result else 'retro'
90
 
91
+ def get_stats(self):
92
+ """Bot statistikasini qaytaradi (jami userlar va amallar)."""
93
+ with self.get_connection() as conn:
94
+ cursor = conn.cursor()
95
+ cursor.execute('SELECT COUNT(*) FROM users')
96
+ total_users = cursor.fetchone()[0]
97
+
98
+ cursor.execute('SELECT COUNT(*) FROM history')
99
+ total_processed = cursor.fetchone()[0]
100
+
101
+ # Oxirgi 24 soatdagi faollik
102
+ cursor.execute('''
103
+ SELECT COUNT(*) FROM history
104
+ WHERE processed_at > datetime("now", "-1 day")
105
+ ''')
106
+ daily_active = cursor.fetchone()[0]
107
+
108
+ return {
109
+ "total_users": total_users,
110
+ "total_processed": total_processed,
111
+ "daily_active": daily_active
112
+ }
113
+
114
+ def get_all_users(self):
115
+ """Xabar tarqatish uchun barcha user ID-larini qaytaradi."""
116
+ with self.get_connection() as conn:
117
+ cursor = conn.cursor()
118
+ cursor.execute('SELECT user_id FROM users')
119
+ return [row[0] for row in cursor.fetchall()]
120
+
121
  # Global DB instance
122
  db = Database()
main.py CHANGED
@@ -55,11 +55,13 @@ from filters import (
55
  process_video_trim, process_video_face_fix, process_video_auto_enhance,
56
  process_video_fps_boost, apply_nudenet_filter, process_video_nnsfw,
57
  process_video_subtitle,
58
- apply_glitch_filter, apply_mirror_filter, apply_watermark, apply_bg_remove,
59
- apply_style_transfer, apply_quality_boost,
60
- process_video_glitch, process_video_mirror, process_video_watermark,
61
  process_video_subtitle_translate
62
  )
 
 
 
 
 
63
  from database import db
64
  from concurrent.futures import ThreadPoolExecutor
65
  from apscheduler.schedulers.asyncio import AsyncIOScheduler
@@ -266,6 +268,34 @@ async def handle_photo(update: Update, context: ContextTypes.DEFAULT_TYPE):
266
  logger.error(f"Error in handle_photo: {e}")
267
  await update.message.reply_text("❌ Xatolik yuz berdi.")
268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  async def handle_video(update: Update, context: ContextTypes.DEFAULT_TYPE):
270
  """Videolarni qabul qilish."""
271
  try:
@@ -376,11 +406,60 @@ async def navigation_handler(update: Update, context: ContextTypes.DEFAULT_TYPE)
376
  keyboard = [[InlineKeyboardButton("πŸ”™ Orqaga", callback_data="nav|main")]]
377
  await query.edit_message_text(text, reply_markup=InlineKeyboardMarkup(keyboard), parse_mode=constants.ParseMode.MARKDOWN)
378
 
379
- async def button_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
380
- """Filtr tugmalari."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
  query = update.callback_query
382
  await query.answer()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
 
 
384
  try:
385
  data = query.data.split("|")
386
  action, m_type, short_id = data[0], data[1], data[2]
@@ -604,11 +683,13 @@ if __name__ == '__main__':
604
  app = ApplicationBuilder().token(TOKEN).request(request).post_init(post_init).build()
605
 
606
  app.add_handler(CommandHandler("start", start))
 
607
  app.add_handler(CallbackQueryHandler(navigation_handler, pattern=r"^nav\|"))
608
  app.add_handler(CallbackQueryHandler(settings_callback_handler, pattern=r"^set\|"))
609
- app.add_handler(CallbackQueryHandler(button_handler))
610
  app.add_handler(MessageHandler(filters.PHOTO, handle_photo))
611
  app.add_handler(MessageHandler(filters.VIDEO | filters.ANIMATION | filters.Document.ALL, handle_video))
 
612
 
613
  logger.info("Bot polling rejimi ishga tushmoqda...")
614
  app.run_polling()
 
55
  process_video_trim, process_video_face_fix, process_video_auto_enhance,
56
  process_video_fps_boost, apply_nudenet_filter, process_video_nnsfw,
57
  process_video_subtitle,
 
 
 
58
  process_video_subtitle_translate
59
  )
60
+
61
+ # Admin sozlamalari
62
+ ADMIN_ID = int(os.environ.get("ADMIN_ID", 6309900880))
63
+ BROADCAST_MODE = {} # {admin_id: True}
64
+
65
  from database import db
66
  from concurrent.futures import ThreadPoolExecutor
67
  from apscheduler.schedulers.asyncio import AsyncIOScheduler
 
268
  logger.error(f"Error in handle_photo: {e}")
269
  await update.message.reply_text("❌ Xatolik yuz berdi.")
270
 
271
+ async def handle_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
272
+ """Matn xabarlarini qabul qilish."""
273
+ # Agar admin xabar tarqatish rejimida bo'lsa
274
+ if update.effective_user.id == ADMIN_ID and BROADCAST_MODE.get(ADMIN_ID):
275
+ BROADCAST_MODE[ADMIN_ID] = False
276
+ text_to_send = update.message.text
277
+ users = db.get_all_users()
278
+ count = 0
279
+ status_msg = await update.message.reply_text(f"πŸš€ Xabar tarqatish boshlandi (0/{len(users)})...")
280
+
281
+ for u_id in users:
282
+ try:
283
+ await context.bot.send_message(u_id, text_to_send)
284
+ count += 1
285
+ if count % 10 == 0:
286
+ await status_msg.edit_text(f"πŸš€ Xabar tarqatish davom etmoqda ({count}/{len(users)})...")
287
+ except:
288
+ pass
289
+
290
+ await status_msg.edit_text(f"βœ… Xabar tarqatish yakunlandi. {count} ta foydalanuvchiga yuborildi.")
291
+ return
292
+
293
+ # Check for text (if they send prompt for style transfer or other features)
294
+ text = update.message.text
295
+ # Add any other text handling logic here if needed
296
+ await update.message.reply_text("Kechirasiz, men faqat rasm va videolarni qayta ishlay olaman. Iltimos, rasm yoki video yuboring.")
297
+
298
+
299
  async def handle_video(update: Update, context: ContextTypes.DEFAULT_TYPE):
300
  """Videolarni qabul qilish."""
301
  try:
 
406
  keyboard = [[InlineKeyboardButton("πŸ”™ Orqaga", callback_data="nav|main")]]
407
  await query.edit_message_text(text, reply_markup=InlineKeyboardMarkup(keyboard), parse_mode=constants.ParseMode.MARKDOWN)
408
 
409
+ async def admin_panel(update: Update, context: ContextTypes.DEFAULT_TYPE):
410
+ """Faqat admin ko'ra oladigan boshqaruv paneli."""
411
+ if update.effective_user.id != ADMIN_ID:
412
+ return
413
+
414
+ keyboard = [
415
+ [
416
+ InlineKeyboardButton("πŸ“Š Statistika", callback_data="admin_stats"),
417
+ InlineKeyboardButton("πŸ“‚ Bazani yuklab olish", callback_data="admin_db")
418
+ ],
419
+ [
420
+ InlineKeyboardButton("πŸ“’ Xabar tarqatish", callback_data="admin_broadcast")
421
+ ]
422
+ ]
423
+ reply_markup = InlineKeyboardMarkup(keyboard)
424
+ await update.message.reply_text("πŸ‘‘ **Admin Panel**\n\nBotni boshqarish uchun kerakli bo'limni tanlang:",
425
+ reply_markup=reply_markup, parse_mode=constants.ParseMode.MARKDOWN)
426
+
427
+ async def handle_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
428
  query = update.callback_query
429
  await query.answer()
430
+
431
+ if query.data.startswith("admin_"):
432
+ if update.effective_user.id != ADMIN_ID:
433
+ return
434
+
435
+ if query.data == "admin_stats":
436
+ stats = db.get_stats()
437
+ text = (f"πŸ“Š **Bot Statistikasi**\n\n"
438
+ f"πŸ‘₯ Jami foydalanuvchilar: {stats['total_users']}\n"
439
+ f"πŸ”„ Jami tahrirlangan media: {stats['total_processed']}\n"
440
+ f"πŸ“ˆ Oxirgi 24 soatdagi faollik: {stats['daily_active']}")
441
+ await query.edit_message_text(text, parse_mode=constants.ParseMode.MARKDOWN,
442
+ reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("⬅️ Orqaga", callback_data="admin_back")]]))
443
+
444
+ elif query.data == "admin_db":
445
+ await query.message.reply_document(document=open(db.db_path, 'rb'), caption="πŸ“‚ Bot ma'lumotlar bazasi zaxira nusxasi.")
446
+
447
+ elif query.data == "admin_broadcast":
448
+ BROADCAST_MODE[ADMIN_ID] = True
449
+ await query.edit_message_text("πŸ“ **Xabar tarqatish rejimi**\n\nBarcha foydalanuvchilarga yubormoqchi bo'lgan matningizni kiriting:",
450
+ reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("❌ Bekor qilish", callback_data="admin_back")]]))
451
+
452
+ elif query.data == "admin_back":
453
+ BROADCAST_MODE[ADMIN_ID] = False
454
+ keyboard = [
455
+ [InlineKeyboardButton("πŸ“Š Statistika", callback_data="admin_stats"),
456
+ InlineKeyboardButton("πŸ“‚ Bazani yuklab olish", callback_data="admin_db")],
457
+ [InlineKeyboardButton("πŸ“’ Xabar tarqatish", callback_data="admin_broadcast")]
458
+ ]
459
+ await query.edit_message_text("πŸ‘‘ **Admin Panel**", reply_markup=InlineKeyboardMarkup(keyboard), parse_mode=constants.ParseMode.MARKDOWN)
460
+ return
461
 
462
+ # [Avvalgi button_handler mantiqi davom etadi...]
463
  try:
464
  data = query.data.split("|")
465
  action, m_type, short_id = data[0], data[1], data[2]
 
683
  app = ApplicationBuilder().token(TOKEN).request(request).post_init(post_init).build()
684
 
685
  app.add_handler(CommandHandler("start", start))
686
+ app.add_handler(CommandHandler("admin", admin_panel))
687
  app.add_handler(CallbackQueryHandler(navigation_handler, pattern=r"^nav\|"))
688
  app.add_handler(CallbackQueryHandler(settings_callback_handler, pattern=r"^set\|"))
689
+ app.add_handler(CallbackQueryHandler(handle_callback)) # This now handles all callbacks, including admin and regular buttons
690
  app.add_handler(MessageHandler(filters.PHOTO, handle_photo))
691
  app.add_handler(MessageHandler(filters.VIDEO | filters.ANIMATION | filters.Document.ALL, handle_video))
692
+ app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text)) # Handle general text messages
693
 
694
  logger.info("Bot polling rejimi ishga tushmoqda...")
695
  app.run_polling()