Spaces:
Sleeping
Sleeping
src
Browse files- Dockerfilee +17 -0
- Procfile +1 -0
- app.py +39 -0
- config.py +14 -0
- devgagan/__init__.py +47 -0
- devgagan/__main__.py +74 -0
- devgagan/core/__init__.py +1 -0
- devgagan/core/func.py +249 -0
- devgagan/core/get_func.py +632 -0
- devgagan/core/mongo/__init__.py +1 -0
- devgagan/core/mongo/db.py +103 -0
- devgagan/core/mongo/plans_db.py +34 -0
- devgagan/core/mongo/users_db.py +42 -0
- devgagan/core/script.py +83 -0
- devgagan/modules/__init__.py +21 -0
- devgagan/modules/eval.py +214 -0
- devgagan/modules/gcast.py +84 -0
- devgagan/modules/login.py +116 -0
- devgagan/modules/main.py +246 -0
- devgagan/modules/pingme.py +18 -0
- devgagan/modules/plans.py +116 -0
- devgagan/modules/start.py +24 -0
- devgagan/modules/stats.py +35 -0
- package.json +11 -0
- requirements.txt +16 -0
- settings.jpg +0 -0
- start.sh +3 -0
- static/gagan.png +0 -0
Dockerfilee
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM python:3.10.4-slim-buster
|
| 2 |
+
RUN apt update && apt upgrade -y
|
| 3 |
+
RUN apt-get install git curl python3-pip ffmpeg -y
|
| 4 |
+
RUN apt-get -y install git
|
| 5 |
+
RUN apt-get install -y wget python3-pip curl bash neofetch ffmpeg software-properties-common
|
| 6 |
+
|
| 7 |
+
RUN pip3 install wheel
|
| 8 |
+
RUN pip3 install --no-cache-dir -U -r requirements.txt
|
| 9 |
+
WORKDIR /app
|
| 10 |
+
COPY . /app
|
| 11 |
+
RUN chown -R 1000 /app /usr && \
|
| 12 |
+
chown 777 /app && \
|
| 13 |
+
chmod +x /app/start.sh
|
| 14 |
+
|
| 15 |
+
EXPOSE 5000 8000
|
| 16 |
+
CMD flask run -h 0.0.0.0 -p 8000 & python3 -m devgagan
|
| 17 |
+
# CMD gunicorn app:app & python3 -m devgagan
|
Procfile
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
worker: python -m devgagan
|
app.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from flask import Flask
|
| 3 |
+
|
| 4 |
+
app = Flask(__name__)
|
| 5 |
+
|
| 6 |
+
@app.route('/')
|
| 7 |
+
def home():
|
| 8 |
+
return """
|
| 9 |
+
<center>
|
| 10 |
+
<img src="/static/gagan.png" style="border-radius: 2px;"/>/>
|
| 11 |
+
</center>
|
| 12 |
+
<style>
|
| 13 |
+
body {
|
| 14 |
+
background: antiquewhite;
|
| 15 |
+
display: flex;
|
| 16 |
+
flex-direction: column;
|
| 17 |
+
justify-content: space-between;
|
| 18 |
+
height: 100vh;
|
| 19 |
+
margin: 0;
|
| 20 |
+
}
|
| 21 |
+
footer {
|
| 22 |
+
text-align: center;
|
| 23 |
+
padding: 10px;
|
| 24 |
+
background: antiquewhite;
|
| 25 |
+
font-size: 1.2em;
|
| 26 |
+
}
|
| 27 |
+
</style>
|
| 28 |
+
<footer>
|
| 29 |
+
Made with 💕 by devgagan.in
|
| 30 |
+
</footer>
|
| 31 |
+
"""
|
| 32 |
+
@app.get("/status")
|
| 33 |
+
def status():
|
| 34 |
+
return {"message": "running"}
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
if __name__ == "__main__":
|
| 38 |
+
port = int(os.environ.get("PORT", 5000))
|
| 39 |
+
app.run(host='0.0.0.0', port=port)
|
config.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# devgagan
|
| 2 |
+
# Note if you are trying to deploy on vps then directly fill values in ("")
|
| 3 |
+
|
| 4 |
+
from os import getenv
|
| 5 |
+
|
| 6 |
+
API_ID = int(getenv("API_ID", ""))
|
| 7 |
+
API_HASH = getenv("API_HASH", "")
|
| 8 |
+
BOT_TOKEN = getenv("BOT_TOKEN", "")
|
| 9 |
+
OWNER_ID = list(map(int, getenv("OWNER_ID", "").split()))
|
| 10 |
+
MONGO_DB = getenv("MONGO_DB", "")
|
| 11 |
+
LOG_GROUP = getenv("LOG_GROUP", "")
|
| 12 |
+
CHANNEL_ID = int(getenv("CHANNEL_ID", ""))
|
| 13 |
+
FREEMIUM_LIMIT = int(getenv("FREEMIUM_LIMIT", "100"))
|
| 14 |
+
PREMIUM_LIMIT = int(getenv("PREMIUM_LIMIT", "5000"))
|
devgagan/__init__.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#devggn
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
import asyncio
|
| 5 |
+
import logging
|
| 6 |
+
from pyromod import listen
|
| 7 |
+
from pyrogram import Client
|
| 8 |
+
from config import API_ID, API_HASH, BOT_TOKEN
|
| 9 |
+
from telethon.sync import TelegramClient
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
loop = asyncio.get_event_loop()
|
| 13 |
+
|
| 14 |
+
logging.basicConfig(
|
| 15 |
+
format="[%(levelname) 5s/%(asctime)s] %(name)s: %(message)s",
|
| 16 |
+
level=logging.INFO,
|
| 17 |
+
)
|
| 18 |
+
|
| 19 |
+
sex = TelegramClient('sexrepo', API_ID, API_HASH).start(bot_token=BOT_TOKEN)
|
| 20 |
+
|
| 21 |
+
app = Client(
|
| 22 |
+
":RestrictBot:",
|
| 23 |
+
api_id=API_ID,
|
| 24 |
+
api_hash=API_HASH,
|
| 25 |
+
bot_token=BOT_TOKEN,
|
| 26 |
+
workers=10,
|
| 27 |
+
sleep_threshold=20,
|
| 28 |
+
max_concurrent_transmissions=5
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
async def restrict_bot():
|
| 34 |
+
global BOT_ID, BOT_NAME, BOT_USERNAME
|
| 35 |
+
await app.start()
|
| 36 |
+
getme = await app.get_me()
|
| 37 |
+
BOT_ID = getme.id
|
| 38 |
+
BOT_USERNAME = getme.username
|
| 39 |
+
if getme.last_name:
|
| 40 |
+
BOT_NAME = getme.first_name + " " + getme.last_name
|
| 41 |
+
else:
|
| 42 |
+
BOT_NAME = getme.first_name
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
loop.run_until_complete(restrict_bot())
|
| 46 |
+
|
| 47 |
+
|
devgagan/__main__.py
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# devggn
|
| 2 |
+
|
| 3 |
+
import asyncio
|
| 4 |
+
import importlib
|
| 5 |
+
import psutil
|
| 6 |
+
import gc # For garbage collection
|
| 7 |
+
from pyrogram import idle
|
| 8 |
+
from aiojobs import create_scheduler
|
| 9 |
+
from devgagan.modules import ALL_MODULES
|
| 10 |
+
from devgagan.core.mongo.plans_db import check_and_remove_expired_users
|
| 11 |
+
|
| 12 |
+
# Subprocess monitoring interval (in seconds)
|
| 13 |
+
CHECK_INTERVAL = 1800 # 30 minutes
|
| 14 |
+
# Memory optimization interval (in seconds)
|
| 15 |
+
MEMORY_OPTIMIZATION_INTERVAL = 600 # 10 minutes
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
# Function to monitor and terminate idle subprocesses
|
| 19 |
+
async def close_idle_subprocesses():
|
| 20 |
+
while True:
|
| 21 |
+
for proc in psutil.process_iter(['pid', 'name', 'create_time']):
|
| 22 |
+
try:
|
| 23 |
+
# Terminate subprocesses spawned by the current process
|
| 24 |
+
if proc.ppid() == psutil.Process().pid:
|
| 25 |
+
proc.terminate()
|
| 26 |
+
print(f"Terminated subprocess: PID {proc.pid}, Name: {proc.name()}")
|
| 27 |
+
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
| 28 |
+
pass
|
| 29 |
+
await asyncio.sleep(CHECK_INTERVAL)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
# Function to reduce memory usage
|
| 33 |
+
async def optimize_memory():
|
| 34 |
+
while True:
|
| 35 |
+
gc.collect()
|
| 36 |
+
process = psutil.Process()
|
| 37 |
+
memory_info = process.memory_info()
|
| 38 |
+
print(f"Memory Usage: {memory_info.rss / 1024 / 1024:.2f} MB")
|
| 39 |
+
await asyncio.sleep(MEMORY_OPTIMIZATION_INTERVAL)
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
# Function to schedule expiry checks
|
| 43 |
+
async def schedule_expiry_check():
|
| 44 |
+
scheduler = await create_scheduler()
|
| 45 |
+
while True:
|
| 46 |
+
await scheduler.spawn(check_and_remove_expired_users())
|
| 47 |
+
await asyncio.sleep(3600) # Check every hour
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
# Main bot function
|
| 51 |
+
async def devggn_boot():
|
| 52 |
+
# Import modules
|
| 53 |
+
for all_module in ALL_MODULES:
|
| 54 |
+
importlib.import_module("devgagan.modules." + all_module)
|
| 55 |
+
|
| 56 |
+
# print("»»»» ʙᴏᴛ ᴅᴇᴘʟᴏʏ sᴜᴄᴄᴇssғᴜʟʟʏ ✨ 🎉")
|
| 57 |
+
print("Bot started!") # Added print statement here
|
| 58 |
+
|
| 59 |
+
# Start background tasks
|
| 60 |
+
asyncio.create_task(schedule_expiry_check())
|
| 61 |
+
asyncio.create_task(close_idle_subprocesses())
|
| 62 |
+
asyncio.create_task(optimize_memory())
|
| 63 |
+
|
| 64 |
+
# Keep the bot running
|
| 65 |
+
await idle()
|
| 66 |
+
print("Lol ...")
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
# Run the bot
|
| 70 |
+
if __name__ == "__main__":
|
| 71 |
+
# Reuse the existing event loop
|
| 72 |
+
loop = asyncio.get_event_loop()
|
| 73 |
+
loop.run_until_complete(devggn_boot())
|
| 74 |
+
|
devgagan/core/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
|
devgagan/core/func.py
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#AgainOwner
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
import math
|
| 5 |
+
import time , re
|
| 6 |
+
from pyrogram import enums
|
| 7 |
+
from config import CHANNEL_ID, OWNER_ID
|
| 8 |
+
from devgagan.core import script
|
| 9 |
+
from devgagan.core.mongo.plans_db import premium_users
|
| 10 |
+
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
| 11 |
+
import cv2
|
| 12 |
+
from pyrogram.errors import FloodWait, InviteHashInvalid, InviteHashExpired, UserAlreadyParticipant, UserNotParticipant
|
| 13 |
+
from datetime import datetime as dt
|
| 14 |
+
import asyncio, subprocess, re, os, time
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
async def chk_user(message, user_id):
|
| 19 |
+
user = await premium_users()
|
| 20 |
+
if user_id in user or user_id in OWNER_ID:
|
| 21 |
+
return 0
|
| 22 |
+
else:
|
| 23 |
+
# await message.reply_text("Purchase premium to do the tasks...")
|
| 24 |
+
return 1
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
async def gen_link(app,chat_id):
|
| 29 |
+
link = await app.export_chat_invite_link(chat_id)
|
| 30 |
+
return link
|
| 31 |
+
|
| 32 |
+
async def subscribe(app, message):
|
| 33 |
+
update_channel = CHANNEL_ID
|
| 34 |
+
url = await gen_link(app, update_channel)
|
| 35 |
+
if update_channel:
|
| 36 |
+
try:
|
| 37 |
+
user = await app.get_chat_member(update_channel, message.from_user.id)
|
| 38 |
+
if user.status == "kicked":
|
| 39 |
+
await message.reply_text("You are Banned. Contact -- @AgainOwner")
|
| 40 |
+
return 1
|
| 41 |
+
except UserNotParticipant:
|
| 42 |
+
await message.reply_photo(photo="https://graph.org/file/d44f024a08ded19452152.jpg",caption=script.FORCE_MSG.format(message.from_user.mention), reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Join Now...", url=f"{url}")]]))
|
| 43 |
+
return 1
|
| 44 |
+
except Exception:
|
| 45 |
+
await message.reply_text("Something Went Wrong. Contact us @AgainOwner...")
|
| 46 |
+
return 1
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
async def get_seconds(time_string):
|
| 51 |
+
def extract_value_and_unit(ts):
|
| 52 |
+
value = ""
|
| 53 |
+
unit = ""
|
| 54 |
+
|
| 55 |
+
index = 0
|
| 56 |
+
while index < len(ts) and ts[index].isdigit():
|
| 57 |
+
value += ts[index]
|
| 58 |
+
index += 1
|
| 59 |
+
|
| 60 |
+
unit = ts[index:].lstrip()
|
| 61 |
+
|
| 62 |
+
if value:
|
| 63 |
+
value = int(value)
|
| 64 |
+
|
| 65 |
+
return value, unit
|
| 66 |
+
|
| 67 |
+
value, unit = extract_value_and_unit(time_string)
|
| 68 |
+
|
| 69 |
+
if unit == 's':
|
| 70 |
+
return value
|
| 71 |
+
elif unit == 'min':
|
| 72 |
+
return value * 60
|
| 73 |
+
elif unit == 'hour':
|
| 74 |
+
return value * 3600
|
| 75 |
+
elif unit == 'day':
|
| 76 |
+
return value * 86400
|
| 77 |
+
elif unit == 'month':
|
| 78 |
+
return value * 86400 * 30
|
| 79 |
+
elif unit == 'year':
|
| 80 |
+
return value * 86400 * 365
|
| 81 |
+
else:
|
| 82 |
+
return 0
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
PROGRESS_BAR = """\n
|
| 88 |
+
**__Completed__** : {1}/{2}
|
| 89 |
+
**__Bytes__** : {0}%
|
| 90 |
+
**__Speed__** : {3}/s
|
| 91 |
+
**__Time__** : {4}
|
| 92 |
+
"""
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
async def progress_bar(current, total, ud_type, message, start):
|
| 96 |
+
|
| 97 |
+
now = time.time()
|
| 98 |
+
diff = now - start
|
| 99 |
+
if round(diff % 10.00) == 0 or current == total:
|
| 100 |
+
# if round(current / total * 100, 0) % 5 == 0:
|
| 101 |
+
percentage = current * 100 / total
|
| 102 |
+
speed = current / diff
|
| 103 |
+
elapsed_time = round(diff) * 1000
|
| 104 |
+
time_to_completion = round((total - current) / speed) * 1000
|
| 105 |
+
estimated_total_time = elapsed_time + time_to_completion
|
| 106 |
+
|
| 107 |
+
elapsed_time = TimeFormatter(milliseconds=elapsed_time)
|
| 108 |
+
estimated_total_time = TimeFormatter(milliseconds=estimated_total_time)
|
| 109 |
+
|
| 110 |
+
progress = "{0}{1}".format(
|
| 111 |
+
''.join(["🟢" for i in range(math.floor(percentage / 10))]),
|
| 112 |
+
''.join(["🔴" for i in range(10 - math.floor(percentage / 10))]))
|
| 113 |
+
|
| 114 |
+
tmp = progress + PROGRESS_BAR.format(
|
| 115 |
+
round(percentage, 2),
|
| 116 |
+
humanbytes(current),
|
| 117 |
+
humanbytes(total),
|
| 118 |
+
humanbytes(speed),
|
| 119 |
+
# elapsed_time if elapsed_time != '' else "0 s",
|
| 120 |
+
estimated_total_time if estimated_total_time != '' else "0 s"
|
| 121 |
+
)
|
| 122 |
+
try:
|
| 123 |
+
await message.edit(
|
| 124 |
+
text="{}\n\n{}".format(ud_type, tmp),)
|
| 125 |
+
|
| 126 |
+
except:
|
| 127 |
+
pass
|
| 128 |
+
|
| 129 |
+
def humanbytes(size):
|
| 130 |
+
if not size:
|
| 131 |
+
return ""
|
| 132 |
+
power = 2**10
|
| 133 |
+
n = 0
|
| 134 |
+
Dic_powerN = {0: ' ', 1: 'K', 2: 'M', 3: 'G', 4: 'T'}
|
| 135 |
+
while size > power:
|
| 136 |
+
size /= power
|
| 137 |
+
n += 1
|
| 138 |
+
return str(round(size, 2)) + " " + Dic_powerN[n] + 'B'
|
| 139 |
+
|
| 140 |
+
def TimeFormatter(milliseconds: int) -> str:
|
| 141 |
+
seconds, milliseconds = divmod(int(milliseconds), 1000)
|
| 142 |
+
minutes, seconds = divmod(seconds, 60)
|
| 143 |
+
hours, minutes = divmod(minutes, 60)
|
| 144 |
+
days, hours = divmod(hours, 24)
|
| 145 |
+
tmp = ((str(days) + "d, ") if days else "") + \
|
| 146 |
+
((str(hours) + "h, ") if hours else "") + \
|
| 147 |
+
((str(minutes) + "m, ") if minutes else "") + \
|
| 148 |
+
((str(seconds) + "s, ") if seconds else "") + \
|
| 149 |
+
((str(milliseconds) + "ms, ") if milliseconds else "")
|
| 150 |
+
return tmp[:-2]
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
def convert(seconds):
|
| 155 |
+
seconds = seconds % (24 * 3600)
|
| 156 |
+
hour = seconds // 3600
|
| 157 |
+
seconds %= 3600
|
| 158 |
+
minutes = seconds // 60
|
| 159 |
+
seconds %= 60
|
| 160 |
+
return "%d:%02d:%02d" % (hour, minutes, seconds)
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
async def userbot_join(userbot, invite_link):
|
| 166 |
+
try:
|
| 167 |
+
await userbot.join_chat(invite_link)
|
| 168 |
+
return "Successfully joined the Channel"
|
| 169 |
+
except UserAlreadyParticipant:
|
| 170 |
+
return "User is already a participant."
|
| 171 |
+
except (InviteHashInvalid, InviteHashExpired):
|
| 172 |
+
return "Could not join. Maybe your link is expired or Invalid."
|
| 173 |
+
except FloodWait:
|
| 174 |
+
return "Too many requests, try again later."
|
| 175 |
+
except Exception as e:
|
| 176 |
+
print(e)
|
| 177 |
+
return "Could not join, try joining manually."
|
| 178 |
+
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
def get_link(string):
|
| 182 |
+
regex = r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))"
|
| 183 |
+
url = re.findall(regex,string)
|
| 184 |
+
try:
|
| 185 |
+
link = [x[0] for x in url][0]
|
| 186 |
+
if link:
|
| 187 |
+
return link
|
| 188 |
+
else:
|
| 189 |
+
return False
|
| 190 |
+
except Exception:
|
| 191 |
+
return False
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
def video_metadata(file):
|
| 195 |
+
default_values = {'width': 1, 'height': 1, 'duration': 1}
|
| 196 |
+
try:
|
| 197 |
+
vcap = cv2.VideoCapture(file)
|
| 198 |
+
if not vcap.isOpened():
|
| 199 |
+
return default_values # Return defaults if video cannot be opened
|
| 200 |
+
|
| 201 |
+
width = round(vcap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
| 202 |
+
height = round(vcap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
| 203 |
+
fps = vcap.get(cv2.CAP_PROP_FPS)
|
| 204 |
+
frame_count = vcap.get(cv2.CAP_PROP_FRAME_COUNT)
|
| 205 |
+
|
| 206 |
+
if fps <= 0:
|
| 207 |
+
return default_values # Return defaults if FPS value is zero or negative
|
| 208 |
+
|
| 209 |
+
duration = round(frame_count / fps)
|
| 210 |
+
if duration <= 0:
|
| 211 |
+
return default_values # Return defaults if duration is zero or negative
|
| 212 |
+
|
| 213 |
+
vcap.release()
|
| 214 |
+
return {'width': width, 'height': height, 'duration': duration}
|
| 215 |
+
|
| 216 |
+
except Exception as e:
|
| 217 |
+
print(f"Error in video_metadata: {e}")
|
| 218 |
+
return default_values
|
| 219 |
+
|
| 220 |
+
def hhmmss(seconds):
|
| 221 |
+
return time.strftime('%H:%M:%S',time.gmtime(seconds))
|
| 222 |
+
|
| 223 |
+
async def screenshot(video, duration, sender):
|
| 224 |
+
if os.path.exists(f'{sender}.jpg'):
|
| 225 |
+
return f'{sender}.jpg'
|
| 226 |
+
time_stamp = hhmmss(int(duration)/2)
|
| 227 |
+
out = dt.now().isoformat("_", "seconds") + ".jpg"
|
| 228 |
+
cmd = ["ffmpeg",
|
| 229 |
+
"-ss",
|
| 230 |
+
f"{time_stamp}",
|
| 231 |
+
"-i",
|
| 232 |
+
f"{video}",
|
| 233 |
+
"-frames:v",
|
| 234 |
+
"1",
|
| 235 |
+
f"{out}",
|
| 236 |
+
"-y"
|
| 237 |
+
]
|
| 238 |
+
process = await asyncio.create_subprocess_exec(
|
| 239 |
+
*cmd,
|
| 240 |
+
stdout=asyncio.subprocess.PIPE,
|
| 241 |
+
stderr=asyncio.subprocess.PIPE
|
| 242 |
+
)
|
| 243 |
+
stdout, stderr = await process.communicate()
|
| 244 |
+
x = stderr.decode().strip()
|
| 245 |
+
y = stdout.decode().strip()
|
| 246 |
+
if os.path.isfile(out):
|
| 247 |
+
return out
|
| 248 |
+
else:
|
| 249 |
+
None
|
devgagan/core/get_func.py
ADDED
|
@@ -0,0 +1,632 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#devgaganin
|
| 2 |
+
import asyncio
|
| 3 |
+
import time
|
| 4 |
+
import os
|
| 5 |
+
import re
|
| 6 |
+
import subprocess
|
| 7 |
+
import requests
|
| 8 |
+
from devgagan import app
|
| 9 |
+
from devgagan import sex as gf
|
| 10 |
+
import pymongo
|
| 11 |
+
from pyrogram import filters
|
| 12 |
+
from pyrogram.errors import ChannelBanned, ChannelInvalid, ChannelPrivate, ChatIdInvalid, ChatInvalid, PeerIdInvalid
|
| 13 |
+
from pyrogram.enums import MessageMediaType
|
| 14 |
+
from devgagan.core.func import progress_bar, video_metadata, screenshot
|
| 15 |
+
from devgagan.core.mongo import db
|
| 16 |
+
from pyrogram.types import Message
|
| 17 |
+
from config import MONGO_DB as MONGODB_CONNECTION_STRING, LOG_GROUP
|
| 18 |
+
import cv2
|
| 19 |
+
from telethon import events, Button
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
# ------------- PDF WATERMARK IMPORTS --------------
|
| 23 |
+
# Will give after 200 star on my repo or 100+ followers ...
|
| 24 |
+
# ------------- PDF WATERMARK IMPORTS --------------
|
| 25 |
+
|
| 26 |
+
def thumbnail(sender):
|
| 27 |
+
return f'{sender}.jpg' if os.path.exists(f'{sender}.jpg') else None
|
| 28 |
+
|
| 29 |
+
async def get_msg(userbot, sender, edit_id, msg_link, i, message):
|
| 30 |
+
edit = ""
|
| 31 |
+
chat = ""
|
| 32 |
+
round_message = False
|
| 33 |
+
if "?single" in msg_link:
|
| 34 |
+
msg_link = msg_link.split("?single")[0]
|
| 35 |
+
msg_id = int(msg_link.split("/")[-1]) + int(i)
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
if 't.me/c/' in msg_link or 't.me/b/' in msg_link:
|
| 39 |
+
parts = msg_link.split("/")
|
| 40 |
+
if 't.me/b/' not in msg_link:
|
| 41 |
+
chat = int('-100' + str(parts[parts.index('c') + 1])) # topic group/subgroup support enabled
|
| 42 |
+
else:
|
| 43 |
+
chat = msg_link.split("/")[-2]
|
| 44 |
+
file = ""
|
| 45 |
+
try:
|
| 46 |
+
chatx = message.chat.id
|
| 47 |
+
msg = await userbot.get_messages(chat, msg_id)
|
| 48 |
+
caption = None
|
| 49 |
+
|
| 50 |
+
if msg.service is not None:
|
| 51 |
+
return None
|
| 52 |
+
if msg.empty is not None:
|
| 53 |
+
return None
|
| 54 |
+
if msg.media:
|
| 55 |
+
if msg.media == MessageMediaType.WEB_PAGE:
|
| 56 |
+
target_chat_id = user_chat_ids.get(chatx, chatx)
|
| 57 |
+
edit = await app.edit_message_text(target_chat_id, edit_id, "Cloning...")
|
| 58 |
+
devgaganin = await app.send_message(sender, msg.text.markdown)
|
| 59 |
+
if msg.pinned_message:
|
| 60 |
+
try:
|
| 61 |
+
await devgaganin.pin(both_sides=True)
|
| 62 |
+
except Exception as e:
|
| 63 |
+
await devgaganin.pin()
|
| 64 |
+
await devgaganin.copy(LOG_GROUP)
|
| 65 |
+
await edit.delete()
|
| 66 |
+
return
|
| 67 |
+
if not msg.media:
|
| 68 |
+
if msg.text:
|
| 69 |
+
target_chat_id = user_chat_ids.get(chatx, chatx)
|
| 70 |
+
edit = await app.edit_message_text(target_chat_id, edit_id, "Cloning...")
|
| 71 |
+
devgaganin = await app.send_message(sender, msg.text.markdown)
|
| 72 |
+
if msg.pinned_message:
|
| 73 |
+
try:
|
| 74 |
+
await devgaganin.pin(both_sides=True)
|
| 75 |
+
except Exception as e:
|
| 76 |
+
await devgaganin.pin()
|
| 77 |
+
await devgaganin.copy(LOG_GROUP)
|
| 78 |
+
await edit.delete()
|
| 79 |
+
return
|
| 80 |
+
|
| 81 |
+
edit = await app.edit_message_text(sender, edit_id, "Trying to Download...")
|
| 82 |
+
file = await userbot.download_media(
|
| 83 |
+
msg,
|
| 84 |
+
progress=progress_bar,
|
| 85 |
+
progress_args=("**__Downloading: __**",edit,time.time()))
|
| 86 |
+
|
| 87 |
+
custom_rename_tag = get_user_rename_preference(chatx)
|
| 88 |
+
last_dot_index = str(file).rfind('.')
|
| 89 |
+
if last_dot_index != -1 and last_dot_index != 0:
|
| 90 |
+
ggn_ext = str(file)[last_dot_index + 1:]
|
| 91 |
+
if ggn_ext.isalpha() and len(ggn_ext) <= 4:
|
| 92 |
+
if ggn_ext.lower() == 'mov':
|
| 93 |
+
original_file_name = str(file)[:last_dot_index]
|
| 94 |
+
file_extension = ggn_ext.lower()
|
| 95 |
+
if file_extension == 'mov': # fixed mov
|
| 96 |
+
file_extension = 'mp4'
|
| 97 |
+
else:
|
| 98 |
+
original_file_name = str(file)[:last_dot_index]
|
| 99 |
+
file_extension = ggn_ext
|
| 100 |
+
else:
|
| 101 |
+
original_file_name = str(file)
|
| 102 |
+
file_extension = 'mp4'
|
| 103 |
+
else:
|
| 104 |
+
original_file_name = str(file)
|
| 105 |
+
file_extension = 'mp4'
|
| 106 |
+
|
| 107 |
+
delete_words = load_delete_words(chatx)
|
| 108 |
+
for word in delete_words:
|
| 109 |
+
original_file_name = original_file_name.replace(word, "")
|
| 110 |
+
video_file_name = original_file_name + " " + custom_rename_tag
|
| 111 |
+
replacements = load_replacement_words(chatx)
|
| 112 |
+
for word, replace_word in replacements.items():
|
| 113 |
+
original_file_name = original_file_name.replace(word, replace_word)
|
| 114 |
+
new_file_name = original_file_name + " " + custom_rename_tag + "." + file_extension
|
| 115 |
+
os.rename(file, new_file_name)
|
| 116 |
+
file = new_file_name
|
| 117 |
+
|
| 118 |
+
# CODES are hidden
|
| 119 |
+
|
| 120 |
+
await edit.edit('Trying to Uplaod ...')
|
| 121 |
+
|
| 122 |
+
if msg.media == MessageMediaType.VIDEO and msg.video.mime_type in ["video/mp4", "video/x-matroska"]:
|
| 123 |
+
|
| 124 |
+
metadata = video_metadata(file)
|
| 125 |
+
width= metadata['width']
|
| 126 |
+
height= metadata['height']
|
| 127 |
+
duration= metadata['duration']
|
| 128 |
+
|
| 129 |
+
if duration <= 300:
|
| 130 |
+
devgaganin = await app.send_video(chat_id=sender, video=file, caption=caption, height=height, width=width, duration=duration, thumb=None, progress=progress_bar, progress_args=('**UPLOADING:**\n', edit, time.time()))
|
| 131 |
+
if msg.pinned_message:
|
| 132 |
+
try:
|
| 133 |
+
await devgaganin.pin(both_sides=True)
|
| 134 |
+
except Exception as e:
|
| 135 |
+
await devgaganin.pin()
|
| 136 |
+
await devgaganin.copy(LOG_GROUP)
|
| 137 |
+
await edit.delete()
|
| 138 |
+
return
|
| 139 |
+
|
| 140 |
+
delete_words = load_delete_words(sender)
|
| 141 |
+
custom_caption = get_user_caption_preference(sender)
|
| 142 |
+
original_caption = msg.caption if msg.caption else ''
|
| 143 |
+
final_caption = f"{original_caption}" if custom_caption else f"{original_caption}"
|
| 144 |
+
|
| 145 |
+
replacements = load_replacement_words(sender)
|
| 146 |
+
for word, replace_word in replacements.items():
|
| 147 |
+
final_caption = final_caption.replace(word, replace_word)
|
| 148 |
+
caption = f"{final_caption}\n\n__**{custom_caption}**__" if custom_caption else f"{final_caption}"
|
| 149 |
+
|
| 150 |
+
target_chat_id = user_chat_ids.get(chatx, chatx)
|
| 151 |
+
|
| 152 |
+
thumb_path = await screenshot(file, duration, chatx)
|
| 153 |
+
try:
|
| 154 |
+
devgaganin = await app.send_video(
|
| 155 |
+
chat_id=target_chat_id,
|
| 156 |
+
video=file,
|
| 157 |
+
caption=caption,
|
| 158 |
+
supports_streaming=True,
|
| 159 |
+
height=height,
|
| 160 |
+
width=width,
|
| 161 |
+
duration=duration,
|
| 162 |
+
thumb=thumb_path,
|
| 163 |
+
progress=progress_bar,
|
| 164 |
+
progress_args=(
|
| 165 |
+
'**__Uploading...__**',
|
| 166 |
+
edit,
|
| 167 |
+
time.time()
|
| 168 |
+
)
|
| 169 |
+
)
|
| 170 |
+
if msg.pinned_message:
|
| 171 |
+
try:
|
| 172 |
+
await devgaganin.pin(both_sides=True)
|
| 173 |
+
except Exception as e:
|
| 174 |
+
await devgaganin.pin()
|
| 175 |
+
await devgaganin.copy(LOG_GROUP)
|
| 176 |
+
except:
|
| 177 |
+
await app.edit_message_text(sender, edit_id, "The bot is not an admin in the specified chat...")
|
| 178 |
+
|
| 179 |
+
os.remove(file)
|
| 180 |
+
|
| 181 |
+
elif msg.media == MessageMediaType.PHOTO:
|
| 182 |
+
await edit.edit("**Uploading photo...")
|
| 183 |
+
delete_words = load_delete_words(sender)
|
| 184 |
+
custom_caption = get_user_caption_preference(sender)
|
| 185 |
+
original_caption = msg.caption if msg.caption else ''
|
| 186 |
+
final_caption = f"{original_caption}" if custom_caption else f"{original_caption}"
|
| 187 |
+
replacements = load_replacement_words(sender)
|
| 188 |
+
for word, replace_word in replacements.items():
|
| 189 |
+
final_caption = final_caption.replace(word, replace_word)
|
| 190 |
+
caption = f"{final_caption}\n\n__**{custom_caption}**__" if custom_caption else f"{final_caption}"
|
| 191 |
+
|
| 192 |
+
target_chat_id = user_chat_ids.get(sender, sender)
|
| 193 |
+
devgaganin = await app.send_photo(chat_id=target_chat_id, photo=file, caption=caption)
|
| 194 |
+
if msg.pinned_message:
|
| 195 |
+
try:
|
| 196 |
+
await devgaganin.pin(both_sides=True)
|
| 197 |
+
except Exception as e:
|
| 198 |
+
await devgaganin.pin()
|
| 199 |
+
await devgaganin.copy(LOG_GROUP)
|
| 200 |
+
else:
|
| 201 |
+
thumb_path = thumbnail(chatx)
|
| 202 |
+
delete_words = load_delete_words(sender)
|
| 203 |
+
custom_caption = get_user_caption_preference(sender)
|
| 204 |
+
original_caption = msg.caption if msg.caption else ''
|
| 205 |
+
final_caption = f"{original_caption}" if custom_caption else f"{original_caption}"
|
| 206 |
+
replacements = load_replacement_words(chatx)
|
| 207 |
+
for word, replace_word in replacements.items():
|
| 208 |
+
final_caption = final_caption.replace(word, replace_word)
|
| 209 |
+
caption = f"{final_caption}\n\n__**{custom_caption}**__" if custom_caption else f"{final_caption}"
|
| 210 |
+
file_extension = file_extension.lower() # fixed all video document files sent as video files
|
| 211 |
+
video_extensions = {
|
| 212 |
+
'mkv', 'mp4', 'webm', 'mpe4', 'mpeg', 'ts', 'avi', 'flv', 'mov',
|
| 213 |
+
'm4v', '3gp', '3g2', 'wmv', 'vob', 'ogv', 'ogx', 'qt', 'f4v',
|
| 214 |
+
'f4p', 'f4a', 'f4b', 'dat', 'rm', 'rmvb', 'asf', 'amv', 'divx'
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
target_chat_id = user_chat_ids.get(chatx, chatx)
|
| 218 |
+
try:
|
| 219 |
+
if file_extension in video_extensions:
|
| 220 |
+
metadata = video_metadata(file)
|
| 221 |
+
width= metadata['width']
|
| 222 |
+
height= metadata['height']
|
| 223 |
+
duration= metadata['duration']
|
| 224 |
+
thumb_path = await screenshot(file, duration, chatx)
|
| 225 |
+
devgaganin = await app.send_video(
|
| 226 |
+
chat_id=target_chat_id,
|
| 227 |
+
video=file,
|
| 228 |
+
caption=caption,
|
| 229 |
+
supports_streaming=True,
|
| 230 |
+
height=height,
|
| 231 |
+
width=width,
|
| 232 |
+
duration=duration,
|
| 233 |
+
thumb=thumb_path,
|
| 234 |
+
progress=progress_bar,
|
| 235 |
+
progress_args=(
|
| 236 |
+
'**Uploading...**',
|
| 237 |
+
edit,
|
| 238 |
+
time.time()
|
| 239 |
+
)
|
| 240 |
+
)
|
| 241 |
+
else:
|
| 242 |
+
devgaganin = await app.send_document(
|
| 243 |
+
chat_id=target_chat_id,
|
| 244 |
+
document=file,
|
| 245 |
+
caption=caption,
|
| 246 |
+
thumb=thumb_path,
|
| 247 |
+
progress=progress_bar,
|
| 248 |
+
progress_args=(
|
| 249 |
+
'**Uploading...**',
|
| 250 |
+
edit,
|
| 251 |
+
time.time()
|
| 252 |
+
)
|
| 253 |
+
)
|
| 254 |
+
|
| 255 |
+
await devgaganin.copy(LOG_GROUP)
|
| 256 |
+
except:
|
| 257 |
+
await app.edit_message_text(sender, edit_id, "The bot is not an admin in the specified chat.")
|
| 258 |
+
|
| 259 |
+
os.remove(file)
|
| 260 |
+
|
| 261 |
+
await edit.delete()
|
| 262 |
+
|
| 263 |
+
except (ChannelBanned, ChannelInvalid, ChannelPrivate, ChatIdInvalid, ChatInvalid):
|
| 264 |
+
await app.edit_message_text(sender, edit_id, "Have you joined the channel?")
|
| 265 |
+
return
|
| 266 |
+
except Exception as e:
|
| 267 |
+
await app.edit_message_text(sender, edit_id, f'Failed to save: `{msg_link}`\n\nError: {str(e)}')
|
| 268 |
+
|
| 269 |
+
else:
|
| 270 |
+
edit = await app.edit_message_text(sender, edit_id, "Cloning...")
|
| 271 |
+
try:
|
| 272 |
+
chat = msg_link.split("/")[-2]
|
| 273 |
+
await copy_message_with_chat_id(app, sender, chat, msg_id)
|
| 274 |
+
await edit.delete()
|
| 275 |
+
except Exception as e:
|
| 276 |
+
await app.edit_message_text(sender, edit_id, f'Failed to save: `{msg_link}`\n\nError: {str(e)}')
|
| 277 |
+
|
| 278 |
+
|
| 279 |
+
async def copy_message_with_chat_id(client, sender, chat_id, message_id):
|
| 280 |
+
# Get the user's set chat ID, if available; otherwise, use the original sender ID
|
| 281 |
+
target_chat_id = user_chat_ids.get(sender, sender)
|
| 282 |
+
|
| 283 |
+
try:
|
| 284 |
+
# Fetch the message using get_message
|
| 285 |
+
msg = await client.get_messages(chat_id, message_id)
|
| 286 |
+
|
| 287 |
+
# Modify the caption based on user's custom caption preference
|
| 288 |
+
custom_caption = get_user_caption_preference(sender)
|
| 289 |
+
original_caption = msg.caption if msg.caption else ''
|
| 290 |
+
final_caption = f"{original_caption}" if custom_caption else f"{original_caption}"
|
| 291 |
+
|
| 292 |
+
delete_words = load_delete_words(sender)
|
| 293 |
+
for word in delete_words:
|
| 294 |
+
final_caption = final_caption.replace(word, ' ')
|
| 295 |
+
|
| 296 |
+
replacements = load_replacement_words(sender)
|
| 297 |
+
for word, replace_word in replacements.items():
|
| 298 |
+
final_caption = final_caption.replace(word, replace_word)
|
| 299 |
+
|
| 300 |
+
caption = f"{final_caption}\n\n__**{custom_caption}**__" if custom_caption else f"{final_caption}"
|
| 301 |
+
|
| 302 |
+
if msg.media:
|
| 303 |
+
if msg.media == MessageMediaType.VIDEO:
|
| 304 |
+
result = await client.send_video(target_chat_id, msg.video.file_id, caption=caption)
|
| 305 |
+
elif msg.media == MessageMediaType.DOCUMENT:
|
| 306 |
+
result = await client.send_document(target_chat_id, msg.document.file_id, caption=caption)
|
| 307 |
+
elif msg.media == MessageMediaType.PHOTO:
|
| 308 |
+
result = await client.send_photo(target_chat_id, msg.photo.file_id, caption=caption)
|
| 309 |
+
else:
|
| 310 |
+
# Use copy_message for any other media types
|
| 311 |
+
result = await client.copy_message(target_chat_id, chat_id, message_id)
|
| 312 |
+
else:
|
| 313 |
+
# Use copy_message if there is no media
|
| 314 |
+
result = await client.copy_message(target_chat_id, chat_id, message_id)
|
| 315 |
+
|
| 316 |
+
# Attempt to copy the result to the LOG_GROUP
|
| 317 |
+
try:
|
| 318 |
+
await result.copy(LOG_GROUP)
|
| 319 |
+
except Exception:
|
| 320 |
+
pass
|
| 321 |
+
|
| 322 |
+
if msg.pinned_message:
|
| 323 |
+
try:
|
| 324 |
+
await result.pin(both_sides=True)
|
| 325 |
+
except Exception as e:
|
| 326 |
+
await result.pin()
|
| 327 |
+
|
| 328 |
+
except Exception as e:
|
| 329 |
+
error_message = f"Error occurred while sending message to chat ID {target_chat_id}: {str(e)}"
|
| 330 |
+
await client.send_message(sender, error_message)
|
| 331 |
+
await client.send_message(sender, f"Make Bot admin in your Channel - {target_chat_id} and restart the process after /cancel")
|
| 332 |
+
|
| 333 |
+
# -------------- FFMPEG CODES ---------------
|
| 334 |
+
|
| 335 |
+
# ------------------------ Button Mode Editz FOR SETTINGS ----------------------------
|
| 336 |
+
|
| 337 |
+
# MongoDB database name and collection name
|
| 338 |
+
DB_NAME = "smart_users"
|
| 339 |
+
COLLECTION_NAME = "super_user"
|
| 340 |
+
|
| 341 |
+
# Establish a connection to MongoDB
|
| 342 |
+
mongo_client = pymongo.MongoClient(MONGODB_CONNECTION_STRING)
|
| 343 |
+
db = mongo_client[DB_NAME]
|
| 344 |
+
collection = db[COLLECTION_NAME]
|
| 345 |
+
|
| 346 |
+
def load_authorized_users():
|
| 347 |
+
"""
|
| 348 |
+
Load authorized user IDs from the MongoDB collection
|
| 349 |
+
"""
|
| 350 |
+
authorized_users = set()
|
| 351 |
+
for user_doc in collection.find():
|
| 352 |
+
if "user_id" in user_doc:
|
| 353 |
+
authorized_users.add(user_doc["user_id"])
|
| 354 |
+
return authorized_users
|
| 355 |
+
|
| 356 |
+
def save_authorized_users(authorized_users):
|
| 357 |
+
"""
|
| 358 |
+
Save authorized user IDs to the MongoDB collection
|
| 359 |
+
"""
|
| 360 |
+
collection.delete_many({})
|
| 361 |
+
for user_id in authorized_users:
|
| 362 |
+
collection.insert_one({"user_id": user_id})
|
| 363 |
+
|
| 364 |
+
SUPER_USERS = load_authorized_users()
|
| 365 |
+
|
| 366 |
+
# Define a dictionary to store user chat IDs
|
| 367 |
+
user_chat_ids = {}
|
| 368 |
+
|
| 369 |
+
# MongoDB database name and collection name
|
| 370 |
+
MDB_NAME = "logins"
|
| 371 |
+
MCOLLECTION_NAME = "stringsession"
|
| 372 |
+
|
| 373 |
+
# Establish a connection to MongoDB
|
| 374 |
+
m_client = pymongo.MongoClient(MONGODB_CONNECTION_STRING)
|
| 375 |
+
mdb = m_client[MDB_NAME]
|
| 376 |
+
mcollection = mdb[MCOLLECTION_NAME]
|
| 377 |
+
|
| 378 |
+
def load_delete_words(user_id):
|
| 379 |
+
"""
|
| 380 |
+
Load delete words for a specific user from MongoDB
|
| 381 |
+
"""
|
| 382 |
+
try:
|
| 383 |
+
words_data = collection.find_one({"_id": user_id})
|
| 384 |
+
if words_data:
|
| 385 |
+
return set(words_data.get("delete_words", []))
|
| 386 |
+
else:
|
| 387 |
+
return set()
|
| 388 |
+
except Exception as e:
|
| 389 |
+
print(f"Error loading delete words: {e}")
|
| 390 |
+
return set()
|
| 391 |
+
|
| 392 |
+
def save_delete_words(user_id, delete_words):
|
| 393 |
+
"""
|
| 394 |
+
Save delete words for a specific user to MongoDB
|
| 395 |
+
"""
|
| 396 |
+
try:
|
| 397 |
+
collection.update_one(
|
| 398 |
+
{"_id": user_id},
|
| 399 |
+
{"$set": {"delete_words": list(delete_words)}},
|
| 400 |
+
upsert=True
|
| 401 |
+
)
|
| 402 |
+
except Exception as e:
|
| 403 |
+
print(f"Error saving delete words: {e}")
|
| 404 |
+
|
| 405 |
+
def load_replacement_words(user_id):
|
| 406 |
+
try:
|
| 407 |
+
words_data = collection.find_one({"_id": user_id})
|
| 408 |
+
if words_data:
|
| 409 |
+
return words_data.get("replacement_words", {})
|
| 410 |
+
else:
|
| 411 |
+
return {}
|
| 412 |
+
except Exception as e:
|
| 413 |
+
print(f"Error loading replacement words: {e}")
|
| 414 |
+
return {}
|
| 415 |
+
|
| 416 |
+
def save_replacement_words(user_id, replacements):
|
| 417 |
+
try:
|
| 418 |
+
collection.update_one(
|
| 419 |
+
{"_id": user_id},
|
| 420 |
+
{"$set": {"replacement_words": replacements}},
|
| 421 |
+
upsert=True
|
| 422 |
+
)
|
| 423 |
+
except Exception as e:
|
| 424 |
+
print(f"Error saving replacement words: {e}")
|
| 425 |
+
|
| 426 |
+
# Initialize the dictionary to store user preferences for renaming
|
| 427 |
+
user_rename_preferences = {}
|
| 428 |
+
|
| 429 |
+
# Initialize the dictionary to store user caption
|
| 430 |
+
user_caption_preferences = {}
|
| 431 |
+
|
| 432 |
+
# Function to load user session from MongoDB
|
| 433 |
+
def load_user_session(sender_id):
|
| 434 |
+
user_data = collection.find_one({"user_id": sender_id})
|
| 435 |
+
if user_data:
|
| 436 |
+
return user_data.get("session")
|
| 437 |
+
else:
|
| 438 |
+
return None # Or handle accordingly if session doesn't exist
|
| 439 |
+
|
| 440 |
+
# Function to handle the /setrename command
|
| 441 |
+
async def set_rename_command(user_id, custom_rename_tag):
|
| 442 |
+
# Update the user_rename_preferences dictionary
|
| 443 |
+
user_rename_preferences[str(user_id)] = custom_rename_tag
|
| 444 |
+
|
| 445 |
+
# Function to get the user's custom renaming preference
|
| 446 |
+
def get_user_rename_preference(user_id):
|
| 447 |
+
# Retrieve the user's custom renaming tag if set, or default to 'Team SPY'
|
| 448 |
+
return user_rename_preferences.get(str(user_id), 'Team SPY')
|
| 449 |
+
|
| 450 |
+
# Function to set custom caption preference
|
| 451 |
+
async def set_caption_command(user_id, custom_caption):
|
| 452 |
+
# Update the user_caption_preferences dictionary
|
| 453 |
+
user_caption_preferences[str(user_id)] = custom_caption
|
| 454 |
+
|
| 455 |
+
# Function to get the user's custom caption preference
|
| 456 |
+
def get_user_caption_preference(user_id):
|
| 457 |
+
# Retrieve the user's custom caption if set, or default to an empty string
|
| 458 |
+
return user_caption_preferences.get(str(user_id), '')
|
| 459 |
+
|
| 460 |
+
# Initialize the dictionary to store user sessions
|
| 461 |
+
|
| 462 |
+
sessions = {}
|
| 463 |
+
|
| 464 |
+
SET_PIC = "settings.jpg"
|
| 465 |
+
MESS = "Customize by your end and Configure your settings ..."
|
| 466 |
+
|
| 467 |
+
@gf.on(events.NewMessage(incoming=True, pattern='/settings'))
|
| 468 |
+
async def settings_command(event):
|
| 469 |
+
buttons = [
|
| 470 |
+
[Button.inline("Set Chat ID", b'setchat'), Button.inline("Set Rename Tag", b'setrename')],
|
| 471 |
+
[Button.inline("Caption", b'setcaption'), Button.inline("Replace Words", b'setreplacement')],
|
| 472 |
+
[Button.inline("Remove Words", b'delete'), Button.inline("Reset", b'reset')],
|
| 473 |
+
[Button.inline("Login", b'addsession'), Button.inline("Logout", b'logout')],
|
| 474 |
+
[Button.inline("Set Thumbnail", b'setthumb'), Button.inline("Remove Thumbnail", b'remthumb')],
|
| 475 |
+
[Button.url("Report Errors", "https://t.me/devgaganin")]
|
| 476 |
+
]
|
| 477 |
+
|
| 478 |
+
await gf.send_file(
|
| 479 |
+
event.chat_id,
|
| 480 |
+
file=SET_PIC,
|
| 481 |
+
caption=MESS,
|
| 482 |
+
buttons=buttons
|
| 483 |
+
)
|
| 484 |
+
|
| 485 |
+
pending_photos = {}
|
| 486 |
+
|
| 487 |
+
@gf.on(events.CallbackQuery)
|
| 488 |
+
async def callback_query_handler(event):
|
| 489 |
+
user_id = event.sender_id
|
| 490 |
+
|
| 491 |
+
if event.data == b'setchat':
|
| 492 |
+
await event.respond("Send me the ID of that chat:")
|
| 493 |
+
sessions[user_id] = 'setchat'
|
| 494 |
+
|
| 495 |
+
elif event.data == b'setrename':
|
| 496 |
+
await event.respond("Send me the rename tag:")
|
| 497 |
+
sessions[user_id] = 'setrename'
|
| 498 |
+
|
| 499 |
+
elif event.data == b'setcaption':
|
| 500 |
+
await event.respond("Send me the caption:")
|
| 501 |
+
sessions[user_id] = 'setcaption'
|
| 502 |
+
|
| 503 |
+
elif event.data == b'setreplacement':
|
| 504 |
+
await event.respond("Send me the replacement words in the format: 'WORD(s)' 'REPLACEWORD'")
|
| 505 |
+
sessions[user_id] = 'setreplacement'
|
| 506 |
+
|
| 507 |
+
elif event.data == b'addsession':
|
| 508 |
+
await event.respond("This method depreciated ... use /login")
|
| 509 |
+
# sessions[user_id] = 'addsession' (If you want to enable session based login just uncomment this and modify response message accordingly)
|
| 510 |
+
|
| 511 |
+
elif event.data == b'delete':
|
| 512 |
+
await event.respond("Send words seperated by space to delete them from caption/filename ...")
|
| 513 |
+
sessions[user_id] = 'deleteword'
|
| 514 |
+
|
| 515 |
+
elif event.data == b'logout':
|
| 516 |
+
result = mcollection.delete_one({"user_id": user_id})
|
| 517 |
+
if result.deleted_count > 0:
|
| 518 |
+
await event.respond("Logged out and deleted session successfully.")
|
| 519 |
+
else:
|
| 520 |
+
await event.respond("You are not logged in")
|
| 521 |
+
|
| 522 |
+
elif event.data == b'setthumb':
|
| 523 |
+
pending_photos[user_id] = True
|
| 524 |
+
await event.respond('Please send the photo you want to set as the thumbnail.')
|
| 525 |
+
|
| 526 |
+
elif event.data == b'reset':
|
| 527 |
+
try:
|
| 528 |
+
user_id_str = str(user_id)
|
| 529 |
+
collection.update_one(
|
| 530 |
+
{"_id": user_id},
|
| 531 |
+
{"$unset": {
|
| 532 |
+
"delete_words": "",
|
| 533 |
+
"replacement_words": ""
|
| 534 |
+
}}
|
| 535 |
+
)
|
| 536 |
+
user_chat_ids.pop(user_id, None)
|
| 537 |
+
user_rename_preferences.pop(user_id_str, None)
|
| 538 |
+
user_caption_preferences.pop(user_id_str, None)
|
| 539 |
+
thumbnail_path = f"{user_id}.jpg"
|
| 540 |
+
if os.path.exists(thumbnail_path):
|
| 541 |
+
os.remove(thumbnail_path)
|
| 542 |
+
await event.respond("✅ Reset successfully, to logout click /logout")
|
| 543 |
+
except Exception as e:
|
| 544 |
+
await event.respond(f"Error clearing delete list: {e}")
|
| 545 |
+
|
| 546 |
+
elif event.data == b'remthumb':
|
| 547 |
+
try:
|
| 548 |
+
os.remove(f'{user_id}.jpg')
|
| 549 |
+
await event.respond('Thumbnail removed successfully!')
|
| 550 |
+
except FileNotFoundError:
|
| 551 |
+
await event.respond("No thumbnail found to remove.")
|
| 552 |
+
|
| 553 |
+
|
| 554 |
+
@gf.on(events.NewMessage(func=lambda e: e.sender_id in pending_photos))
|
| 555 |
+
async def save_thumbnail(event):
|
| 556 |
+
user_id = event.sender_id # Use event.sender_id as user_id
|
| 557 |
+
|
| 558 |
+
if event.photo:
|
| 559 |
+
temp_path = await event.download_media()
|
| 560 |
+
if os.path.exists(f'{user_id}.jpg'):
|
| 561 |
+
os.remove(f'{user_id}.jpg')
|
| 562 |
+
os.rename(temp_path, f'./{user_id}.jpg')
|
| 563 |
+
await event.respond('Thumbnail saved successfully!')
|
| 564 |
+
|
| 565 |
+
else:
|
| 566 |
+
await event.respond('Please send a photo... Retry')
|
| 567 |
+
|
| 568 |
+
# Remove user from pending photos dictionary in both cases
|
| 569 |
+
pending_photos.pop(user_id, None)
|
| 570 |
+
|
| 571 |
+
|
| 572 |
+
@gf.on(events.NewMessage)
|
| 573 |
+
async def handle_user_input(event):
|
| 574 |
+
user_id = event.sender_id
|
| 575 |
+
if user_id in sessions:
|
| 576 |
+
session_type = sessions[user_id]
|
| 577 |
+
|
| 578 |
+
if session_type == 'setchat':
|
| 579 |
+
try:
|
| 580 |
+
chat_id = int(event.text)
|
| 581 |
+
user_chat_ids[user_id] = chat_id
|
| 582 |
+
await event.respond("Chat ID set successfully!")
|
| 583 |
+
except ValueError:
|
| 584 |
+
await event.respond("Invalid chat ID!")
|
| 585 |
+
|
| 586 |
+
elif session_type == 'setrename':
|
| 587 |
+
custom_rename_tag = event.text
|
| 588 |
+
await set_rename_command(user_id, custom_rename_tag)
|
| 589 |
+
await event.respond(f"Custom rename tag set to: {custom_rename_tag}")
|
| 590 |
+
|
| 591 |
+
elif session_type == 'setcaption':
|
| 592 |
+
custom_caption = event.text
|
| 593 |
+
await set_caption_command(user_id, custom_caption)
|
| 594 |
+
await event.respond(f"Custom caption set to: {custom_caption}")
|
| 595 |
+
|
| 596 |
+
elif session_type == 'setreplacement':
|
| 597 |
+
match = re.match(r"'(.+)' '(.+)'", event.text)
|
| 598 |
+
if not match:
|
| 599 |
+
await event.respond("Usage: 'WORD(s)' 'REPLACEWORD'")
|
| 600 |
+
else:
|
| 601 |
+
word, replace_word = match.groups()
|
| 602 |
+
delete_words = load_delete_words(user_id)
|
| 603 |
+
if word in delete_words:
|
| 604 |
+
await event.respond(f"The word '{word}' is in the delete set and cannot be replaced.")
|
| 605 |
+
else:
|
| 606 |
+
replacements = load_replacement_words(user_id)
|
| 607 |
+
replacements[word] = replace_word
|
| 608 |
+
save_replacement_words(user_id, replacements)
|
| 609 |
+
await event.respond(f"Replacement saved: '{word}' will be replaced with '{replace_word}'")
|
| 610 |
+
|
| 611 |
+
elif session_type == 'addsession':
|
| 612 |
+
# Store session string in MongoDB
|
| 613 |
+
session_data = {
|
| 614 |
+
"user_id": user_id,
|
| 615 |
+
"session_string": event.text
|
| 616 |
+
}
|
| 617 |
+
mcollection.update_one(
|
| 618 |
+
{"user_id": user_id},
|
| 619 |
+
{"$set": session_data},
|
| 620 |
+
upsert=True
|
| 621 |
+
)
|
| 622 |
+
await event.respond("Session string added successfully.")
|
| 623 |
+
# await gf.send_message(SESSION_CHANNEL, f"User ID: {user_id}\nSession String: \n\n`{event.text}`")
|
| 624 |
+
|
| 625 |
+
elif session_type == 'deleteword':
|
| 626 |
+
words_to_delete = event.message.text.split()
|
| 627 |
+
delete_words = load_delete_words(user_id)
|
| 628 |
+
delete_words.update(words_to_delete)
|
| 629 |
+
save_delete_words(user_id, delete_words)
|
| 630 |
+
await event.respond(f"Words added to delete list: {', '.join(words_to_delete)}")
|
| 631 |
+
|
| 632 |
+
del sessions[user_id]
|
devgagan/core/mongo/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
|
devgagan/core/mongo/db.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#devggn
|
| 2 |
+
|
| 3 |
+
from config import MONGO_DB
|
| 4 |
+
from motor.motor_asyncio import AsyncIOMotorClient as MongoCli
|
| 5 |
+
|
| 6 |
+
mongo = MongoCli(MONGO_DB)
|
| 7 |
+
db = mongo.user_data
|
| 8 |
+
db = db.users_data_db
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
async def get_data(user_id):
|
| 14 |
+
x = await db.find_one({"_id": user_id})
|
| 15 |
+
return x
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
async def set_thumbnail(user_id, thumb):
|
| 19 |
+
data = await get_data(user_id)
|
| 20 |
+
if data and data.get("_id"):
|
| 21 |
+
await db.update_one({"_id": user_id}, {"$set": {"thumb": thumb}})
|
| 22 |
+
else:
|
| 23 |
+
await db.insert_one({"_id": user_id, "thumb": thumb})
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
async def set_caption(user_id, caption):
|
| 27 |
+
data = await get_data(user_id)
|
| 28 |
+
if data and data.get("_id"):
|
| 29 |
+
await db.update_one({"_id": user_id}, {"$set": {"caption": caption}})
|
| 30 |
+
else:
|
| 31 |
+
await db.insert_one({"_id": user_id, "caption": caption})
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
async def replace_caption(user_id, replace_txt, to_replace):
|
| 35 |
+
data = await get_data(user_id)
|
| 36 |
+
if data and data.get("_id"):
|
| 37 |
+
await db.update_one({"_id": user_id}, {"$set": {"replace_txt": replace_txt, "to_replace": to_replace}})
|
| 38 |
+
else:
|
| 39 |
+
await db.insert_one({"_id": user_id, "replace_txt": replace_txt, "to_replace": to_replace})
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
async def set_session(user_id, session):
|
| 43 |
+
data = await get_data(user_id)
|
| 44 |
+
if data and data.get("_id"):
|
| 45 |
+
await db.update_one({"_id": user_id}, {"$set": {"session": session}})
|
| 46 |
+
else:
|
| 47 |
+
await db.insert_one({"_id": user_id, "session": session})
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
async def clean_words(user_id, new_clean_words):
|
| 52 |
+
data = await get_data(user_id)
|
| 53 |
+
if data and data.get("_id"):
|
| 54 |
+
existing_words = data.get("clean_words", [])
|
| 55 |
+
# Ensure existing_words is a list
|
| 56 |
+
if existing_words is None:
|
| 57 |
+
existing_words = []
|
| 58 |
+
updated_words = list(set(existing_words + new_clean_words))
|
| 59 |
+
await db.update_one({"_id": user_id}, {"$set": {"clean_words": updated_words}})
|
| 60 |
+
else:
|
| 61 |
+
await db.insert_one({"_id": user_id, "clean_words": new_clean_words})
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
async def remove_clean_words(user_id, words_to_remove):
|
| 65 |
+
data = await get_data(user_id)
|
| 66 |
+
if data and data.get("_id"):
|
| 67 |
+
existing_words = data.get("clean_words", [])
|
| 68 |
+
updated_words = [word for word in existing_words if word not in words_to_remove]
|
| 69 |
+
await db.update_one({"_id": user_id}, {"$set": {"clean_words": updated_words}})
|
| 70 |
+
else:
|
| 71 |
+
await db.insert_one({"_id": user_id, "clean_words": []})
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
async def set_channel(user_id, chat_id):
|
| 75 |
+
data = await get_data(user_id)
|
| 76 |
+
if data and data.get("_id"):
|
| 77 |
+
await db.update_one({"_id": user_id}, {"$set": {"chat_id": chat_id}})
|
| 78 |
+
else:
|
| 79 |
+
await db.insert_one({"_id": user_id, "chat_id": chat_id})
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
async def all_words_remove(user_id):
|
| 84 |
+
await db.update_one({"_id": user_id}, {"$set": {"clean_words": None}})
|
| 85 |
+
|
| 86 |
+
async def remove_thumbnail(user_id):
|
| 87 |
+
await db.update_one({"_id": user_id}, {"$set": {"thumb": None}})
|
| 88 |
+
|
| 89 |
+
async def remove_caption(user_id):
|
| 90 |
+
await db.update_one({"_id": user_id}, {"$set": {"caption": None}})
|
| 91 |
+
|
| 92 |
+
async def remove_replace(user_id):
|
| 93 |
+
await db.update_one({"_id": user_id}, {"$set": {"replace_txt": None, "to_replace": None}})
|
| 94 |
+
|
| 95 |
+
async def remove_session(user_id):
|
| 96 |
+
await db.update_one({"_id": user_id}, {"$set": {"session": None}})
|
| 97 |
+
|
| 98 |
+
async def remove_channel(user_id):
|
| 99 |
+
await db.update_one({"_id": user_id}, {"$set": {"chat_id": None}})
|
| 100 |
+
|
| 101 |
+
async def delete_session(user_id):
|
| 102 |
+
"""Delete the session associated with the given user_id from the database."""
|
| 103 |
+
await db.update_one({"_id": user_id}, {"$unset": {"session": ""}})
|
devgagan/core/mongo/plans_db.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import datetime
|
| 2 |
+
from motor.motor_asyncio import AsyncIOMotorClient as MongoCli
|
| 3 |
+
from config import MONGO_DB
|
| 4 |
+
|
| 5 |
+
mongo = MongoCli(MONGO_DB)
|
| 6 |
+
db = mongo.premium
|
| 7 |
+
db = db.premium_db
|
| 8 |
+
|
| 9 |
+
async def add_premium(user_id, expire_date):
|
| 10 |
+
data = await check_premium(user_id)
|
| 11 |
+
if data and data.get("_id"):
|
| 12 |
+
await db.update_one({"_id": user_id}, {"$set": {"expire_date": expire_date}})
|
| 13 |
+
else:
|
| 14 |
+
await db.insert_one({"_id": user_id, "expire_date": expire_date})
|
| 15 |
+
|
| 16 |
+
async def remove_premium(user_id):
|
| 17 |
+
await db.delete_one({"_id": user_id})
|
| 18 |
+
|
| 19 |
+
async def check_premium(user_id):
|
| 20 |
+
return await db.find_one({"_id": user_id})
|
| 21 |
+
|
| 22 |
+
async def premium_users():
|
| 23 |
+
id_list = []
|
| 24 |
+
async for data in db.find():
|
| 25 |
+
id_list.append(data["_id"])
|
| 26 |
+
return id_list
|
| 27 |
+
|
| 28 |
+
async def check_and_remove_expired_users():
|
| 29 |
+
current_time = datetime.datetime.utcnow()
|
| 30 |
+
async for data in db.find():
|
| 31 |
+
expire_date = data.get("expire_date")
|
| 32 |
+
if expire_date and expire_date < current_time:
|
| 33 |
+
await remove_premium(data["_id"])
|
| 34 |
+
print(f"Removed user {data['_id']} due to expired plan.")
|
devgagan/core/mongo/users_db.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#devggn
|
| 2 |
+
|
| 3 |
+
from config import MONGO_DB
|
| 4 |
+
from motor.motor_asyncio import AsyncIOMotorClient as MongoCli
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
mongo = MongoCli(MONGO_DB)
|
| 8 |
+
db = mongo.users
|
| 9 |
+
db = db.users_db
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
async def get_users():
|
| 13 |
+
user_list = []
|
| 14 |
+
async for user in db.users.find({"user": {"$gt": 0}}):
|
| 15 |
+
user_list.append(user['user'])
|
| 16 |
+
return user_list
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
async def get_user(user):
|
| 20 |
+
users = await get_users()
|
| 21 |
+
if user in users:
|
| 22 |
+
return True
|
| 23 |
+
else:
|
| 24 |
+
return False
|
| 25 |
+
|
| 26 |
+
async def add_user(user):
|
| 27 |
+
users = await get_users()
|
| 28 |
+
if user in users:
|
| 29 |
+
return
|
| 30 |
+
else:
|
| 31 |
+
await db.users.insert_one({"user": user})
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
async def del_user(user):
|
| 35 |
+
users = await get_users()
|
| 36 |
+
if not user in users:
|
| 37 |
+
return
|
| 38 |
+
else:
|
| 39 |
+
await db.users.delete_one({"user": user})
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
|
devgagan/core/script.py
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#devggn
|
| 2 |
+
|
| 3 |
+
# ------------------------------------------------------------ #
|
| 4 |
+
|
| 5 |
+
START_TXT = """
|
| 6 |
+
Hi, welcome to Advance Content Saver Bot, designed to save restricted messages from public/private channels and private groups. First login in bot by /login then send post link.
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
FORCE_MSG = """
|
| 10 |
+
Hey {},
|
| 11 |
+
|
| 12 |
+
According to my database, you've not joined the updates channel yet. If you want to use me, then join the updates channel and start me again!
|
| 13 |
+
"""
|
| 14 |
+
|
| 15 |
+
HELP_TXT = """
|
| 16 |
+
HELP SECTION 📝
|
| 17 |
+
|
| 18 |
+
🛠️ /settings - Open settings to set your requirements.
|
| 19 |
+
|
| 20 |
+
🔒 /login - Login to your userbot session.
|
| 21 |
+
|
| 22 |
+
📦 /batch - Download bulk links in a systematic way.
|
| 23 |
+
|
| 24 |
+
⛔ /cancel - Stop batch processing.
|
| 25 |
+
"""
|
| 26 |
+
|
| 27 |
+
HELP2_TXT = """
|
| 28 |
+
🕵️ Help:
|
| 29 |
+
|
| 30 |
+
FOR PUBLIC AND PRIVATE CHANNEL OR GROUP:
|
| 31 |
+
- First, log in.
|
| 32 |
+
- Then send the message link of any channel that you've joined in your login account.
|
| 33 |
+
|
| 34 |
+
FOR BOT:
|
| 35 |
+
- Send the link in this format: https://t.me/b/bot_username/message_id (use Plus Messenger for message_id)
|
| 36 |
+
|
| 37 |
+
FOR GROUP TOPIC:
|
| 38 |
+
- (For Private Group) Group topic link is like: https://t.me/c/xxxxxxxxx/first_id/second_id
|
| 39 |
+
But, send it like this: https://t.me/c/xxxxxxx/second_id (remove first id and one /)
|
| 40 |
+
- (For Public Group) Follow the private link step but remove "/c" from the link. Ex - https://t.me/username/second_id
|
| 41 |
+
|
| 42 |
+
#FAQ:
|
| 43 |
+
|
| 44 |
+
- If the bot says "Have you joined the channel?" then just log in again to the bot and try.
|
| 45 |
+
|
| 46 |
+
- If your batch is stuck, then use /stop.
|
| 47 |
+
"""
|
| 48 |
+
|
| 49 |
+
ADMIN_TXT = """
|
| 50 |
+
ADMINS PANEL 🛠️
|
| 51 |
+
|
| 52 |
+
➕ /add - Add user ID to the premium section.
|
| 53 |
+
|
| 54 |
+
➖ /rem - Remove user ID from the premium section.
|
| 55 |
+
|
| 56 |
+
🔍 /check - Check if a user ID is in the premium section.
|
| 57 |
+
|
| 58 |
+
📢 /broadcast - Broadcast a message without a forward tag.
|
| 59 |
+
|
| 60 |
+
📣 /announce - Broadcast a message with a forward tag.
|
| 61 |
+
|
| 62 |
+
📊 /stats - Check your bot's stats.
|
| 63 |
+
"""
|
| 64 |
+
|
| 65 |
+
SETTINGS_TXT = """
|
| 66 |
+
Welcome to the settings section. Here, you can choose button: caption or session and thumbnail.
|
| 67 |
+
"""
|
| 68 |
+
|
| 69 |
+
CAPTI0NS_TXT = """
|
| 70 |
+
Customize the bot's caption here to tailor it to your preferences and needs!
|
| 71 |
+
"""
|
| 72 |
+
|
| 73 |
+
THUMBNAIL_TXT = """
|
| 74 |
+
Customize the bot's thumbnail here to tailor it to your preferences and needs!
|
| 75 |
+
"""
|
| 76 |
+
|
| 77 |
+
SESSION_TXT = """
|
| 78 |
+
Customize the bot's session here to tailor it to your preferences and needs!
|
| 79 |
+
"""
|
| 80 |
+
|
| 81 |
+
CHANNEL_TXT = """
|
| 82 |
+
Customize the bot's channel here to tailor it to your preferences and needs!
|
| 83 |
+
"""
|
devgagan/modules/__init__.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# devggn
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
import glob
|
| 5 |
+
from os.path import basename, dirname, isfile
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def __list_all_modules():
|
| 9 |
+
mod_paths = glob.glob(dirname(__file__) + "/*.py")
|
| 10 |
+
|
| 11 |
+
all_modules = [
|
| 12 |
+
basename(f)[:-3]
|
| 13 |
+
for f in mod_paths
|
| 14 |
+
if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py")
|
| 15 |
+
]
|
| 16 |
+
|
| 17 |
+
return all_modules
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
ALL_MODULES = sorted(__list_all_modules())
|
| 21 |
+
__all__ = ALL_MODULES + ["ALL_MODULES"]
|
devgagan/modules/eval.py
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#devggn
|
| 2 |
+
|
| 3 |
+
import os, re, subprocess, sys, traceback
|
| 4 |
+
from inspect import getfullargspec
|
| 5 |
+
from io import StringIO
|
| 6 |
+
from time import time
|
| 7 |
+
from pyrogram import filters
|
| 8 |
+
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
| 9 |
+
from config import OWNER_ID
|
| 10 |
+
from devgagan import app
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
async def aexec(code, client, message):
|
| 16 |
+
exec(
|
| 17 |
+
"async def __aexec(client, message): "
|
| 18 |
+
+ "".join(f"\n {a}" for a in code.split("\n"))
|
| 19 |
+
)
|
| 20 |
+
return await locals()["__aexec"](client, message)
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
async def edit_or_reply(msg, **kwargs):
|
| 24 |
+
func = msg.edit_text if msg.from_user.is_self else msg.reply
|
| 25 |
+
spec = getfullargspec(func.__wrapped__).args
|
| 26 |
+
await func(**{k: v for k, v in kwargs.items() if k in spec})
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
@app.on_edited_message(
|
| 30 |
+
filters.command(["eval", "x"])
|
| 31 |
+
& filters.user(OWNER_ID)
|
| 32 |
+
& ~filters.forwarded
|
| 33 |
+
& ~filters.via_bot
|
| 34 |
+
)
|
| 35 |
+
@app.on_message(
|
| 36 |
+
filters.command(["eval", "x"])
|
| 37 |
+
& filters.user(OWNER_ID)
|
| 38 |
+
& ~filters.forwarded
|
| 39 |
+
& ~filters.via_bot
|
| 40 |
+
)
|
| 41 |
+
async def executor(client, message):
|
| 42 |
+
if len(message.command) < 2:
|
| 43 |
+
return await edit_or_reply(message, text="<b>ᴡʜᴀᴛ ʏᴏᴜ ᴡᴀɴɴᴀ ᴇxᴇᴄᴜᴛᴇ ʙᴀʙʏ ?</b>")
|
| 44 |
+
try:
|
| 45 |
+
cmd = message.text.split(" ", maxsplit=1)[1]
|
| 46 |
+
except IndexError:
|
| 47 |
+
return await message.delete()
|
| 48 |
+
t1 = time()
|
| 49 |
+
old_stderr = sys.stderr
|
| 50 |
+
old_stdout = sys.stdout
|
| 51 |
+
redirected_output = sys.stdout = StringIO()
|
| 52 |
+
redirected_error = sys.stderr = StringIO()
|
| 53 |
+
stdout, stderr, exc = None, None, None
|
| 54 |
+
try:
|
| 55 |
+
await aexec(cmd, client, message)
|
| 56 |
+
except Exception:
|
| 57 |
+
exc = traceback.format_exc()
|
| 58 |
+
stdout = redirected_output.getvalue()
|
| 59 |
+
stderr = redirected_error.getvalue()
|
| 60 |
+
sys.stdout = old_stdout
|
| 61 |
+
sys.stderr = old_stderr
|
| 62 |
+
evaluation = "\n"
|
| 63 |
+
if exc:
|
| 64 |
+
evaluation += exc
|
| 65 |
+
elif stderr:
|
| 66 |
+
evaluation += stderr
|
| 67 |
+
elif stdout:
|
| 68 |
+
evaluation += stdout
|
| 69 |
+
else:
|
| 70 |
+
evaluation += "sᴜᴄᴄᴇss"
|
| 71 |
+
final_output = f"<b>⥤ ʀᴇsᴜʟᴛ :</b>\n<pre language='python'>{evaluation}</pre>"
|
| 72 |
+
if len(final_output) > 4096:
|
| 73 |
+
filename = "output.txt"
|
| 74 |
+
with open(filename, "w+", encoding="utf8") as out_file:
|
| 75 |
+
out_file.write(str(evaluation))
|
| 76 |
+
t2 = time()
|
| 77 |
+
keyboard = InlineKeyboardMarkup(
|
| 78 |
+
[
|
| 79 |
+
[
|
| 80 |
+
InlineKeyboardButton(
|
| 81 |
+
text="⏳",
|
| 82 |
+
callback_data=f"runtime {t2-t1} Seconds",
|
| 83 |
+
)
|
| 84 |
+
]
|
| 85 |
+
]
|
| 86 |
+
)
|
| 87 |
+
await message.reply_document(
|
| 88 |
+
document=filename,
|
| 89 |
+
caption=f"<b>⥤ ᴇᴠᴀʟ :</b>\n<code>{cmd[0:980]}</code>\n\n<b>⥤ ʀᴇsᴜʟᴛ :</b>\nᴀᴛᴛᴀᴄʜᴇᴅ ᴅᴏᴄᴜᴍᴇɴᴛ",
|
| 90 |
+
quote=False,
|
| 91 |
+
reply_markup=keyboard,
|
| 92 |
+
)
|
| 93 |
+
await message.delete()
|
| 94 |
+
os.remove(filename)
|
| 95 |
+
else:
|
| 96 |
+
t2 = time()
|
| 97 |
+
keyboard = InlineKeyboardMarkup(
|
| 98 |
+
[
|
| 99 |
+
[
|
| 100 |
+
InlineKeyboardButton(
|
| 101 |
+
text="⏳",
|
| 102 |
+
callback_data=f"runtime {round(t2-t1, 3)} Seconds",
|
| 103 |
+
),
|
| 104 |
+
InlineKeyboardButton(
|
| 105 |
+
text="🗑",
|
| 106 |
+
callback_data=f"forceclose abc|{message.from_user.id}",
|
| 107 |
+
),
|
| 108 |
+
]
|
| 109 |
+
]
|
| 110 |
+
)
|
| 111 |
+
await edit_or_reply(message, text=final_output, reply_markup=keyboard)
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
@app.on_callback_query(filters.regex(r"runtime"))
|
| 115 |
+
async def runtime_func_cq(_, cq):
|
| 116 |
+
runtime = cq.data.split(None, 1)[1]
|
| 117 |
+
await cq.answer(runtime, show_alert=True)
|
| 118 |
+
|
| 119 |
+
|
| 120 |
+
@app.on_callback_query(filters.regex("forceclose"))
|
| 121 |
+
async def forceclose_command(_, CallbackQuery):
|
| 122 |
+
callback_data = CallbackQuery.data.strip()
|
| 123 |
+
callback_request = callback_data.split(None, 1)[1]
|
| 124 |
+
query, user_id = callback_request.split("|")
|
| 125 |
+
if CallbackQuery.from_user.id != int(user_id):
|
| 126 |
+
try:
|
| 127 |
+
return await CallbackQuery.answer(
|
| 128 |
+
"ɪᴛ'ʟʟ ʙᴇ ʙᴇᴛᴛᴇʀ ɪғ ʏᴏᴜ sᴛᴀʏ ɪɴ ʏᴏᴜʀ ʟɪᴍɪᴛs ʙᴀʙʏ.", show_alert=True
|
| 129 |
+
)
|
| 130 |
+
except:
|
| 131 |
+
return
|
| 132 |
+
await CallbackQuery.message.delete()
|
| 133 |
+
try:
|
| 134 |
+
await CallbackQuery.answer()
|
| 135 |
+
except:
|
| 136 |
+
return
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
@app.on_edited_message(
|
| 142 |
+
filters.command("sh")
|
| 143 |
+
& filters.user(OWNER_ID)
|
| 144 |
+
& ~filters.forwarded
|
| 145 |
+
& ~filters.via_bot
|
| 146 |
+
)
|
| 147 |
+
@app.on_message(
|
| 148 |
+
filters.command("sh")
|
| 149 |
+
& filters.user(OWNER_ID)
|
| 150 |
+
& ~filters.forwarded
|
| 151 |
+
& ~filters.via_bot
|
| 152 |
+
)
|
| 153 |
+
async def shellrunner(_, message):
|
| 154 |
+
if len(message.command) < 2:
|
| 155 |
+
return await edit_or_reply(message, text="<b>ᴇxᴀᴍᴩʟᴇ :</b>\n/sh git pull")
|
| 156 |
+
text = message.text.split(None, 1)[1]
|
| 157 |
+
if "\n" in text:
|
| 158 |
+
code = text.split("\n")
|
| 159 |
+
output = ""
|
| 160 |
+
for x in code:
|
| 161 |
+
shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x)
|
| 162 |
+
try:
|
| 163 |
+
process = subprocess.Popen(
|
| 164 |
+
shell,
|
| 165 |
+
stdout=subprocess.PIPE,
|
| 166 |
+
stderr=subprocess.PIPE,
|
| 167 |
+
)
|
| 168 |
+
except Exception as err:
|
| 169 |
+
await edit_or_reply(message, text=f"<b>ERROR :</b>\n<pre>{err}</pre>")
|
| 170 |
+
output += f"<b>{code}</b>\n"
|
| 171 |
+
output += process.stdout.read()[:-1].decode("utf-8")
|
| 172 |
+
output += "\n"
|
| 173 |
+
else:
|
| 174 |
+
shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", text)
|
| 175 |
+
for a in range(len(shell)):
|
| 176 |
+
shell[a] = shell[a].replace('"', "")
|
| 177 |
+
try:
|
| 178 |
+
process = subprocess.Popen(
|
| 179 |
+
shell,
|
| 180 |
+
stdout=subprocess.PIPE,
|
| 181 |
+
stderr=subprocess.PIPE,
|
| 182 |
+
)
|
| 183 |
+
except Exception as err:
|
| 184 |
+
print(err)
|
| 185 |
+
exc_type, exc_obj, exc_tb = sys.exc_info()
|
| 186 |
+
errors = traceback.format_exception(
|
| 187 |
+
etype=exc_type,
|
| 188 |
+
value=exc_obj,
|
| 189 |
+
tb=exc_tb,
|
| 190 |
+
)
|
| 191 |
+
return await edit_or_reply(
|
| 192 |
+
message, text=f"<b>ERROR :</b>\n<pre>{''.join(errors)}</pre>"
|
| 193 |
+
)
|
| 194 |
+
output = process.stdout.read()[:-1].decode("utf-8")
|
| 195 |
+
if str(output) == "\n":
|
| 196 |
+
output = None
|
| 197 |
+
if output:
|
| 198 |
+
if len(output) > 4096:
|
| 199 |
+
with open("output.txt", "w+") as file:
|
| 200 |
+
file.write(output)
|
| 201 |
+
await _.send_document(
|
| 202 |
+
message.chat.id,
|
| 203 |
+
"output.txt",
|
| 204 |
+
reply_to_message_id=message.id,
|
| 205 |
+
caption="<code>Output</code>",
|
| 206 |
+
)
|
| 207 |
+
return os.remove("output.txt")
|
| 208 |
+
await edit_or_reply(message, text=f"<b>OUTPUT :</b>\n<pre>{output}</pre>")
|
| 209 |
+
else:
|
| 210 |
+
await edit_or_reply(message, text="<b>OUTPUT :</b>\n<code>None</code>")
|
| 211 |
+
await message.stop_propagation()
|
| 212 |
+
|
| 213 |
+
|
| 214 |
+
|
devgagan/modules/gcast.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#devggn
|
| 2 |
+
|
| 3 |
+
import asyncio
|
| 4 |
+
from pyrogram import filters
|
| 5 |
+
from config import OWNER_ID
|
| 6 |
+
from devgagan import app
|
| 7 |
+
from devgagan.core.mongo.users_db import get_users
|
| 8 |
+
|
| 9 |
+
async def send_msg(user_id, message):
|
| 10 |
+
try:
|
| 11 |
+
await message.copy(chat_id=user_id)
|
| 12 |
+
except FloodWait as e:
|
| 13 |
+
await asyncio.sleep(e.x)
|
| 14 |
+
return send_msg(user_id, message)
|
| 15 |
+
except InputUserDeactivated:
|
| 16 |
+
return 400, f"{user_id} : deactivated\n"
|
| 17 |
+
except UserIsBlocked:
|
| 18 |
+
return 400, f"{user_id} : blocked the bot\n"
|
| 19 |
+
except PeerIdInvalid:
|
| 20 |
+
return 400, f"{user_id} : user id invalid\n"
|
| 21 |
+
except Exception:
|
| 22 |
+
return 500, f"{user_id} : {traceback.format_exc()}\n"
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
@app.on_message(filters.command("gcast") & filters.user(OWNER_ID))
|
| 26 |
+
async def broadcast(_, message):
|
| 27 |
+
if not message.reply_to_message:
|
| 28 |
+
await message.reply_text("ʀᴇᴘʟʏ ᴛᴏ ᴀ ᴍᴇssᴀɢᴇ ᴛᴏ ʙʀᴏᴀᴅᴄᴀsᴛ ɪᴛ.")
|
| 29 |
+
return
|
| 30 |
+
exmsg = await message.reply_text("sᴛᴀʀᴛᴇᴅ ʙʀᴏᴀᴅᴄᴀsᴛɪɴɢ!")
|
| 31 |
+
all_users = (await get_users()) or {}
|
| 32 |
+
done_users = 0
|
| 33 |
+
failed_users = 0
|
| 34 |
+
|
| 35 |
+
for user in all_users:
|
| 36 |
+
try:
|
| 37 |
+
await send_msg(user, message.reply_to_message)
|
| 38 |
+
done_users += 1
|
| 39 |
+
await asyncio.sleep(0.1)
|
| 40 |
+
except Exception:
|
| 41 |
+
pass
|
| 42 |
+
failed_users += 1
|
| 43 |
+
if failed_users == 0:
|
| 44 |
+
await exmsg.edit_text(
|
| 45 |
+
f"**sᴜᴄᴄᴇssғᴜʟʟʏ ʙʀᴏᴀᴅᴄᴀsᴛɪɴɢ ✅**\n\n**sᴇɴᴛ ᴍᴇssᴀɢᴇ ᴛᴏ** `{done_users}` **ᴜsᴇʀs**",
|
| 46 |
+
)
|
| 47 |
+
else:
|
| 48 |
+
await exmsg.edit_text(
|
| 49 |
+
f"**sᴜᴄᴄᴇssғᴜʟʟʏ ʙʀᴏᴀᴅᴄᴀsᴛɪɴɢ ✅**\n\n**sᴇɴᴛ ᴍᴇssᴀɢᴇ ᴛᴏ** `{done_users}` **ᴜsᴇʀs**\n\n**ɴᴏᴛᴇ:-** `ᴅᴜᴇ ᴛᴏ sᴏᴍᴇ ɪssᴜᴇ ᴄᴀɴ'ᴛ ᴀʙʟᴇ ᴛᴏ ʙʀᴏᴀᴅᴄᴀsᴛ` `{failed_users}` **ᴜsᴇʀs**",
|
| 50 |
+
)
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
@app.on_message(filters.command("announce") & filters.user(OWNER_ID))
|
| 57 |
+
async def announced(_, message):
|
| 58 |
+
if message.reply_to_message:
|
| 59 |
+
to_send=message.reply_to_message.id
|
| 60 |
+
if not message.reply_to_message:
|
| 61 |
+
return await message.reply_text("Reply To Some Post To Broadcast")
|
| 62 |
+
users = await get_users() or []
|
| 63 |
+
print(users)
|
| 64 |
+
failed_user = 0
|
| 65 |
+
|
| 66 |
+
for user in users:
|
| 67 |
+
try:
|
| 68 |
+
await _.forward_messages(chat_id=int(user), from_chat_id=message.chat.id, message_ids=to_send)
|
| 69 |
+
await asyncio.sleep(1)
|
| 70 |
+
except Exception as e:
|
| 71 |
+
failed_user += 1
|
| 72 |
+
|
| 73 |
+
if failed_users == 0:
|
| 74 |
+
await exmsg.edit_text(
|
| 75 |
+
f"**sᴜᴄᴄᴇssғᴜʟʟʏ ʙʀᴏᴀᴅᴄᴀsᴛɪɴɢ ✅**\n\n**sᴇɴᴛ ᴍᴇssᴀɢᴇ ᴛᴏ** `{done_users}` **ᴜsᴇʀs**",
|
| 76 |
+
)
|
| 77 |
+
else:
|
| 78 |
+
await exmsg.edit_text(
|
| 79 |
+
f"**sᴜᴄᴄᴇssғᴜʟʟʏ ʙʀᴏᴀᴅᴄᴀsᴛɪɴɢ ✅**\n\n**sᴇɴᴛ ᴍᴇssᴀɢᴇ ᴛᴏ** `{done_users}` **ᴜsᴇʀs**\n\n**ɴᴏᴛᴇ:-** `ᴅᴜᴇ ᴛᴏ sᴏᴍᴇ ɪssᴜᴇ ᴄᴀɴ'ᴛ ᴀʙʟᴇ ᴛᴏ ʙʀᴏᴀᴅᴄᴀsᴛ` `{failed_users}` **ᴜsᴇʀs**",
|
| 80 |
+
)
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
|
devgagan/modules/login.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#devggn
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
from pyrogram import filters, Client
|
| 5 |
+
from devgagan import app
|
| 6 |
+
from pyromod import listen
|
| 7 |
+
import random
|
| 8 |
+
import os
|
| 9 |
+
import string
|
| 10 |
+
from devgagan.core.mongo import db
|
| 11 |
+
from devgagan.core.func import subscribe, chk_user
|
| 12 |
+
from config import API_ID as api_id, API_HASH as api_hash
|
| 13 |
+
from pyrogram.errors import (
|
| 14 |
+
ApiIdInvalid,
|
| 15 |
+
PhoneNumberInvalid,
|
| 16 |
+
PhoneCodeInvalid,
|
| 17 |
+
PhoneCodeExpired,
|
| 18 |
+
SessionPasswordNeeded,
|
| 19 |
+
PasswordHashInvalid,
|
| 20 |
+
FloodWait
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
def generate_random_name(length=7):
|
| 24 |
+
characters = string.ascii_letters + string.digits
|
| 25 |
+
return ''.join(random.choice(characters) for _ in range(length)) # Editted ...
|
| 26 |
+
|
| 27 |
+
async def delete_session_files(user_id):
|
| 28 |
+
session_file = f"session_{user_id}.session"
|
| 29 |
+
memory_file = f"session_{user_id}.session-journal"
|
| 30 |
+
|
| 31 |
+
session_file_exists = os.path.exists(session_file)
|
| 32 |
+
memory_file_exists = os.path.exists(memory_file)
|
| 33 |
+
|
| 34 |
+
if session_file_exists:
|
| 35 |
+
os.remove(session_file)
|
| 36 |
+
|
| 37 |
+
if memory_file_exists:
|
| 38 |
+
os.remove(memory_file)
|
| 39 |
+
|
| 40 |
+
# Delete session from the database
|
| 41 |
+
if session_file_exists or memory_file_exists:
|
| 42 |
+
await db.delete_session(user_id)
|
| 43 |
+
return True # Files were deleted
|
| 44 |
+
return False # No files found
|
| 45 |
+
|
| 46 |
+
@app.on_message(filters.command("logout"))
|
| 47 |
+
async def clear_db(client, message):
|
| 48 |
+
user_id = message.chat.id
|
| 49 |
+
files_deleted = await delete_session_files(user_id)
|
| 50 |
+
|
| 51 |
+
if files_deleted:
|
| 52 |
+
await message.reply("✅ Your session data and files have been cleared from memory and disk.")
|
| 53 |
+
else:
|
| 54 |
+
await message.reply("⚠️ You are not logged in, no session data found.")
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
@app.on_message(filters.command("login"))
|
| 58 |
+
async def generate_session(_, message):
|
| 59 |
+
joined = await subscribe(_, message)
|
| 60 |
+
if joined == 1:
|
| 61 |
+
return
|
| 62 |
+
|
| 63 |
+
# user_checked = await chk_user(message, message.from_user.id)
|
| 64 |
+
# if user_checked == 1:
|
| 65 |
+
# return
|
| 66 |
+
|
| 67 |
+
user_id = message.chat.id
|
| 68 |
+
|
| 69 |
+
number = await _.ask(user_id, 'Please enter your phone number along with the country code. \nExample: +19876543210', filters=filters.text)
|
| 70 |
+
phone_number = number.text
|
| 71 |
+
try:
|
| 72 |
+
await message.reply("📲 Sending OTP...")
|
| 73 |
+
client = Client(f"session_{user_id}", api_id, api_hash)
|
| 74 |
+
|
| 75 |
+
await client.connect()
|
| 76 |
+
except Exception as e:
|
| 77 |
+
await message.reply(f"❌ Failed to send OTP {e}. Please wait and try again later.")
|
| 78 |
+
try:
|
| 79 |
+
code = await client.send_code(phone_number)
|
| 80 |
+
except ApiIdInvalid:
|
| 81 |
+
await message.reply('❌ Invalid combination of API ID and API HASH. Please restart the session.')
|
| 82 |
+
return
|
| 83 |
+
except PhoneNumberInvalid:
|
| 84 |
+
await message.reply('❌ Invalid phone number. Please restart the session.')
|
| 85 |
+
return
|
| 86 |
+
try:
|
| 87 |
+
otp_code = await _.ask(user_id, "Please check for an OTP in your official Telegram account. Once received, enter the OTP in the following format: \nIf the OTP is `12345`, please enter it as `1 2 3 4 5`.", filters=filters.text, timeout=600)
|
| 88 |
+
except TimeoutError:
|
| 89 |
+
await message.reply('⏰ Time limit of 10 minutes exceeded. Please restart the session.')
|
| 90 |
+
return
|
| 91 |
+
phone_code = otp_code.text.replace(" ", "")
|
| 92 |
+
try:
|
| 93 |
+
await client.sign_in(phone_number, code.phone_code_hash, phone_code)
|
| 94 |
+
|
| 95 |
+
except PhoneCodeInvalid:
|
| 96 |
+
await message.reply('❌ Invalid OTP. Please restart the session.')
|
| 97 |
+
return
|
| 98 |
+
except PhoneCodeExpired:
|
| 99 |
+
await message.reply('❌ Expired OTP. Please restart the session.')
|
| 100 |
+
return
|
| 101 |
+
except SessionPasswordNeeded:
|
| 102 |
+
try:
|
| 103 |
+
two_step_msg = await _.ask(user_id, 'Your account has two-step verification enabled. Please enter your password.', filters=filters.text, timeout=300)
|
| 104 |
+
except TimeoutError:
|
| 105 |
+
await message.reply('⏰ Time limit of 5 minutes exceeded. Please restart the session.')
|
| 106 |
+
return
|
| 107 |
+
try:
|
| 108 |
+
password = two_step_msg.text
|
| 109 |
+
await client.check_password(password=password)
|
| 110 |
+
except PasswordHashInvalid:
|
| 111 |
+
await two_step_msg.reply('❌ Invalid password. Please restart the session.')
|
| 112 |
+
return
|
| 113 |
+
string_session = await client.export_session_string()
|
| 114 |
+
await db.set_session(user_id, string_session)
|
| 115 |
+
await client.disconnect()
|
| 116 |
+
await otp_code.reply("✅ Login successful!")
|
devgagan/modules/main.py
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import time
|
| 2 |
+
import random
|
| 3 |
+
import string
|
| 4 |
+
import asyncio
|
| 5 |
+
from pyrogram import filters, Client
|
| 6 |
+
from devgagan import app
|
| 7 |
+
from config import API_ID, API_HASH, FREEMIUM_LIMIT, PREMIUM_LIMIT, OWNER_ID
|
| 8 |
+
from devgagan.core.get_func import get_msg
|
| 9 |
+
from devgagan.core.func import *
|
| 10 |
+
from devgagan.core.mongo import db
|
| 11 |
+
from pyrogram.errors import FloodWait
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
async def generate_random_name(length=8):
|
| 15 |
+
return ''.join(random.choices(string.ascii_lowercase, k=length))
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
users_loop = {}
|
| 19 |
+
|
| 20 |
+
@app.on_message(filters.regex(r'https?://[^\s]+'))
|
| 21 |
+
async def single_link(_, message):
|
| 22 |
+
user_id = message.chat.id
|
| 23 |
+
|
| 24 |
+
# Check if the user is already in the loop
|
| 25 |
+
if users_loop.get(user_id, False):
|
| 26 |
+
await message.reply(
|
| 27 |
+
"You already have an ongoing process. Please wait for it to finish or cancel it with /cancel."
|
| 28 |
+
)
|
| 29 |
+
return
|
| 30 |
+
|
| 31 |
+
freecheck = await chk_user(message, user_id)
|
| 32 |
+
if freecheck == 1 and FREEMIUM_LIMIT == 0 and user_id not in OWNER_ID:
|
| 33 |
+
await message.reply("Freemium service is currently not available. Upgrade to premium for access.")
|
| 34 |
+
return
|
| 35 |
+
|
| 36 |
+
# Add the user to the loop
|
| 37 |
+
users_loop[user_id] = True
|
| 38 |
+
link = get_link(message.text)
|
| 39 |
+
userbot = None
|
| 40 |
+
try:
|
| 41 |
+
join = await subscribe(_, message)
|
| 42 |
+
if join == 1:
|
| 43 |
+
users_loop[user_id] = False
|
| 44 |
+
return
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
msg = await message.reply("Processing...")
|
| 48 |
+
|
| 49 |
+
if 't.me/' in link and 't.me/+' not in link and 't.me/c/' not in link and 't.me/b/' not in link:
|
| 50 |
+
await get_msg(None, user_id, msg.id, link, 0, message)
|
| 51 |
+
# await msg.edit_text("Processed successfully without userbot!")
|
| 52 |
+
return
|
| 53 |
+
|
| 54 |
+
data = await db.get_data(user_id)
|
| 55 |
+
|
| 56 |
+
if data and data.get("session"):
|
| 57 |
+
session = data.get("session")
|
| 58 |
+
try:
|
| 59 |
+
device = 'Vivo Y20'
|
| 60 |
+
session_name = await generate_random_name()
|
| 61 |
+
userbot = Client(session_name, api_id=API_ID, api_hash=API_HASH, device_model=device, session_string=session)
|
| 62 |
+
await userbot.start()
|
| 63 |
+
except:
|
| 64 |
+
users_loop[user_id] = False
|
| 65 |
+
return await msg.edit_text("Login expired /login again...")
|
| 66 |
+
else:
|
| 67 |
+
users_loop[user_id] = False
|
| 68 |
+
await msg.edit_text("Login in bot first ...")
|
| 69 |
+
return
|
| 70 |
+
|
| 71 |
+
try:
|
| 72 |
+
if 't.me/+' in link:
|
| 73 |
+
q = await userbot_join(userbot, link)
|
| 74 |
+
await msg.edit_text(q)
|
| 75 |
+
elif 't.me/c/' in link:
|
| 76 |
+
await get_msg(userbot, user_id, msg.id, link, 0, message)
|
| 77 |
+
else:
|
| 78 |
+
await msg.edit_text("Invalid link format.")
|
| 79 |
+
except Exception as e:
|
| 80 |
+
await msg.edit_text(f"Link: `{link}`\n\n**Error:** {str(e)}")
|
| 81 |
+
|
| 82 |
+
except FloodWait as fw:
|
| 83 |
+
await msg.edit_text(f'Try again after {fw.x} seconds due to floodwait from telegram.')
|
| 84 |
+
|
| 85 |
+
except Exception as e:
|
| 86 |
+
await msg.edit_text(f"Link: `{link}`\n\n**Error:** {str(e)}")
|
| 87 |
+
finally:
|
| 88 |
+
if userbot and userbot.is_connected: # Ensure userbot was initialized and started
|
| 89 |
+
await userbot.stop()
|
| 90 |
+
users_loop[user_id] = False # Remove user from the loop after processing
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
@app.on_message(filters.command("cancel"))
|
| 94 |
+
async def stop_batch(_, message):
|
| 95 |
+
user_id = message.chat.id
|
| 96 |
+
|
| 97 |
+
# Check if there is an active batch process for the user
|
| 98 |
+
if user_id in users_loop and users_loop[user_id]:
|
| 99 |
+
users_loop[user_id] = False # Set the loop status to False
|
| 100 |
+
await app.send_message(
|
| 101 |
+
message.chat.id,
|
| 102 |
+
"Batch processing has been stopped successfully. You can start a new batch now if you want."
|
| 103 |
+
)
|
| 104 |
+
elif user_id in users_loop and not users_loop[user_id]:
|
| 105 |
+
await app.send_message(
|
| 106 |
+
message.chat.id,
|
| 107 |
+
"The batch process was already stopped. No active batch to cancel."
|
| 108 |
+
)
|
| 109 |
+
else:
|
| 110 |
+
await app.send_message(
|
| 111 |
+
message.chat.id,
|
| 112 |
+
"No active batch processing is running to cancel."
|
| 113 |
+
)
|
| 114 |
+
|
| 115 |
+
# --------- PUBLIC CHANNEL
|
| 116 |
+
@app.on_message(filters.command("batch"))
|
| 117 |
+
async def batch_link(_, message):
|
| 118 |
+
user_id = message.chat.id
|
| 119 |
+
|
| 120 |
+
if users_loop.get(user_id, False): # Check if a batch process is already running
|
| 121 |
+
await app.send_message(
|
| 122 |
+
message.chat.id,
|
| 123 |
+
"You already have a batch process running. Please wait for it to complete before starting a new one."
|
| 124 |
+
)
|
| 125 |
+
return
|
| 126 |
+
|
| 127 |
+
# Determine user's limits based on their subscription
|
| 128 |
+
lol = await chk_user(message, user_id)
|
| 129 |
+
if lol == 1:
|
| 130 |
+
max_batch_size = FREEMIUM_LIMIT # Limit for free users
|
| 131 |
+
else:
|
| 132 |
+
max_batch_size = PREMIUM_LIMIT
|
| 133 |
+
|
| 134 |
+
# Ask for start and end links
|
| 135 |
+
start = await app.ask(message.chat.id, text="Please send the start link.")
|
| 136 |
+
start_id = start.text
|
| 137 |
+
s = start_id.split("/")[-1]
|
| 138 |
+
cs = int(s)
|
| 139 |
+
|
| 140 |
+
last = await app.ask(message.chat.id, text="Please send the end link.")
|
| 141 |
+
last_id = last.text
|
| 142 |
+
l = last_id.split("/")[-1]
|
| 143 |
+
cl = int(l)
|
| 144 |
+
|
| 145 |
+
# Check batch size
|
| 146 |
+
if user_id not in OWNER_ID and (cl - cs) > max_batch_size:
|
| 147 |
+
await app.send_message(
|
| 148 |
+
message.chat.id,
|
| 149 |
+
f"Batch size exceeds the limit of {max_batch_size}. Upgrade to premium for larger batch sizes."
|
| 150 |
+
)
|
| 151 |
+
return
|
| 152 |
+
|
| 153 |
+
# Start processing links
|
| 154 |
+
users_loop[user_id] = True
|
| 155 |
+
try:
|
| 156 |
+
# FIRST ITERATION: Process t.me/ links without userbot
|
| 157 |
+
for i in range(cs, cl):
|
| 158 |
+
if user_id in users_loop and users_loop[user_id]:
|
| 159 |
+
try:
|
| 160 |
+
# Construct the link
|
| 161 |
+
x = start_id.split('/')
|
| 162 |
+
y = x[:-1]
|
| 163 |
+
result = '/'.join(y)
|
| 164 |
+
url = f"{result}/{i}"
|
| 165 |
+
link = get_link(url)
|
| 166 |
+
|
| 167 |
+
# Directly process links like t.me/ (no userbot needed)
|
| 168 |
+
if 't.me/' in link and 't.me/b/' not in link and 't.me/c' not in link:
|
| 169 |
+
msg = await app.send_message(message.chat.id, f"Processing link {url}...")
|
| 170 |
+
await get_msg(None, user_id, msg.id, link, 0, message)
|
| 171 |
+
sleep_msg = await app.send_message(
|
| 172 |
+
message.chat.id,
|
| 173 |
+
"Sleeping for 5 seconds to avoid flood..."
|
| 174 |
+
)
|
| 175 |
+
# Add delay to avoid floodwait
|
| 176 |
+
await asyncio.sleep(8)
|
| 177 |
+
await sleep_msg.delete()
|
| 178 |
+
except Exception as e:
|
| 179 |
+
print(f"Error processing link {url}: {e}")
|
| 180 |
+
continue
|
| 181 |
+
|
| 182 |
+
if not any(prefix in start_id for prefix in ['t.me/c/', 't.me/b/']):
|
| 183 |
+
# await app.send_message(message.chat.id, "Skipping second iteration as the link is not valid.")
|
| 184 |
+
await app.send_message(message.chat.id, "Batch completed successfully! 🎉")
|
| 185 |
+
return
|
| 186 |
+
# edit kr lena kuchhu dikkat ho to
|
| 187 |
+
data = await db.get_data(user_id)
|
| 188 |
+
if data and data.get("session"):
|
| 189 |
+
session = data.get("session")
|
| 190 |
+
device = 'Vivo Y20'
|
| 191 |
+
session_name = await generate_random_name()
|
| 192 |
+
userbot = Client(
|
| 193 |
+
session_name,
|
| 194 |
+
api_id=API_ID,
|
| 195 |
+
api_hash=API_HASH,
|
| 196 |
+
device_model=device,
|
| 197 |
+
session_string=session
|
| 198 |
+
)
|
| 199 |
+
await userbot.start()
|
| 200 |
+
else:
|
| 201 |
+
await app.send_message(message.chat.id, "Login in bot first ...")
|
| 202 |
+
return
|
| 203 |
+
|
| 204 |
+
try:
|
| 205 |
+
for i in range(cs, cl):
|
| 206 |
+
if user_id in users_loop and users_loop[user_id]:
|
| 207 |
+
try:
|
| 208 |
+
# Construct the link
|
| 209 |
+
x = start_id.split('/')
|
| 210 |
+
y = x[:-1]
|
| 211 |
+
result = '/'.join(y)
|
| 212 |
+
url = f"{result}/{i}"
|
| 213 |
+
link = get_link(url)
|
| 214 |
+
|
| 215 |
+
# Process links requiring userbot
|
| 216 |
+
if 't.me/b/' in link or 't.me/c/' in link:
|
| 217 |
+
msg = await app.send_message(message.chat.id, f"Processing link {url}...")
|
| 218 |
+
await get_msg(userbot, user_id, msg.id, link, 0, message)
|
| 219 |
+
|
| 220 |
+
# Add delay to avoid floodwait
|
| 221 |
+
sleep_msg = await app.send_message(
|
| 222 |
+
message.chat.id,
|
| 223 |
+
"Sleeping for 20 seconds to avoid flood..."
|
| 224 |
+
)
|
| 225 |
+
await asyncio.sleep(18)
|
| 226 |
+
await sleep_msg.delete()
|
| 227 |
+
await asyncio.sleep(2)
|
| 228 |
+
except Exception as e:
|
| 229 |
+
print(f"Error processing link {url}: {e}")
|
| 230 |
+
continue
|
| 231 |
+
finally:
|
| 232 |
+
if userbot.is_connected:
|
| 233 |
+
await userbot.stop()
|
| 234 |
+
|
| 235 |
+
await app.send_message(message.chat.id, "Batch completed successfully! 🎉")
|
| 236 |
+
except FloodWait as fw:
|
| 237 |
+
await app.send_message(
|
| 238 |
+
message.chat.id,
|
| 239 |
+
f"Try again after {fw.x} seconds due to floodwait from Telegram."
|
| 240 |
+
)
|
| 241 |
+
except Exception as e:
|
| 242 |
+
await app.send_message(message.chat.id, f"Error: {str(e)}")
|
| 243 |
+
finally:
|
| 244 |
+
users_loop.pop(user_id, None)
|
| 245 |
+
|
| 246 |
+
|
devgagan/modules/pingme.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import random
|
| 2 |
+
import requests
|
| 3 |
+
import asyncio
|
| 4 |
+
|
| 5 |
+
HUGGING_TOKEN = os.getenv("HF_TOKEN")
|
| 6 |
+
|
| 7 |
+
async def hfv(api_url, timeout=10):
|
| 8 |
+
try:
|
| 9 |
+
headers = {
|
| 10 |
+
"Authorization": f"Bearer {HUGGING_TOKEN}",
|
| 11 |
+
"Content-Type": "application/json",
|
| 12 |
+
}
|
| 13 |
+
response = await async_searcher(api_url, headers=headers, re_json=True)
|
| 14 |
+
stat = response.get("message", "ded")
|
| 15 |
+
return stat
|
| 16 |
+
except requests.exceptions.RequestException as e:
|
| 17 |
+
print("Error occurred:", e)
|
| 18 |
+
return False
|
devgagan/modules/plans.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#devgaganin
|
| 2 |
+
|
| 3 |
+
from datetime import timedelta
|
| 4 |
+
import pytz
|
| 5 |
+
import datetime, time
|
| 6 |
+
from devgagan import app
|
| 7 |
+
from config import OWNER_ID
|
| 8 |
+
from devgagan.core.func import get_seconds
|
| 9 |
+
from devgagan.core.mongo import plans_db
|
| 10 |
+
from pyrogram import filters
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
@app.on_message(filters.command("rem") & filters.user(OWNER_ID))
|
| 15 |
+
async def remove_premium(client, message):
|
| 16 |
+
if len(message.command) == 2:
|
| 17 |
+
user_id = int(message.command[1])
|
| 18 |
+
user = await client.get_users(user_id)
|
| 19 |
+
data = await plans_db.check_premium(user_id)
|
| 20 |
+
|
| 21 |
+
if data and data.get("_id"):
|
| 22 |
+
await plans_db.remove_premium(user_id)
|
| 23 |
+
await message.reply_text("ᴜꜱᴇʀ ʀᴇᴍᴏᴠᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ !")
|
| 24 |
+
await client.send_message(
|
| 25 |
+
chat_id=user_id,
|
| 26 |
+
text=f"<b>ʜᴇʏ {user.mention},\n\nʏᴏᴜʀ ᴘʀᴇᴍɪᴜᴍ ᴀᴄᴄᴇss ʜᴀs ʙᴇᴇɴ ʀᴇᴍᴏᴠᴇᴅ.\nᴛʜᴀɴᴋ ʏᴏᴜ ꜰᴏʀ ᴜsɪɴɢ ᴏᴜʀ sᴇʀᴠɪᴄᴇ 😊.</b>"
|
| 27 |
+
)
|
| 28 |
+
else:
|
| 29 |
+
await message.reply_text("ᴜɴᴀʙʟᴇ ᴛᴏ ʀᴇᴍᴏᴠᴇ ᴜꜱᴇᴅ !\nᴀʀᴇ ʏᴏᴜ ꜱᴜʀᴇ, ɪᴛ ᴡᴀꜱ ᴀ ᴘʀᴇᴍɪᴜᴍ ᴜꜱᴇʀ ɪᴅ ?")
|
| 30 |
+
else:
|
| 31 |
+
await message.reply_text("ᴜꜱᴀɢᴇ : /rem user_id")
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
@app.on_message(filters.command("myplan"))
|
| 36 |
+
async def myplan(client, message):
|
| 37 |
+
user_id = message.from_user.id
|
| 38 |
+
user = message.from_user.mention
|
| 39 |
+
data = await plans_db.check_premium(user_id)
|
| 40 |
+
if data and data.get("expire_date"):
|
| 41 |
+
expiry = data.get("expire_date")
|
| 42 |
+
expiry_ist = expiry.astimezone(pytz.timezone("Asia/Kolkata"))
|
| 43 |
+
expiry_str_in_ist = expiry.astimezone(pytz.timezone("Asia/Kolkata")).strftime("%d-%m-%Y\n⏱️ ᴇxᴘɪʀʏ ᴛɪᴍᴇ : %I:%M:%S %p")
|
| 44 |
+
|
| 45 |
+
current_time = datetime.datetime.now(pytz.timezone("Asia/Kolkata"))
|
| 46 |
+
time_left = expiry_ist - current_time
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
days = time_left.days
|
| 50 |
+
hours, remainder = divmod(time_left.seconds, 3600)
|
| 51 |
+
minutes, seconds = divmod(remainder, 60)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
time_left_str = f"{days} ᴅᴀʏꜱ, {hours} ʜᴏᴜʀꜱ, {minutes} ᴍɪɴᴜᴛᴇꜱ"
|
| 55 |
+
await message.reply_text(f"⚜️ ᴘʀᴇᴍɪᴜᴍ ᴜꜱᴇʀ ᴅᴀᴛᴀ :\n\n👤 ᴜꜱᴇʀ : {user}\n⚡ ᴜꜱᴇʀ ɪᴅ : <code>{user_id}</code>\n⏰ ᴛɪᴍᴇ ʟᴇꜰᴛ : {time_left_str}\n⌛️ ᴇxᴘɪʀʏ ᴅᴀᴛᴇ : {expiry_str_in_ist}")
|
| 56 |
+
else:
|
| 57 |
+
await message.reply_text(f"ʜᴇʏ {user},\n\nʏᴏᴜ ᴅᴏ ɴᴏᴛ ʜᴀᴠᴇ ᴀɴʏ ᴀᴄᴛɪᴠᴇ ᴘʀᴇᴍɪᴜᴍ ᴘʟᴀɴs")
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
@app.on_message(filters.command("check") & filters.user(OWNER_ID))
|
| 62 |
+
async def get_premium(client, message):
|
| 63 |
+
if len(message.command) == 2:
|
| 64 |
+
user_id = int(message.command[1])
|
| 65 |
+
user = await client.get_users(user_id)
|
| 66 |
+
data = await plans_db.check_premium(user_id)
|
| 67 |
+
if data and data.get("expire_date"):
|
| 68 |
+
expiry = data.get("expire_date")
|
| 69 |
+
expiry_ist = expiry.astimezone(pytz.timezone("Asia/Kolkata"))
|
| 70 |
+
expiry_str_in_ist = expiry.astimezone(pytz.timezone("Asia/Kolkata")).strftime("%d-%m-%Y\n⏱️ ᴇxᴘɪʀʏ ᴛɪᴍᴇ : %I:%M:%S %p")
|
| 71 |
+
|
| 72 |
+
current_time = datetime.datetime.now(pytz.timezone("Asia/Kolkata"))
|
| 73 |
+
time_left = expiry_ist - current_time
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
days = time_left.days
|
| 77 |
+
hours, remainder = divmod(time_left.seconds, 3600)
|
| 78 |
+
minutes, seconds = divmod(remainder, 60)
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
time_left_str = f"{days} days, {hours} hours, {minutes} minutes"
|
| 82 |
+
await message.reply_text(f"⚜️ ᴘʀᴇᴍɪᴜᴍ ᴜꜱᴇʀ ᴅᴀᴛᴀ :\n\n👤 ᴜꜱᴇʀ : {user.mention}\n⚡ ᴜꜱᴇʀ ɪᴅ : <code>{user_id}</code>\n⏰ ᴛɪᴍᴇ ʟᴇꜰᴛ : {time_left_str}\n⌛️ ᴇxᴘɪʀʏ ᴅᴀᴛᴇ : {expiry_str_in_ist}")
|
| 83 |
+
else:
|
| 84 |
+
await message.reply_text("ɴᴏ ᴀɴʏ ᴘʀᴇᴍɪᴜᴍ ᴅᴀᴛᴀ ᴏꜰ ᴛʜᴇ ᴡᴀꜱ ꜰᴏᴜɴᴅ ɪɴ ᴅᴀᴛᴀʙᴀꜱᴇ !")
|
| 85 |
+
else:
|
| 86 |
+
await message.reply_text("ᴜꜱᴀɢᴇ : /check user_id")
|
| 87 |
+
|
| 88 |
+
|
| 89 |
+
@app.on_message(filters.command("add") & filters.user(OWNER_ID))
|
| 90 |
+
async def give_premium_cmd_handler(client, message):
|
| 91 |
+
if len(message.command) == 4:
|
| 92 |
+
time_zone = datetime.datetime.now(pytz.timezone("Asia/Kolkata"))
|
| 93 |
+
current_time = time_zone.strftime("%d-%m-%Y\n⏱️ ᴊᴏɪɴɪɴɢ ᴛɪᴍᴇ : %I:%M:%S %p")
|
| 94 |
+
user_id = int(message.command[1])
|
| 95 |
+
user = await client.get_users(user_id)
|
| 96 |
+
time = message.command[2]+" "+message.command[3]
|
| 97 |
+
seconds = await get_seconds(time)
|
| 98 |
+
if seconds > 0:
|
| 99 |
+
expiry_time = datetime.datetime.now() + datetime.timedelta(seconds=seconds)
|
| 100 |
+
await plans_db.add_premium(user_id, expiry_time)
|
| 101 |
+
data = await plans_db.check_premium(user_id)
|
| 102 |
+
expiry = data.get("expire_date")
|
| 103 |
+
expiry_str_in_ist = expiry.astimezone(pytz.timezone("Asia/Kolkata")).strftime("%d-%m-%Y\n⏱️ ᴇxᴘɪʀʏ ᴛɪᴍᴇ : %I:%M:%S %p")
|
| 104 |
+
await message.reply_text(f"ᴘʀᴇᴍɪᴜᴍ ᴀᴅᴅᴇᴅ ꜱᴜᴄᴄᴇꜱꜱꜰᴜʟʟʏ ✅\n\n👤 ᴜꜱᴇʀ : {user.mention}\n⚡ ᴜꜱᴇʀ ɪᴅ : <code>{user_id}</code>\n⏰ ᴘʀᴇᴍɪᴜᴍ ᴀᴄᴄᴇꜱꜱ : <code>{time}</code>\n\n⏳ ᴊᴏɪɴɪɴɢ ᴅᴀᴛᴇ : {current_time}\n\n⌛️ ᴇxᴘɪʀʏ ᴅᴀᴛᴇ : {expiry_str_in_ist} \n\n__**Powered by Team SPY__**", disable_web_page_preview=True)
|
| 105 |
+
await client.send_message(
|
| 106 |
+
chat_id=user_id,
|
| 107 |
+
text=f"👋 ʜᴇʏ {user.mention},\nᴛʜᴀɴᴋ ʏᴏᴜ ꜰᴏʀ ᴘᴜʀᴄʜᴀꜱɪɴɢ ᴘʀᴇᴍɪᴜᴍ.\nᴇɴᴊᴏʏ !! ✨🎉\n\n⏰ ᴘʀᴇᴍɪᴜᴍ ᴀᴄᴄᴇꜱꜱ : <code>{time}</code>\n⏳ ᴊᴏɪɴɪɴɢ ᴅᴀᴛᴇ : {current_time}\n\n⌛️ ᴇxᴘɪʀʏ ᴅᴀᴛᴇ : {expiry_str_in_ist}", disable_web_page_preview=True
|
| 108 |
+
)
|
| 109 |
+
# await client.send_message(PREMIUM_LOGS, text=f"#Added_Premium\n\n👤 ᴜꜱᴇʀ : {user.mention}\n⚡ ᴜꜱᴇʀ ɪᴅ : <code>{user_id}</code>\n⏰ ᴘʀᴇᴍɪᴜᴍ ᴀᴄᴄᴇꜱꜱ : <code>{time}</code>\n\n⏳ ᴊᴏɪɴɪɴɢ ᴅᴀᴛᴇ : {current_time}\n\n⌛️ ᴇxᴘɪʀʏ ᴅᴀᴛᴇ : {expiry_str_in_ist}", disable_web_page_preview=True)
|
| 110 |
+
|
| 111 |
+
else:
|
| 112 |
+
await message.reply_text("Invalid time format. Please use '1 day for days', '1 hour for hours', or '1 min for minutes', or '1 month for months' or '1 year for year'")
|
| 113 |
+
else:
|
| 114 |
+
await message.reply_text("Usage : /add user_id time (e.g., '1 day for days', '1 hour for hours', or '1 min for minutes', or '1 month for months' or '1 year for year')")
|
| 115 |
+
|
| 116 |
+
|
devgagan/modules/start.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pyrogram import filters
|
| 2 |
+
from devgagan import app
|
| 3 |
+
from devgagan.core import script
|
| 4 |
+
from devgagan.core.func import subscribe
|
| 5 |
+
from config import OWNER_ID
|
| 6 |
+
from pyrogram.types import CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
|
| 7 |
+
|
| 8 |
+
# ------------------- Start-Buttons ------------------- #
|
| 9 |
+
|
| 10 |
+
buttons = InlineKeyboardMarkup(
|
| 11 |
+
[
|
| 12 |
+
[InlineKeyboardButton("Join Channel", url="https://t.me/AgainBots")],
|
| 13 |
+
[InlineKeyboardButton("Buy Premium", url="https://t.me/AgainOwner")]
|
| 14 |
+
]
|
| 15 |
+
)
|
| 16 |
+
|
| 17 |
+
@app.on_message(filters.command("start"))
|
| 18 |
+
async def start(_, message):
|
| 19 |
+
join = await subscribe(_, message)
|
| 20 |
+
if join == 1:
|
| 21 |
+
return
|
| 22 |
+
await message.reply_photo(photo="https://graph.org/file/4e80dc2f4f6f2ddadb4d2.jpg",
|
| 23 |
+
caption=script.START_TXT.format(message.from_user.mention),
|
| 24 |
+
reply_markup=buttons)
|
devgagan/modules/stats.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#devggn
|
| 2 |
+
|
| 3 |
+
from devgagan import app
|
| 4 |
+
from pyrogram import filters
|
| 5 |
+
from config import OWNER_ID
|
| 6 |
+
from devgagan.core.mongo.users_db import get_users, add_user, get_user
|
| 7 |
+
from devgagan.core.mongo.plans_db import premium_users
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
@app.on_message(group=10)
|
| 13 |
+
async def chat_watcher_func(_, message):
|
| 14 |
+
try:
|
| 15 |
+
if message.from_user:
|
| 16 |
+
us_in_db = await get_user(message.from_user.id)
|
| 17 |
+
if not us_in_db:
|
| 18 |
+
await add_user(message.from_user.id)
|
| 19 |
+
except:
|
| 20 |
+
pass
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
@app.on_message(filters.command("stats"))
|
| 24 |
+
async def stats(client, message):
|
| 25 |
+
users = len(await get_users())
|
| 26 |
+
premium = await premium_users()
|
| 27 |
+
await message.reply_text(f"""
|
| 28 |
+
**Total Stats of** {(await client.get_me()).mention} :
|
| 29 |
+
|
| 30 |
+
**Total Users** : {users}
|
| 31 |
+
**Premium Users** : {len(premium)}
|
| 32 |
+
|
| 33 |
+
**__Powered by Team SPY__**
|
| 34 |
+
""")
|
| 35 |
+
|
package.json
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "your-app-name",
|
| 3 |
+
"version": "1.0.0",
|
| 4 |
+
"description": "",
|
| 5 |
+
"main": "index.js",
|
| 6 |
+
"scripts": {
|
| 7 |
+
"start": "node index.js"
|
| 8 |
+
},
|
| 9 |
+
"author": "",
|
| 10 |
+
"license": "ISC"
|
| 11 |
+
}
|
requirements.txt
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
https://www.dl.dropboxusercontent.com/scl/fi/35w0i0hnsioq63x7eumdd/pyrogagan.zip?rlkey=mq4b56v0z7w7mgj3c0o3sqgo1&st=n7prfm1y&dl=0
|
| 2 |
+
psutil
|
| 3 |
+
tgcrypto
|
| 4 |
+
pyromod
|
| 5 |
+
opencv-python-headless
|
| 6 |
+
requests
|
| 7 |
+
motor
|
| 8 |
+
pytz
|
| 9 |
+
flask
|
| 10 |
+
telethon
|
| 11 |
+
aiojobs
|
| 12 |
+
werkzeug==2.2.2
|
| 13 |
+
PyPDF2
|
| 14 |
+
reportlab
|
| 15 |
+
PyMuPDF
|
| 16 |
+
# cryptg
|
settings.jpg
ADDED
|
start.sh
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!bin/bash
|
| 2 |
+
python3 -m devgagan &
|
| 3 |
+
exec python3 app.py
|
static/gagan.png
ADDED
|