Update app.py
Browse files
app.py
CHANGED
|
@@ -42,93 +42,96 @@ scheduler = AsyncIOScheduler()
|
|
| 42 |
def random_group_name():
|
| 43 |
return f"{random.choice(adjectives)} {random.choice(nouns)}"
|
| 44 |
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
|
|
|
|
|
|
|
|
|
| 49 |
|
| 50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
t = now + timedelta(minutes=random_minutes)
|
| 59 |
-
times.add(t)
|
| 60 |
|
| 61 |
-
|
| 62 |
-
|
| 63 |
|
| 64 |
-
|
|
|
|
|
|
|
|
|
|
| 65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
|
| 67 |
-
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
for plan in plans.find():
|
| 70 |
-
|
| 71 |
-
if
|
| 72 |
-
|
|
|
|
|
|
|
| 73 |
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
run_date=run_time,
|
| 84 |
-
args=[userbots[plan["user_id"]], acc, plan]
|
| 85 |
-
)
|
| 86 |
|
| 87 |
-
|
| 88 |
-
tz = pytz.timezone("Asia/Kolkata")
|
| 89 |
-
now = datetime.now(tz).replace(second=0, microsecond=0)
|
| 90 |
-
midnight = (now + timedelta(days=1)).replace(hour=0, minute=0, second=0, microsecond=0)
|
| 91 |
-
minutes_left = int((midnight - now).total_seconds() // 60)
|
| 92 |
-
|
| 93 |
-
plans.delete_many({}) # Clear old plans
|
| 94 |
|
|
|
|
|
|
|
|
|
|
| 95 |
for acc in accounts.find():
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
if minutes_left < 20:
|
| 101 |
-
continue
|
| 102 |
-
|
| 103 |
-
times = []
|
| 104 |
-
used_minutes = set()
|
| 105 |
-
while len(times) < 3:
|
| 106 |
-
now = datetime.now(tz).replace(second=0, microsecond=0)
|
| 107 |
-
minutes_left = int(((now + timedelta(days=1)).replace(hour=0, minute=0) - now).total_seconds() // 60)
|
| 108 |
-
|
| 109 |
-
if minutes_left < 10:
|
| 110 |
-
break
|
| 111 |
-
|
| 112 |
-
random_minutes = random.randint(6, minutes_left)
|
| 113 |
-
if random_minutes in used_minutes:
|
| 114 |
-
continue
|
| 115 |
-
|
| 116 |
-
used_minutes.add(random_minutes)
|
| 117 |
-
future_time = now + timedelta(minutes=random_minutes)
|
| 118 |
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
continue
|
| 122 |
|
| 123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
"created": 0
|
| 129 |
-
})
|
| 130 |
|
| 131 |
-
|
|
|
|
|
|
|
| 132 |
|
| 133 |
@bot.on(events.NewMessage(pattern=r'^/stats$'))
|
| 134 |
async def handle_stats(event):
|
|
@@ -163,23 +166,6 @@ async def handle_stats(event):
|
|
| 163 |
await event.reply(msg)
|
| 164 |
|
| 165 |
|
| 166 |
-
@bot.on(events.NewMessage(pattern=r'^/reset$'))
|
| 167 |
-
async def handle_reset(event):
|
| 168 |
-
sender = await event.get_sender()
|
| 169 |
-
if sender.id != ADMIN_ID:
|
| 170 |
-
return await event.reply("β You are not authorized to run this command.")
|
| 171 |
-
for job in scheduler.get_jobs():
|
| 172 |
-
if job.func.__name__ == "reset_and_plan" or job.id == "daily_reset_job":
|
| 173 |
-
job.remove()
|
| 174 |
-
reset_and_plan()
|
| 175 |
-
scheduler.add_job(reset_and_plan, CronTrigger(hour=0, minute=0, timezone="Asia/Kolkata"), id="daily_reset_job", replace_existing=True)
|
| 176 |
-
await event.reply("β
Schedule reset and re-planned for tonight 00:00 IST.")
|
| 177 |
-
|
| 178 |
-
scheduler.add_job(reset_and_plan, CronTrigger(hour=0, minute=0, timezone="Asia/Kolkata"), id="daily_reset_job", replace_existing=True)
|
| 179 |
-
|
| 180 |
-
# Continue with rest of your previous unchanged functions and endpoints...
|
| 181 |
-
# (like auto_create_groups, start_userbot, load_all_userbots, Flask setup, etc.)
|
| 182 |
-
|
| 183 |
async def auto_create_groups(userbot, acc_doc, plan_doc=None):
|
| 184 |
if plan_doc and plan_doc["created"] >= len(plan_doc["times"]):
|
| 185 |
await bot.send_message(ADMIN_ID, f"β Group creation skipped: Limit exceeded for {acc_doc['name']}")
|
|
|
|
| 42 |
def random_group_name():
|
| 43 |
return f"{random.choice(adjectives)} {random.choice(nouns)}"
|
| 44 |
|
| 45 |
+
import random
|
| 46 |
+
from datetime import datetime, timedelta
|
| 47 |
+
from pymongo import MongoClient
|
| 48 |
+
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
| 49 |
+
from apscheduler.triggers.cron import CronTrigger
|
| 50 |
+
import pytz
|
| 51 |
+
from telethon import events
|
| 52 |
|
| 53 |
+
# MongoDB setup
|
| 54 |
+
client = MongoClient("mongodb://localhost:27017/")
|
| 55 |
+
db = client["mydb"]
|
| 56 |
+
accounts = db["accounts"]
|
| 57 |
+
plans = db["plans"]
|
| 58 |
|
| 59 |
+
# Scheduler
|
| 60 |
+
scheduler = AsyncIOScheduler()
|
| 61 |
+
scheduler.start()
|
| 62 |
|
| 63 |
+
# Timezone
|
| 64 |
+
tz = pytz.timezone("Asia/Kolkata")
|
|
|
|
|
|
|
| 65 |
|
| 66 |
+
# Dummy userbot registry
|
| 67 |
+
userbots = {} # Fill this with: {user_id: bot_instance}
|
| 68 |
|
| 69 |
+
def create_plan(account, limit):
|
| 70 |
+
now = datetime.now(tz)
|
| 71 |
+
end_of_day = now.replace(hour=23, minute=59, second=59, microsecond=0)
|
| 72 |
+
time_gap = (end_of_day - now) / limit
|
| 73 |
|
| 74 |
+
times = []
|
| 75 |
+
for i in range(limit):
|
| 76 |
+
planned_time = now + i * time_gap
|
| 77 |
+
# Ensure future time
|
| 78 |
+
if planned_time <= now:
|
| 79 |
+
planned_time = now + timedelta(minutes=1)
|
| 80 |
+
times.append(planned_time)
|
| 81 |
|
| 82 |
+
for t in times:
|
| 83 |
+
plans.insert_one({
|
| 84 |
+
"account_id": account["_id"],
|
| 85 |
+
"scheduled_time": t.isoformat()
|
| 86 |
+
})
|
| 87 |
+
|
| 88 |
+
def apply_plan():
|
| 89 |
+
now = datetime.now(tz)
|
| 90 |
for plan in plans.find():
|
| 91 |
+
plan_time = datetime.fromisoformat(plan["scheduled_time"]).astimezone(tz)
|
| 92 |
+
if plan_time > now:
|
| 93 |
+
account = accounts.find_one({"_id": plan["account_id"]})
|
| 94 |
+
if not account:
|
| 95 |
+
continue
|
| 96 |
|
| 97 |
+
userbot = userbots.get(account["_id"])
|
| 98 |
+
if not userbot:
|
| 99 |
+
continue
|
| 100 |
|
| 101 |
+
def job_wrapper(acc_id):
|
| 102 |
+
def job():
|
| 103 |
+
print(f"Running job for account {acc_id} at {datetime.now(tz)}")
|
| 104 |
+
# Your action here
|
| 105 |
+
return job
|
|
|
|
|
|
|
|
|
|
| 106 |
|
| 107 |
+
scheduler.add_job(job_wrapper(account["_id"]), trigger='date', run_date=plan_time)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
|
| 109 |
+
def reset_and_plan():
|
| 110 |
+
print("π Resetting plans and scheduling new ones...")
|
| 111 |
+
plans.delete_many({}) # Clear all plans
|
| 112 |
for acc in accounts.find():
|
| 113 |
+
limit = random.randint(3, 5)
|
| 114 |
+
create_plan(acc, limit)
|
| 115 |
+
apply_plan()
|
| 116 |
+
print("β
Plans created and scheduled.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
|
| 118 |
+
# Schedule reset daily at 00:00 IST
|
| 119 |
+
scheduler.add_job(reset_and_plan, CronTrigger(hour=0, minute=0, timezone="Asia/Kolkata"), id="daily_reset_job", replace_existing=True)
|
|
|
|
| 120 |
|
| 121 |
+
# Telethon /reset command
|
| 122 |
+
@bot.on(events.NewMessage(pattern=r'^/reset$'))
|
| 123 |
+
async def handle_reset(event):
|
| 124 |
+
sender = await event.get_sender()
|
| 125 |
+
if sender.id != ADMIN_ID:
|
| 126 |
+
return await event.reply("β You are not authorized to run this command.")
|
| 127 |
|
| 128 |
+
for job in scheduler.get_jobs():
|
| 129 |
+
if job.func.__name__ == "reset_and_plan" or job.id == "daily_reset_job":
|
| 130 |
+
job.remove()
|
|
|
|
|
|
|
| 131 |
|
| 132 |
+
reset_and_plan()
|
| 133 |
+
scheduler.add_job(reset_and_plan, CronTrigger(hour=0, minute=0, timezone="Asia/Kolkata"), id="daily_reset_job", replace_existing=True)
|
| 134 |
+
await event.reply("β
Schedule reset and re-planned for tonight 00:00 IST.")
|
| 135 |
|
| 136 |
@bot.on(events.NewMessage(pattern=r'^/stats$'))
|
| 137 |
async def handle_stats(event):
|
|
|
|
| 166 |
await event.reply(msg)
|
| 167 |
|
| 168 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
async def auto_create_groups(userbot, acc_doc, plan_doc=None):
|
| 170 |
if plan_doc and plan_doc["created"] >= len(plan_doc["times"]):
|
| 171 |
await bot.send_message(ADMIN_ID, f"β Group creation skipped: Limit exceeded for {acc_doc['name']}")
|