kailashhh commited on
Commit
6b1e8b6
·
1 Parent(s): 19173f7
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