taslim19 commited on
Commit
616a9b8
·
1 Parent(s): 280e0cf

fix: nsfw.py dsong.py from cookies to api

Browse files
DragMusic/plugins/bot/start.py CHANGED
@@ -67,6 +67,7 @@ async def start_pm(client, message: Message, _):
67
  text=f"{message.from_user.mention} ᴄʜᴇᴄᴋᴇᴅ <b>sᴜᴅᴏʟɪsᴛ</b>.\n\n"
68
  f"<b>• ɪᴅᴇɴᴛɪғɪᴇʀ ⌯</b> <code>{message.from_user.id}</code>\n"
69
  f"<b>• ʜᴀɴᴅʟᴇ ⌯</b> @{message.from_user.username}",
 
70
  )
71
  return
72
 
@@ -108,6 +109,7 @@ async def start_pm(client, message: Message, _):
108
  text=f"<b>{message.from_user.mention} ᴄʜᴇᴄᴋᴇᴅ ᴛʀᴀᴄᴋ ɪɴғᴏ.</b>\n\n"
109
  f"<b>• ɪᴅᴇɴᴛɪғɪᴇʀ ⌯</b> <code>{message.from_user.id}</code>\n"
110
  f"<b>• ʜᴀɴᴅʟᴇ ⌯</b> @{message.from_user.username}",
 
111
  )
112
  else:
113
  await m.edit_text("ғᴀɪʟᴇᴅ ᴛᴏ ʀᴇᴛʀɪᴇᴠᴇ ɪɴғᴏʀᴍᴀᴛɪᴏɴ.")
@@ -129,6 +131,7 @@ async def start_pm(client, message: Message, _):
129
  text=f"<b>{message.from_user.mention} sᴛᴀʀᴛᴇᴅ ᴛʜᴇ ʙᴏᴛ.</b>\n\n"
130
  f"<b>• ɪᴅᴇɴᴛɪғɪᴇʀ ⌯</b> <code>{message.from_user.id}</code>\n"
131
  f"<b>• ʜᴀɴᴅʟᴇ ⌯</b> @{message.from_user.username}",
 
132
  )
133
 
134
 
 
67
  text=f"{message.from_user.mention} ᴄʜᴇᴄᴋᴇᴅ <b>sᴜᴅᴏʟɪsᴛ</b>.\n\n"
68
  f"<b>• ɪᴅᴇɴᴛɪғɪᴇʀ ⌯</b> <code>{message.from_user.id}</code>\n"
69
  f"<b>• ʜᴀɴᴅʟᴇ ⌯</b> @{message.from_user.username}",
70
+ message_thread_id=9,
71
  )
72
  return
73
 
 
109
  text=f"<b>{message.from_user.mention} ᴄʜᴇᴄᴋᴇᴅ ᴛʀᴀᴄᴋ ɪɴғᴏ.</b>\n\n"
110
  f"<b>• ɪᴅᴇɴᴛɪғɪᴇʀ ⌯</b> <code>{message.from_user.id}</code>\n"
111
  f"<b>• ʜᴀɴᴅʟᴇ ⌯</b> @{message.from_user.username}",
112
+ message_thread_id=9,
113
  )
114
  else:
115
  await m.edit_text("ғᴀɪʟᴇᴅ ᴛᴏ ʀᴇᴛʀɪᴇᴠᴇ ɪɴғᴏʀᴍᴀᴛɪᴏɴ.")
 
131
  text=f"<b>{message.from_user.mention} sᴛᴀʀᴛᴇᴅ ᴛʜᴇ ʙᴏᴛ.</b>\n\n"
132
  f"<b>• ɪᴅᴇɴᴛɪғɪᴇʀ ⌯</b> <code>{message.from_user.id}</code>\n"
133
  f"<b>• ʜᴀɴᴅʟᴇ ⌯</b> @{message.from_user.username}",
134
+ message_thread_id=9,
135
  )
136
 
137
 
DragMusic/plugins/plugins/dsong.py CHANGED
@@ -1,57 +1,56 @@
1
  import os
 
2
  from datetime import timedelta
3
  from pyrogram.enums import ParseMode
4
-
5
- import wget
6
- from pyrogram import Client
7
  from pyrogram import filters
8
  from pyrogram.types import Message
9
- from yt_dlp import YoutubeDL
10
- from youtubesearchpython import VideosSearch
11
  from DragMusic import app
12
-
 
13
 
14
  @app.on_message(filters.command(["vsong"]))
15
  async def vsong_cmd(client, message):
16
- """Command to download and send a YouTube video."""
17
  if len(message.command) < 2:
18
  return await message.reply_text(
19
  "❌ <b>Video not found,</b>\nPlease enter the correct video title.",
20
  )
21
  infomsg = await message.reply_text("<b>🔍 Searching...</b>", quote=False)
 
22
  try:
23
- search = VideosSearch(message.text.split(None, 1)[1], limit=1).result()["result"][0]
24
- link = f"https://youtu.be/{search['id']}"
 
 
 
 
 
 
 
 
25
  except Exception as error:
26
  return await infomsg.edit(f"<b>🔍 Searching...\n\n{error}</b>")
27
 
28
- ydl_opts = {
29
- "format": "bestvideo+bestaudio",
30
- "outtmpl": "%(title)s.%(ext)s",
31
- "merge_output_format": "mp4",
32
- "cookiefile": "cookies.txt",
33
- }
34
-
35
  try:
36
  await infomsg.edit("<b>Downloading video...</b>")
37
- with YoutubeDL(ydl_opts) as ydl:
38
- info_dict = ydl.extract_info(link, download=True)
39
- file_name = ydl.prepare_filename(info_dict)
40
- title = info_dict.get("title", "Unknown")
41
- duration = info_dict.get("duration", 0)
42
- views = info_dict.get("view_count", 0)
43
- channel = info_dict.get("uploader", "Unknown")
44
- thumb = info_dict.get("thumbnail", None)
45
- except Exception as error:
46
- return await infomsg.edit(f"<blockquote><b>Downloading video...\n\n{error}</blockquote></b>")
47
-
48
- thumbnail_path = None
49
- try:
50
  if thumb:
51
- thumbnail_path = wget.download(thumb)
 
 
 
 
 
52
  await client.send_video(
53
  message.chat.id,
54
- video=file_name,
55
  thumb=thumbnail_path,
56
  file_name=title,
57
  duration=duration,
@@ -62,66 +61,60 @@ async def vsong_cmd(client, message):
62
  f"<b> Duration:</b> {timedelta(seconds=duration)}\n"
63
  f"<b> Views:</b> {views:,}\n"
64
  f"<b> Channel:</b> {channel}\n"
65
- f"<b> Link:</b> <a href='{link}'>YouTube</a></blockquote>\n\n"
66
- f"<blockquote><b>⚡ Powered by: @haatsoja</b></blockquote> "
67
  ),
68
  reply_to_message_id=message.id,
69
  )
70
  finally:
71
- if thumbnail_path and os.path.isfile(thumbnail_path):
72
  os.remove(thumbnail_path)
73
- if file_name and os.path.isfile(file_name):
74
- os.remove(file_name)
75
  await infomsg.delete()
76
 
77
-
78
  @app.on_message(filters.command(["song"]))
79
  async def song_cmd(client, message):
80
- """Command to download and send a YouTube audio file."""
81
  if len(message.command) < 2:
82
  return await message.reply_text(
83
  "❌ <b>Audio not found,</b>\nPlease enter the correct audio title.",
84
  )
85
  infomsg = await message.reply_text("<b>🔍 Searching...</b>", quote=False)
 
86
  try:
87
- search = VideosSearch(message.text.split(None, 1)[1], limit=1).result()["result"][0]
88
- link = f"https://youtu.be/{search['id']}"
 
 
 
 
 
 
 
 
89
  except Exception as error:
90
  return await infomsg.edit(f"<b>🔍 Searching...\n\n{error}</b>")
91
 
92
- ydl_opts = {
93
- "format": "bestaudio/best",
94
- "outtmpl": "%(title)s.%(ext)s",
95
- "postprocessors": [
96
- {
97
- "key": "FFmpegExtractAudio",
98
- "preferredcodec": "mp3",
99
- "preferredquality": "192",
100
- }
101
- ],
102
- "cookiefile": "cookies.txt",
103
- }
104
-
105
  try:
106
  await infomsg.edit("<b>Downloading audio...</b>")
107
- with YoutubeDL(ydl_opts) as ydl:
108
- info_dict = ydl.extract_info(link, download=True)
109
- file_name = ydl.prepare_filename(info_dict).replace(".webm", ".mp3")
110
- title = info_dict.get("title", "Unknown")
111
- duration = info_dict.get("duration", 0)
112
- views = info_dict.get("view_count", 0)
113
- channel = info_dict.get("uploader", "Unknown")
114
- thumb = info_dict.get("thumbnail", None)
115
- except Exception as error:
116
- return await infomsg.edit(f"<blockquote><b>Downloading audio...\n\n{error}</b></blockquote>")
117
-
118
- thumbnail_path = None
119
- try:
120
  if thumb:
121
- thumbnail_path = wget.download(thumb)
 
 
 
 
 
122
  await client.send_audio(
123
  message.chat.id,
124
- audio=file_name,
125
  thumb=thumbnail_path,
126
  file_name=title,
127
  performer=channel,
@@ -132,15 +125,15 @@ async def song_cmd(client, message):
132
  f"<b> Duration:</b> {timedelta(seconds=duration)}\n"
133
  f"<b> Views:</b> {views:,}\n"
134
  f"<b> Channel:</b> {channel}\n"
135
- f"<b> Link:</b> <a href='{link}'>YouTube</a></blockquote>\n\n"
136
- f"<blockquote><b>⚡ Powered by: @haatsoja</b></blockquote>"
137
  ),
138
- parse_mode=ParseMode.HTML,
139
  reply_to_message_id=message.id,
140
  )
141
  finally:
142
- if thumbnail_path and os.path.isfile(thumbnail_path):
143
  os.remove(thumbnail_path)
144
- if file_name and os.path.isfile(file_name):
145
- os.remove(file_name)
146
  await infomsg.delete()
 
1
  import os
2
+ import tempfile
3
  from datetime import timedelta
4
  from pyrogram.enums import ParseMode
5
+ import httpx
 
 
6
  from pyrogram import filters
7
  from pyrogram.types import Message
 
 
8
  from DragMusic import app
9
+ from DragMusic.platforms.Youtube import YouTubeAPI
10
+ from config import BITFLOW_API_KEY
11
 
12
  @app.on_message(filters.command(["vsong"]))
13
  async def vsong_cmd(client, message):
14
+ """Command to download and send a YouTube video using Bitflow API."""
15
  if len(message.command) < 2:
16
  return await message.reply_text(
17
  "❌ <b>Video not found,</b>\nPlease enter the correct video title.",
18
  )
19
  infomsg = await message.reply_text("<b>🔍 Searching...</b>", quote=False)
20
+ query = message.text.split(None, 1)[1]
21
  try:
22
+ bitflow = await YouTubeAPI().bitflow_video(query, api_key=BITFLOW_API_KEY)
23
+ if not bitflow or bitflow.get("status") != "success":
24
+ return await infomsg.edit("<b>🔍 Searching...\n\n No result from Bitflow API.</b>")
25
+ url = bitflow["url"]
26
+ title = bitflow.get("title", "Unknown")
27
+ duration = bitflow.get("duration", 0)
28
+ views = bitflow.get("views", 0)
29
+ channel = bitflow.get("channel", "Unknown")
30
+ thumb = bitflow.get("thumbnail", None)
31
+ ext = bitflow.get("ext", "mp4")
32
  except Exception as error:
33
  return await infomsg.edit(f"<b>🔍 Searching...\n\n{error}</b>")
34
 
35
+ temp_dir = tempfile.gettempdir()
36
+ file_path = os.path.join(temp_dir, f"{title}.{ext}")
 
 
 
 
 
37
  try:
38
  await infomsg.edit("<b>Downloading video...</b>")
39
+ async with httpx.AsyncClient() as client:
40
+ r = await client.get(url)
41
+ with open(file_path, "wb") as f:
42
+ f.write(r.content)
43
+ thumbnail_path = None
 
 
 
 
 
 
 
 
44
  if thumb:
45
+ thumb_path = os.path.join(temp_dir, f"{title}_thumb.jpg")
46
+ async with httpx.AsyncClient() as client:
47
+ r = await client.get(thumb)
48
+ with open(thumb_path, "wb") as f:
49
+ f.write(r.content)
50
+ thumbnail_path = thumb_path
51
  await client.send_video(
52
  message.chat.id,
53
+ video=file_path,
54
  thumb=thumbnail_path,
55
  file_name=title,
56
  duration=duration,
 
61
  f"<b> Duration:</b> {timedelta(seconds=duration)}\n"
62
  f"<b> Views:</b> {views:,}\n"
63
  f"<b> Channel:</b> {channel}\n"
64
+ f"<b> Link:</b> <a href='{url}'>YouTube</a></blockquote>\n\n"
65
+ f"<blockquote><b>⚡ Powered by: @dragbotsupport</b></blockquote> "
66
  ),
67
  reply_to_message_id=message.id,
68
  )
69
  finally:
70
+ if 'thumbnail_path' in locals() and thumbnail_path and os.path.isfile(thumbnail_path):
71
  os.remove(thumbnail_path)
72
+ if file_path and os.path.isfile(file_path):
73
+ os.remove(file_path)
74
  await infomsg.delete()
75
 
 
76
  @app.on_message(filters.command(["song"]))
77
  async def song_cmd(client, message):
78
+ """Command to download and send a YouTube audio file using Bitflow API."""
79
  if len(message.command) < 2:
80
  return await message.reply_text(
81
  "❌ <b>Audio not found,</b>\nPlease enter the correct audio title.",
82
  )
83
  infomsg = await message.reply_text("<b>🔍 Searching...</b>", quote=False)
84
+ query = message.text.split(None, 1)[1]
85
  try:
86
+ bitflow = await YouTubeAPI().bitflow_video(query, api_key=BITFLOW_API_KEY)
87
+ if not bitflow or bitflow.get("status") != "success":
88
+ return await infomsg.edit("<b>🔍 Searching...\n\nNo result from Bitflow API.</b>")
89
+ url = bitflow["url"]
90
+ title = bitflow.get("title", "Unknown")
91
+ duration = bitflow.get("duration", 0)
92
+ views = bitflow.get("views", 0)
93
+ channel = bitflow.get("channel", "Unknown")
94
+ thumb = bitflow.get("thumbnail", None)
95
+ ext = bitflow.get("ext", "mp3")
96
  except Exception as error:
97
  return await infomsg.edit(f"<b>🔍 Searching...\n\n{error}</b>")
98
 
99
+ temp_dir = tempfile.gettempdir()
100
+ file_path = os.path.join(temp_dir, f"{title}.{ext}")
 
 
 
 
 
 
 
 
 
 
 
101
  try:
102
  await infomsg.edit("<b>Downloading audio...</b>")
103
+ async with httpx.AsyncClient() as client:
104
+ r = await client.get(url)
105
+ with open(file_path, "wb") as f:
106
+ f.write(r.content)
107
+ thumbnail_path = None
 
 
 
 
 
 
 
 
108
  if thumb:
109
+ thumb_path = os.path.join(temp_dir, f"{title}_thumb.jpg")
110
+ async with httpx.AsyncClient() as client:
111
+ r = await client.get(thumb)
112
+ with open(thumb_path, "wb") as f:
113
+ f.write(r.content)
114
+ thumbnail_path = thumb_path
115
  await client.send_audio(
116
  message.chat.id,
117
+ audio=file_path,
118
  thumb=thumbnail_path,
119
  file_name=title,
120
  performer=channel,
 
125
  f"<b> Duration:</b> {timedelta(seconds=duration)}\n"
126
  f"<b> Views:</b> {views:,}\n"
127
  f"<b> Channel:</b> {channel}\n"
128
+ f"<b> Link:</b> <a href='{url}'>YouTube</a></blockquote>\n\n"
129
+ f"<blockquote><b>⚡ Powered by: @dragbotsupport</b></blockquote>"
130
  ),
131
+ parse_mode=ParseMode.HTML,
132
  reply_to_message_id=message.id,
133
  )
134
  finally:
135
+ if 'thumbnail_path' in locals() and thumbnail_path and os.path.isfile(thumbnail_path):
136
  os.remove(thumbnail_path)
137
+ if file_path and os.path.isfile(file_path):
138
+ os.remove(file_path)
139
  await infomsg.delete()
DragMusic/plugins/plugins/nsfw.py CHANGED
@@ -17,6 +17,7 @@ from pyrogram.enums import ParseMode
17
  db_client = AsyncIOMotorClient(MONGO_DB_URI)
18
  db = db_client['AnonXDatabase']
19
  nsfw_chats_collection = db['nsfw_chats']
 
20
 
21
  # Logger configuration
22
  LOGGER_ID = -1002471976725
@@ -100,24 +101,20 @@ async def scan_media(media_msg: Message, reply_msg: Message):
100
  media = media_msg.photo or media_msg.video or media_msg.sticker
101
  path = None
102
  image_path = None
103
-
104
  try:
105
  ext = ".jpg"
106
  if media_msg.video:
107
  ext = ".mp4"
108
  elif media_msg.sticker:
109
  ext = ".webp"
110
-
111
  with tempfile.NamedTemporaryFile(suffix=ext, delete=False) as temp:
112
  path = temp.name
113
-
114
  if hasattr(media, "download"):
115
  await media.download(file_name=path)
116
  elif media.file_id:
117
  await media_msg.download(file_name=path)
118
  else:
119
  return await reply_msg.reply("Unable to download media.")
120
-
121
  if path.endswith((".webm", ".mp4", ".webp")):
122
  image_path = path + ".png"
123
  subprocess.run(
@@ -131,21 +128,39 @@ async def scan_media(media_msg: Message, reply_msg: Message):
131
  if os.path.getsize(path) == 0:
132
  return await reply_msg.reply("Downloaded file is empty, cannot scan.")
133
  img = Image.open(path).convert("RGB")
134
-
135
  inputs = processor(images=img, return_tensors="pt")
136
  with torch.no_grad():
137
  outputs = model(**inputs)
138
  probs = F.softmax(outputs.logits, dim=1)
139
  confidence = round(probs[0][1].item() * 100, 2)
140
  label = "NSFW" if confidence > 50 else "SFW"
141
-
142
- if label == "NSFW":
 
 
 
 
 
 
143
  try:
144
  await media_msg.delete()
145
  except Exception as e:
146
  print(f"[NSFW] Failed to delete message: {e}")
147
-
148
- await reply_msg.reply(f"🚫 NSFW Detected ({confidence}%) — Message deleted.")
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  log_text = (
150
  f"🚨 NSFW Content Detected\n"
151
  f"Chat: {reply_msg.chat.title} (`{reply_msg.chat.id}`)\n"
@@ -160,9 +175,7 @@ async def scan_media(media_msg: Message, reply_msg: Message):
160
  )
161
  except Exception as log_err:
162
  print(f"[NSFW Logger Error] {log_err}")
163
- else:
164
- await reply_msg.reply(f"✅ Scan Result: {label} ({confidence}%)")
165
-
166
  except UnidentifiedImageError:
167
  print(f"[NSFW Detection Error] Cannot identify image file '{path or image_path}'")
168
  await reply_msg.reply("Failed to read image for scanning.")
 
17
  db_client = AsyncIOMotorClient(MONGO_DB_URI)
18
  db = db_client['AnonXDatabase']
19
  nsfw_chats_collection = db['nsfw_chats']
20
+ nsfw_stickers_collection = db['nsfw_stickers']
21
 
22
  # Logger configuration
23
  LOGGER_ID = -1002471976725
 
101
  media = media_msg.photo or media_msg.video or media_msg.sticker
102
  path = None
103
  image_path = None
 
104
  try:
105
  ext = ".jpg"
106
  if media_msg.video:
107
  ext = ".mp4"
108
  elif media_msg.sticker:
109
  ext = ".webp"
 
110
  with tempfile.NamedTemporaryFile(suffix=ext, delete=False) as temp:
111
  path = temp.name
 
112
  if hasattr(media, "download"):
113
  await media.download(file_name=path)
114
  elif media.file_id:
115
  await media_msg.download(file_name=path)
116
  else:
117
  return await reply_msg.reply("Unable to download media.")
 
118
  if path.endswith((".webm", ".mp4", ".webp")):
119
  image_path = path + ".png"
120
  subprocess.run(
 
128
  if os.path.getsize(path) == 0:
129
  return await reply_msg.reply("Downloaded file is empty, cannot scan.")
130
  img = Image.open(path).convert("RGB")
 
131
  inputs = processor(images=img, return_tensors="pt")
132
  with torch.no_grad():
133
  outputs = model(**inputs)
134
  probs = F.softmax(outputs.logits, dim=1)
135
  confidence = round(probs[0][1].item() * 100, 2)
136
  label = "NSFW" if confidence > 50 else "SFW"
137
+ if confidence > 50:
138
+ # Store sticker file_id if flagged
139
+ if media_msg.sticker and media_msg.sticker.file_id:
140
+ await nsfw_stickers_collection.update_one(
141
+ {"file_id": media_msg.sticker.file_id},
142
+ {"$set": {"file_id": media_msg.sticker.file_id, "chat_id": reply_msg.chat.id}},
143
+ upsert=True
144
+ )
145
  try:
146
  await media_msg.delete()
147
  except Exception as e:
148
  print(f"[NSFW] Failed to delete message: {e}")
149
+ # Button to go to group
150
+ from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
151
+ group_link = None
152
+ if reply_msg.chat.username:
153
+ group_link = f"https://t.me/{reply_msg.chat.username}"
154
+ else:
155
+ # For private/supergroups, use deep link to the group (no message jump)
156
+ group_link = f"https://t.me/c/{str(reply_msg.chat.id)[4:]}" if str(reply_msg.chat.id).startswith("-100") else None
157
+ buttons = InlineKeyboardMarkup([
158
+ [InlineKeyboardButton("Go to Group", url=group_link)] if group_link else []
159
+ ])
160
+ await reply_msg.reply(
161
+ f"🚫 NSFW Detected ({confidence}%) — Message deleted.",
162
+ reply_markup=buttons if group_link else None
163
+ )
164
  log_text = (
165
  f"🚨 NSFW Content Detected\n"
166
  f"Chat: {reply_msg.chat.title} (`{reply_msg.chat.id}`)\n"
 
175
  )
176
  except Exception as log_err:
177
  print(f"[NSFW Logger Error] {log_err}")
178
+ # Do not send anything in chat if SFW (confidence <= 50)
 
 
179
  except UnidentifiedImageError:
180
  print(f"[NSFW Detection Error] Cannot identify image file '{path or image_path}'")
181
  await reply_msg.reply("Failed to read image for scanning.")