pmrony commited on
Commit
78c0d08
·
verified ·
1 Parent(s): b4bfbc0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +148 -66
app.py CHANGED
@@ -57,7 +57,6 @@ ffmpeg_available = True
57
  # ================= AUTO SHARE VARIABLES =================
58
  auto_share_running = False
59
  auto_share_task = None
60
- TARGET_SHARE_GROUP = -1004333630822
61
  # =========================================================
62
 
63
  try:
@@ -363,8 +362,8 @@ async def save_progress(source_id, dest_id, msg_id):
363
  except Exception as e: print(f"Error saving progress: {e}")
364
 
365
 
366
- # ================= FIXED AUTO SHARE LOGIC =================
367
- async def auto_share_loop(client, target_chat_id, delay=300):
368
  global auto_share_running
369
 
370
  try:
@@ -379,7 +378,6 @@ async def auto_share_loop(client, target_chat_id, delay=300):
379
  f"👉 <b><a href='{bot_link}'>▶️ Click Here to Watch</a></b>\n\n"
380
  f"🎁 <b>App এর ভেতর 'Secret Box' ওপেন করে Premium Channel Claim করুন!</b> 👇"
381
  )
382
- # ২টা বাটন: একটা ভিডিও দেখার, অন্যটা সিক্রেট বক্সের
383
  group_markup = InlineKeyboardMarkup([
384
  [InlineKeyboardButton("🎬 Watch Full Video Here 🔞", url=bot_link)],
385
  [InlineKeyboardButton("🎁 Open Secret Box", url=f"{bot_link}?start=secretbox")]
@@ -387,18 +385,37 @@ async def auto_share_loop(client, target_chat_id, delay=300):
387
 
388
  while auto_share_running:
389
  try:
390
- progress_res = await db_query(lambda: supabase.table('clone_progress').select('last_copied_id').eq('source_id', STORAGE_CHANNEL_ID).eq('dest_id', target_chat_id).execute())
391
- last_checked_id = 0
392
- if progress_res.data:
393
- last_checked_id = progress_res.data[0]['last_copied_id']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
394
 
395
  batch_to_send = []
396
  current_id = last_checked_id + 1
397
- search_limit = 50
398
  highest_valid_id = last_checked_id
399
 
400
- chunk_ids = list(range(current_id, current_id + search_limit))
401
-
402
  try:
403
  msgs = await client.get_messages(STORAGE_CHANNEL_ID, chunk_ids)
404
  valid_messages_found = False
@@ -408,7 +425,6 @@ async def auto_share_loop(client, target_chat_id, delay=300):
408
  if msg and not getattr(msg, "empty", False):
409
  valid_messages_found = True
410
  highest_valid_id = msg.id
411
-
412
  if msg.video or (msg.document and msg.document.mime_type and "video" in msg.document.mime_type) or msg.photo:
413
  batch_to_send.append(msg)
414
  if len(batch_to_send) == 5:
@@ -417,51 +433,52 @@ async def auto_share_loop(client, target_chat_id, delay=300):
417
  await asyncio.sleep(e.value + 1)
418
  continue
419
  except Exception as e:
420
- print(f"Fetch error in auto share: {e}")
421
  await asyncio.sleep(5)
422
  continue
423
 
424
  if not batch_to_send:
425
  if valid_messages_found and highest_valid_id > last_checked_id:
426
- await save_progress(STORAGE_CHANNEL_ID, target_chat_id, highest_valid_id)
427
  await asyncio.sleep(30)
428
  continue
429
 
430
- last_sent_id = highest_valid_id
431
- sent_message_ids = []
432
 
433
  for msg in batch_to_send:
434
  if not auto_share_running: break
435
- try:
436
- sent = await msg.copy(
437
- target_chat_id,
438
- caption=caption_text,
439
- reply_markup=group_markup
440
- )
441
- sent_message_ids.append(sent.id)
442
- last_sent_id = msg.id
443
- await asyncio.sleep(1.5)
444
- except FloodWait as e:
445
- await asyncio.sleep(e.value + 1)
446
- except Exception as e:
447
- print(f"Error copying msg {msg.id}: {e}")
448
-
449
- if last_sent_id > last_checked_id:
450
- await save_progress(STORAGE_CHANNEL_ID, target_chat_id, last_sent_id)
451
 
 
452
  for _ in range(delay):
453
  if not auto_share_running: break
454
  await asyncio.sleep(1)
455
 
456
- if sent_message_ids and auto_share_running:
457
- try:
458
- await client.delete_messages(target_chat_id, sent_message_ids)
459
- except FloodWait as e:
460
- await asyncio.sleep(e.value + 1)
461
- await client.delete_messages(target_chat_id, sent_message_ids)
462
- except Exception as e:
463
- print(f"Error deleting msgs: {e}")
464
-
 
 
 
465
  except Exception as e:
466
  print(f"Auto-share loop error: {e}")
467
  await asyncio.sleep(5)
@@ -472,15 +489,15 @@ async def start_sharing_cmd(client, message):
472
  args = message.command
473
 
474
  if len(args) > 1 and args[1].lower() == "reset":
475
- await save_progress(STORAGE_CHANNEL_ID, TARGET_SHARE_GROUP, 0)
476
  await message.reply("🔄 <b>Progress reset!</b> The bot will now start sharing from the 1st video.")
477
 
478
  if auto_share_running:
479
  return await message.reply("⚠️ <b>Auto-share is already running!</b>\nUse `/stopshare` to stop it first.")
480
 
481
  auto_share_running = True
482
- auto_share_task = asyncio.create_task(auto_share_loop(client, TARGET_SHARE_GROUP, 300))
483
- await message.reply(f"✅ <b>Auto-sharing started!</b>\n\n📌 <b>Target Group:</b> <code>{TARGET_SHARE_GROUP}</code>\n📦 <b>Batch Size:</b> 5 videos\n⏱ <b>Interval:</b> 5 minutes\n\n<i>Bot will send 5 videos with new caption & Secret Box button!</i>", parse_mode=enums.ParseMode.HTML)
484
 
485
  @bot.on_message(filters.command("stopshare") & filters.private & filters.user(ADMIN_IDS))
486
  async def stop_sharing_cmd(client, message):
@@ -505,6 +522,7 @@ async def help_command(client, message):
505
  help_text += "👉 `/stats` - Check total users, videos, and groups.\n"
506
  help_text += "👉 `/broadcast` - Send a message to all bot users.\n"
507
  help_text += "👉 `/clone <source_id> <dest_id>` - Clone videos from one group to another.\n"
 
508
  help_text += "👉 `/sendto <group_id>` - Reply to a media to forward it directly to a specific group.\n"
509
  help_text += "👉 `/upload <telegram/byse>` - Change video upload server (Local or byse.sx).\n"
510
  help_text += "👉 `/blur <percentage>` - Enable video/photo blur (e.g., `/blur 60`). Send `/blur 0` to disable.\n"
@@ -606,27 +624,6 @@ async def bot_added_to_group(client, message):
606
  try: await client.send_message(chat_id=admin_id, text=admin_msg, parse_mode=enums.ParseMode.HTML)
607
  except: pass
608
 
609
- progress_res = await db_query(lambda: supabase.table('clone_progress').select('source_id', 'last_copied_id').eq('dest_id', 0).execute())
610
-
611
- if progress_res.data:
612
- last_record = progress_res.data[0]
613
- src_chat = last_record['source_id']
614
- msg_id = last_record['last_copied_id']
615
-
616
- bot_link = f"https://t.me/{me.username}"
617
- caption_text = (
618
- f"🔥 <b>New Premium Viral Video Leaked!</b> 🔞\n\n"
619
- f"🎬 <b>Watch HD Video Here:</b>\n"
620
- f"👉 <b><a href='{bot_link}'>▶️ Click Here to Watch</a></b>\n\n"
621
- f"🎁 <b>App এর ভেতর 'Secret Box' ওপেন করে Premium Channel Claim করুন!</b> 👇"
622
- )
623
- group_markup = InlineKeyboardMarkup([
624
- [InlineKeyboardButton("🎬 Watch Full Video Here 🔞", url=bot_link)],
625
- [InlineKeyboardButton("🎁 Open Secret Box", url=f"{bot_link}?start=secretbox")]
626
- ])
627
-
628
- await asyncio.sleep(2)
629
- await client.copy_message(message.chat.id, src_chat, msg_id, caption=caption_text, reply_markup=group_markup)
630
  except Exception as e:
631
  print(f"Error handling new group logic: {e}")
632
 
@@ -734,6 +731,91 @@ async def start_cloning(client, message):
734
  status_msg = await message.reply("⏳ Initializing cloning task...", parse_mode=enums.ParseMode.HTML)
735
  asyncio.create_task(clone_videos_background(client, source_id, dest_id, status_msg))
736
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
737
  @bot.on_message(filters.command("upload") & filters.private & filters.user(ADMIN_IDS))
738
  async def set_upload_mode(client, message):
739
  global upload_mode
@@ -1251,7 +1333,7 @@ async def auto_clean_channel_loop():
1251
  print(f"Auto clean error: {e}")
1252
  await asyncio.sleep(4 * 3600)
1253
 
1254
- @bot.on_message(filters.private & filters.user(ADMIN_IDS) & ~filters.command(["start", "stats", "users", "broadcast", "png", "addvideo", "blur", "clean", "sendto", "clone", "upload", "startshare", "stopshare", "help"]))
1255
  async def catch_admin_steps(client, message):
1256
  state = admin_states.get(message.chat.id, {})
1257
  if state.get("step") == 1:
 
57
  # ================= AUTO SHARE VARIABLES =================
58
  auto_share_running = False
59
  auto_share_task = None
 
60
  # =========================================================
61
 
62
  try:
 
362
  except Exception as e: print(f"Error saving progress: {e}")
363
 
364
 
365
+ # ================= SMART AUTO SHARE LOGIC =================
366
+ async def auto_share_loop(client, delay=300):
367
  global auto_share_running
368
 
369
  try:
 
378
  f"👉 <b><a href='{bot_link}'>▶️ Click Here to Watch</a></b>\n\n"
379
  f"🎁 <b>App এর ভেতর 'Secret Box' ওপেন করে Premium Channel Claim করুন!</b> 👇"
380
  )
 
381
  group_markup = InlineKeyboardMarkup([
382
  [InlineKeyboardButton("🎬 Watch Full Video Here 🔞", url=bot_link)],
383
  [InlineKeyboardButton("🎁 Open Secret Box", url=f"{bot_link}?start=secretbox")]
 
385
 
386
  while auto_share_running:
387
  try:
388
+ # ১. ডাটাবেজ থেকে সব গ্রুপ আনা এবং অ্যাডমিন পারমিশন চেক করা
389
+ groups_res = await db_query(lambda: supabase.table('groups').select('group_id').execute())
390
+ eligible_groups = []
391
+
392
+ if groups_res.data:
393
+ for g in groups_res.data:
394
+ gid = g['group_id']
395
+ try:
396
+ member = await client.get_chat_member(gid, "me")
397
+ # চেক করবে বট অ্যাডমিন কিনা এবং মেসেজ ডিলিট করার পারমিশন আছে কিনা
398
+ if member.status in [enums.ChatMemberStatus.ADMINISTRATOR, enums.ChatMemberStatus.OWNER]:
399
+ if member.privileges and member.privileges.can_delete_messages:
400
+ eligible_groups.append(gid)
401
+ except FloodWait as e:
402
+ await asyncio.sleep(e.value + 1)
403
+ except Exception:
404
+ pass # বট গ্রুপে না থাকলে বা ব্যান খেলে স্কিপ করবে
405
+
406
+ if not eligible_groups:
407
+ await asyncio.sleep(60) # কোনো এলিজিবল গ্রুপ না পেলে ১ মিনিট ওয়েট করবে
408
+ continue
409
+
410
+ # ২. স্টোরেজ থেকে ৫টি ভিডিও নেওয়া (dest_id = -1 ব্যবহার করা হচ্ছে গ্লোবাল ট্র্যাকিং এর জন্য)
411
+ progress_res = await db_query(lambda: supabase.table('clone_progress').select('last_copied_id').eq('source_id', STORAGE_CHANNEL_ID).eq('dest_id', -1).execute())
412
+ last_checked_id = progress_res.data[0]['last_copied_id'] if progress_res.data else 0
413
 
414
  batch_to_send = []
415
  current_id = last_checked_id + 1
 
416
  highest_valid_id = last_checked_id
417
 
418
+ chunk_ids = list(range(current_id, current_id + 50))
 
419
  try:
420
  msgs = await client.get_messages(STORAGE_CHANNEL_ID, chunk_ids)
421
  valid_messages_found = False
 
425
  if msg and not getattr(msg, "empty", False):
426
  valid_messages_found = True
427
  highest_valid_id = msg.id
 
428
  if msg.video or (msg.document and msg.document.mime_type and "video" in msg.document.mime_type) or msg.photo:
429
  batch_to_send.append(msg)
430
  if len(batch_to_send) == 5:
 
433
  await asyncio.sleep(e.value + 1)
434
  continue
435
  except Exception as e:
 
436
  await asyncio.sleep(5)
437
  continue
438
 
439
  if not batch_to_send:
440
  if valid_messages_found and highest_valid_id > last_checked_id:
441
+ await save_progress(STORAGE_CHANNEL_ID, -1, highest_valid_id)
442
  await asyncio.sleep(30)
443
  continue
444
 
445
+ # ৩. এলিজিবল গ্রুপগুলোতে ৫টি ভিডিও সেন্ড করা
446
+ sent_message_ids = {} # { group_id: [msg_id1, msg_id2...] }
447
 
448
  for msg in batch_to_send:
449
  if not auto_share_running: break
450
+ for gid in eligible_groups:
451
+ try:
452
+ sent = await msg.copy(gid, caption=caption_text, reply_markup=group_markup)
453
+ if gid not in sent_message_ids:
454
+ sent_message_ids[gid] = []
455
+ sent_message_ids[gid].append(sent.id)
456
+ await asyncio.sleep(1) # ফ্লাডওয়েট এড়াতে স্লিপ
457
+ except FloodWait as e:
458
+ await asyncio.sleep(e.value + 1)
459
+ except Exception:
460
+ pass
461
+
462
+ if highest_valid_id > last_checked_id:
463
+ await save_progress(STORAGE_CHANNEL_ID, -1, highest_valid_id)
 
 
464
 
465
+ # ৪. ৫ মিনিট অপেক্ষা করা
466
  for _ in range(delay):
467
  if not auto_share_running: break
468
  await asyncio.sleep(1)
469
 
470
+ # ৫. সব গ্রুপ থেকে পাঠানো ভিডিওগুলো ডিলিট করা
471
+ if auto_share_running:
472
+ for gid, msg_ids in sent_message_ids.items():
473
+ try:
474
+ await client.delete_messages(gid, msg_ids)
475
+ await asyncio.sleep(1)
476
+ except FloodWait as e:
477
+ await asyncio.sleep(e.value + 1)
478
+ await client.delete_messages(gid, msg_ids)
479
+ except Exception:
480
+ pass
481
+
482
  except Exception as e:
483
  print(f"Auto-share loop error: {e}")
484
  await asyncio.sleep(5)
 
489
  args = message.command
490
 
491
  if len(args) > 1 and args[1].lower() == "reset":
492
+ await save_progress(STORAGE_CHANNEL_ID, -1, 0)
493
  await message.reply("🔄 <b>Progress reset!</b> The bot will now start sharing from the 1st video.")
494
 
495
  if auto_share_running:
496
  return await message.reply("⚠️ <b>Auto-share is already running!</b>\nUse `/stopshare` to stop it first.")
497
 
498
  auto_share_running = True
499
+ auto_share_task = asyncio.create_task(auto_share_loop(client, 300))
500
+ await message.reply(f"✅ <b>Smart Auto-sharing started!</b>\n\n📌 <b>Target:</b> All Groups (Admin + Delete Permitted)\n📦 <b>Batch Size:</b> 5 videos\n⏱ <b>Interval:</b> 5 minutes\n\n<i>Bot will scan all groups, verify permissions, send 5 videos, and delete them automatically!</i>", parse_mode=enums.ParseMode.HTML)
501
 
502
  @bot.on_message(filters.command("stopshare") & filters.private & filters.user(ADMIN_IDS))
503
  async def stop_sharing_cmd(client, message):
 
522
  help_text += "👉 `/stats` - Check total users, videos, and groups.\n"
523
  help_text += "👉 `/broadcast` - Send a message to all bot users.\n"
524
  help_text += "👉 `/clone <source_id> <dest_id>` - Clone videos from one group to another.\n"
525
+ help_text += "👉 `/cloneall` - Mass clone all videos from all connected groups to Target Group.\n"
526
  help_text += "👉 `/sendto <group_id>` - Reply to a media to forward it directly to a specific group.\n"
527
  help_text += "👉 `/upload <telegram/byse>` - Change video upload server (Local or byse.sx).\n"
528
  help_text += "👉 `/blur <percentage>` - Enable video/photo blur (e.g., `/blur 60`). Send `/blur 0` to disable.\n"
 
624
  try: await client.send_message(chat_id=admin_id, text=admin_msg, parse_mode=enums.ParseMode.HTML)
625
  except: pass
626
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
627
  except Exception as e:
628
  print(f"Error handling new group logic: {e}")
629
 
 
731
  status_msg = await message.reply("⏳ Initializing cloning task...", parse_mode=enums.ParseMode.HTML)
732
  asyncio.create_task(clone_videos_background(client, source_id, dest_id, status_msg))
733
 
734
+
735
+ # ================= MASS CLONE FROM ALL GROUPS =================
736
+ async def clone_all_background(client, dest_id, status_msg):
737
+ try:
738
+ groups_res = await db_query(lambda: supabase.table('groups').select('group_id').execute())
739
+ if not groups_res.data:
740
+ return await status_msg.edit_text("❌ <b>No groups found in database.</b>", parse_mode=enums.ParseMode.HTML)
741
+
742
+ groups = [g['group_id'] for g in groups_res.data]
743
+ total_groups = len(groups)
744
+
745
+ await status_msg.edit_text(f"✅ Found <b>{total_groups}</b> groups.\n🚀 Starting mass cloning from oldest videos...", parse_mode=enums.ParseMode.HTML)
746
+
747
+ total_copied = 0
748
+
749
+ for index, source_id in enumerate(groups, 1):
750
+ if source_id == dest_id or source_id == STORAGE_CHANNEL_ID or source_id == PREMIUM_CHANNEL_ID:
751
+ continue
752
+
753
+ try:
754
+ await status_msg.edit_text(f"⏳ <b>Cloning Group {index}/{total_groups}</b>\nID: <code>{source_id}</code>\nTotal Copied So Far: <b>{total_copied}</b>", parse_mode=enums.ParseMode.HTML)
755
+ except Exception: pass
756
+
757
+ progress_res = await db_query(lambda: supabase.table('clone_progress').select('last_copied_id').eq('source_id', source_id).eq('dest_id', dest_id).execute())
758
+ last_copied_id = progress_res.data[0]['last_copied_id'] if progress_res.data else None
759
+
760
+ video_ids = []
761
+ retries = 3
762
+ while retries > 0:
763
+ try:
764
+ async for msg in client.search_messages(source_id, filter=enums.MessagesFilter.VIDEO):
765
+ if last_copied_id and msg.id <= last_copied_id: continue
766
+ video_ids.append(msg.id)
767
+ if len(video_ids) % 100 == 0: await asyncio.sleep(0.1)
768
+ break
769
+ except FloodWait as e:
770
+ await asyncio.sleep(e.value + 1)
771
+ except Exception as e:
772
+ err_msg = str(e).lower()
773
+ if "disconnect" in err_msg or "connection" in err_msg or "timeout" in err_msg:
774
+ retries -= 1
775
+ video_ids = []
776
+ await asyncio.sleep(5)
777
+ else:
778
+ break
779
+
780
+ if not video_ids:
781
+ continue
782
+
783
+ video_ids.reverse()
784
+
785
+ for msg_id in video_ids:
786
+ copy_retries = 3
787
+ copy_success = False
788
+ while copy_retries > 0:
789
+ try:
790
+ await client.copy_message(chat_id=dest_id, from_chat_id=source_id, message_id=msg_id)
791
+ total_copied += 1
792
+ await save_progress(source_id, dest_id, msg_id)
793
+ copy_success = True
794
+ break
795
+ except FloodWait as e:
796
+ await asyncio.sleep(e.value + 2)
797
+ except Exception as e:
798
+ err_msg = str(e).lower()
799
+ if "disconnect" in err_msg or "connection" in err_msg or "timeout" in err_msg:
800
+ copy_retries -= 1
801
+ await asyncio.sleep(3)
802
+ else:
803
+ break
804
+ await asyncio.sleep(2.5)
805
+
806
+ await status_msg.edit_text(f"🎉 <b>Mass Cloning Completely Finished!</b>\n\nTotal Videos Copied from all groups: <b>{total_copied}</b>", parse_mode=enums.ParseMode.HTML)
807
+
808
+ except Exception as e:
809
+ try: await status_msg.edit_text(f"❌ <b>Cloning Error:</b> {e}", parse_mode=enums.ParseMode.HTML)
810
+ except: pass
811
+
812
+ @bot.on_message(filters.command("cloneall") & filters.private & filters.user(ADMIN_IDS))
813
+ async def start_mass_cloning(client, message):
814
+ dest_id = -1003798479478
815
+ status_msg = await message.reply(f"⏳ <b>Initializing mass cloning task to <code>{dest_id}</code>...</b>", parse_mode=enums.ParseMode.HTML)
816
+ asyncio.create_task(clone_all_background(client, dest_id, status_msg))
817
+
818
+
819
  @bot.on_message(filters.command("upload") & filters.private & filters.user(ADMIN_IDS))
820
  async def set_upload_mode(client, message):
821
  global upload_mode
 
1333
  print(f"Auto clean error: {e}")
1334
  await asyncio.sleep(4 * 3600)
1335
 
1336
+ @bot.on_message(filters.private & filters.user(ADMIN_IDS) & ~filters.command(["start", "stats", "users", "broadcast", "png", "addvideo", "blur", "clean", "sendto", "clone", "cloneall", "upload", "startshare", "stopshare", "help"]))
1337
  async def catch_admin_steps(client, message):
1338
  state = admin_states.get(message.chat.id, {})
1339
  if state.get("step") == 1: