Captain Ezio commited on
Commit
c26bbaf
·
1 Parent(s): 51e1c40

`V 2.2.0` few more changes left

Browse files
Powers/__init__.py CHANGED
@@ -1,3 +1,4 @@
 
1
  from datetime import datetime
2
  from importlib import import_module as imp_mod
3
  from logging import (INFO, WARNING, FileHandler, StreamHandler, basicConfig,
@@ -21,6 +22,9 @@ LOGDIR = f"{__name__}/logs"
21
  # Make Logs directory if it does not exixts
22
  if not path.isdir(LOGDIR):
23
  mkdir(LOGDIR)
 
 
 
24
 
25
  LOGFILE = f"{LOGDIR}/{__name__}_{LOG_DATETIME}_log.txt"
26
 
@@ -59,9 +63,9 @@ except Exception as ef:
59
  # time zone
60
  TIME_ZONE = pytz.timezone(Config.TIME_ZONE)
61
 
62
- path = "./Version"
63
  version = []
64
- for i in listdir(path):
65
  if i.startswith("version") and i.endswith("md"):
66
  version.append(i)
67
  else:
@@ -134,6 +138,9 @@ Defult_dev = set(defult_dev)
134
  DEVS = DEVS_USER | Defult_dev
135
  DEV_USERS = list(DEVS)
136
 
 
 
 
137
  # Plugins, DB and Workers
138
  DB_URI = Config.DB_URI
139
  DB_NAME = Config.DB_NAME
@@ -148,6 +155,14 @@ HELP_COMMANDS = {} # For help menu
148
  UPTIME = time() # Check bot uptime
149
 
150
 
 
 
 
 
 
 
 
 
151
  scheduler = AsyncIOScheduler(timezone=TIME_ZONE)
152
 
153
 
 
1
+ import shutil
2
  from datetime import datetime
3
  from importlib import import_module as imp_mod
4
  from logging import (INFO, WARNING, FileHandler, StreamHandler, basicConfig,
 
22
  # Make Logs directory if it does not exixts
23
  if not path.isdir(LOGDIR):
24
  mkdir(LOGDIR)
25
+ else:
26
+ shutil.rmtree(LOGDIR)
27
+ mkdir(LOGDIR)
28
 
29
  LOGFILE = f"{LOGDIR}/{__name__}_{LOG_DATETIME}_log.txt"
30
 
 
63
  # time zone
64
  TIME_ZONE = pytz.timezone(Config.TIME_ZONE)
65
 
66
+ Vpath = "./Version"
67
  version = []
68
+ for i in listdir(Vpath):
69
  if i.startswith("version") and i.endswith("md"):
70
  version.append(i)
71
  else:
 
138
  DEVS = DEVS_USER | Defult_dev
139
  DEV_USERS = list(DEVS)
140
 
141
+ CHROME_BIN = Config.CHROME_BIN
142
+ CHROME_DRIVER = Config.CHROME_DRIVER
143
+
144
  # Plugins, DB and Workers
145
  DB_URI = Config.DB_URI
146
  DB_NAME = Config.DB_NAME
 
155
  UPTIME = time() # Check bot uptime
156
 
157
 
158
+ #Make dir
159
+ youtube_dir = "./Youtube/"
160
+ if not path.isdir(youtube_dir):
161
+ mkdir(youtube_dir)
162
+ else:
163
+ shutil.rmtree(youtube_dir)
164
+ mkdir(youtube_dir)
165
+
166
  scheduler = AsyncIOScheduler(timezone=TIME_ZONE)
167
 
168
 
Powers/plugins/bans.py CHANGED
@@ -487,7 +487,7 @@ async def skick_usr(c: Gojo, m: Message):
487
  return
488
 
489
  if user_id == Config.BOT_ID:
490
- await m.reply_text("Huh, why would I kick myself?")
491
  await m.stop_propagation()
492
 
493
  SUPPORT_STAFF = get_support_staff()
 
487
  return
488
 
489
  if user_id == Config.BOT_ID:
490
+ await m.reply_text("Nuh Hu, why would I kick myself?")
491
  await m.stop_propagation()
492
 
493
  SUPPORT_STAFF = get_support_staff()
Powers/plugins/formatting.py CHANGED
@@ -39,14 +39,7 @@ async def markdownhelp(_, m: Message):
39
  return
40
 
41
 
42
- @Gojo.on_callback_query(filters.regex("^formatting."))
43
- async def get_formatting_info(c: Gojo, q: CallbackQuery):
44
- cmd = q.data.split(".")[1]
45
- kb = ikb([[("Back", "back.formatting")]])
46
-
47
- if cmd == "md_formatting":
48
-
49
- txt = """<b>Markdown Formatting</b>
50
  You can format your message using <b>bold</b>, <i>italic</i>, <u>underline</u>, <strike>strike</strike> and much more. Go ahead and experiment!
51
 
52
  **Note**: It supports telegram user based formatting as well as html and markdown formattings.
@@ -66,19 +59,74 @@ If you would like to send buttons on the same row, use the <code>:same</code> fo
66
  <code>[button 2](buttonurl://example.com:same)</code>
67
  <code>[button 3](buttonurl://example.com)</code>
68
  This will show button 1 and 2 on the same line, while 3 will be underneath."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  try:
70
  await q.edit_message_caption(
71
- caption=txt,
72
  reply_markup=kb,
73
  parse_mode=enums.ParseMode.HTML,
74
  )
75
  except MediaCaptionTooLong:
76
- kb = ikb([[("Back", "DELETEEEE")]])
77
- await c.send_message(
78
- chat_id=q.message.chat.id,
79
- text=txt,
80
  parse_mode=enums.ParseMode.HTML,
81
- reply_markup=kb)
82
  elif cmd == "fillings":
83
  await q.edit_message_caption(
84
  caption="""<b>Fillings</b>
 
39
  return
40
 
41
 
42
+ md_txt = """<b>Markdown Formatting</b>
 
 
 
 
 
 
 
43
  You can format your message using <b>bold</b>, <i>italic</i>, <u>underline</u>, <strike>strike</strike> and much more. Go ahead and experiment!
44
 
45
  **Note**: It supports telegram user based formatting as well as html and markdown formattings.
 
59
  <code>[button 2](buttonurl://example.com:same)</code>
60
  <code>[button 3](buttonurl://example.com)</code>
61
  This will show button 1 and 2 on the same line, while 3 will be underneath."""
62
+
63
+ async def get_splited_formatting(msg, page=1):
64
+ msg = msg.split("\n")
65
+ l = len(msg)
66
+ new_msg = ""
67
+ total = l // 10
68
+ first = 10 * (page - 1)
69
+ last = 10 * page
70
+ if not first:
71
+ for i in msg[first:last]:
72
+ new_msg += f"{i}\n"
73
+ kb = [
74
+ [
75
+ ("Next page ▶️", f"next_format_{page+1}")
76
+ ]
77
+ ]
78
+ else:
79
+ first += 1
80
+ if page == total:
81
+ for i in msg[first:]:
82
+ new_msg += f"{i}\n"
83
+ kb = [
84
+ [
85
+ ("◀️ Previous page", f"next_format_{page-1}")
86
+ ]
87
+ ]
88
+ else:
89
+ for i in msg[first:last]:
90
+ new_msg += f"{i}\n"
91
+ kb = [
92
+ [
93
+ ("◀️ Previous page", f"next_format_{page-1}"),
94
+ ("Next page ▶️", f"next_format_{page+1}")
95
+ ]
96
+ ]
97
+
98
+
99
+ kb = ikb(kb, True, "back.formatting")
100
+
101
+ return new_msg, kb
102
+
103
+ @Gojo.on_callback_query(filters.regex(r"^next_format_.*[0-9]$"))
104
+ async def change_formatting_page(c: Gojo, q: CallbackQuery):
105
+ page = q.data.split("_")[-1]
106
+ txt, kb = await get_splited_formatting(md_txt, int(page))
107
+ await q.edit_message_caption(txt, reply_markup=kb,parse_mode=enums.ParseMode.HTML,)
108
+ return
109
+
110
+ @Gojo.on_callback_query(filters.regex("^formatting."))
111
+ async def get_formatting_info(c: Gojo, q: CallbackQuery):
112
+ cmd = q.data.split(".")[1]
113
+ kb = ikb([[("Back", "back.formatting")]])
114
+
115
+ if cmd == "md_formatting":
116
+
117
  try:
118
  await q.edit_message_caption(
119
+ caption=md_txt,
120
  reply_markup=kb,
121
  parse_mode=enums.ParseMode.HTML,
122
  )
123
  except MediaCaptionTooLong:
124
+ txt, kb = await get_splited_formatting(md_txt)
125
+ await q.edit_message_caption(
126
+ caption=txt,
127
+ reply_markup=kb,
128
  parse_mode=enums.ParseMode.HTML,
129
+ )
130
  elif cmd == "fillings":
131
  await q.edit_message_caption(
132
  caption="""<b>Fillings</b>
Powers/plugins/locks.py CHANGED
@@ -36,7 +36,9 @@ l_t = """
36
  - `forwardall` = Forwarding from channel and user
37
  - `forwardu` = Forwarding from user
38
  - `forwardc` = Forwarding from channel
39
- - `links | url` = Lock links"""
 
 
40
 
41
 
42
  @Gojo.on_message(command("locktypes"))
 
36
  - `forwardall` = Forwarding from channel and user
37
  - `forwardu` = Forwarding from user
38
  - `forwardc` = Forwarding from channel
39
+ - `links | url` = Lock links
40
+ - `bot` = Adding bot will be forbidden
41
+ """
42
 
43
 
44
  @Gojo.on_message(command("locktypes"))
Powers/plugins/start.py CHANGED
@@ -18,8 +18,9 @@ from Powers.utils.custom_filters import command
18
  from Powers.utils.extras import StartPic
19
  from Powers.utils.kbhelpers import ikb
20
  from Powers.utils.parser import mention_html
21
- from Powers.utils.start_utils import (gen_cmds_kb, gen_start_kb, get_help_msg,
22
- get_private_note, get_private_rules)
 
23
  from Powers.utils.string import encode_decode
24
  from Powers.vars import Config
25
 
@@ -85,7 +86,7 @@ async def start(c: Gojo, m: Message):
85
  await get_private_rules(c, m, help_option)
86
  return
87
 
88
- help_msg, help_kb = await get_help_msg(c, m, help_option)
89
 
90
  if not help_msg:
91
  return
@@ -219,7 +220,7 @@ async def help_menu(c: Gojo, m: Message):
219
  if len(m.text.split()) >= 2:
220
  textt = m.text.replace(" ", "_",).replace("_", " ", 1)
221
  help_option = (textt.split(None)[1]).lower()
222
- help_msg, help_kb = await get_help_msg(c, m, help_option)
223
 
224
  if not help_msg:
225
  LOGGER.error(
@@ -291,6 +292,64 @@ Commands available:
291
  return
292
 
293
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
  @Gojo.on_callback_query(filters.regex("^bot_curr_info$"))
295
  async def give_curr_info(c: Gojo, q: CallbackQuery):
296
  start = time()
@@ -323,17 +382,20 @@ async def get_module_info(c: Gojo, q: CallbackQuery):
323
  reply_markup=ikb(help_kb, True, todo="commands"),
324
  )
325
  except MediaCaptionTooLong:
326
- kb = ikb([[("Back", "DELETEEEE")]])
327
- await c.send_message(chat_id=q.message.chat.id, text=help_msg, reply_markup=kb)
 
 
 
 
328
  await q.answer()
329
  return
330
 
331
- DEV_USERS = get_support_staff("dev")
332
- SUDO_USERS = get_support_staff("sudo")
333
-
334
 
335
  @Gojo.on_callback_query(filters.regex("^give_bot_staffs$"))
336
  async def give_bot_staffs(c: Gojo, q: CallbackQuery):
 
 
337
  try:
338
  owner = await c.get_users(OWNER_ID)
339
  reply = f"<b>🌟 Owner:</b> {(await mention_html(owner.first_name, OWNER_ID))} (<code>{OWNER_ID}</code>)\n"
 
18
  from Powers.utils.extras import StartPic
19
  from Powers.utils.kbhelpers import ikb
20
  from Powers.utils.parser import mention_html
21
+ from Powers.utils.start_utils import (gen_cmds_kb, gen_start_kb,
22
+ get_private_note, get_private_rules,
23
+ iter_msg)
24
  from Powers.utils.string import encode_decode
25
  from Powers.vars import Config
26
 
 
86
  await get_private_rules(c, m, help_option)
87
  return
88
 
89
+ help_msg, help_kb = await iter_msg(c, m, help_option)
90
 
91
  if not help_msg:
92
  return
 
220
  if len(m.text.split()) >= 2:
221
  textt = m.text.replace(" ", "_",).replace("_", " ", 1)
222
  help_option = (textt.split(None)[1]).lower()
223
+ help_msg, help_kb = await iter_msg(c, m, help_option)
224
 
225
  if not help_msg:
226
  LOGGER.error(
 
292
  return
293
 
294
 
295
+ async def get_divided_msg(plugin_name: str, page:int=1, back_to_do = None):
296
+ msg = HELP_COMMANDS[plugin_name]["help_msg"]
297
+ msg = msg.split("\n")
298
+ l = len(msg)
299
+ new_msg = ""
300
+ total = l // 10
301
+ first = 10 * (page - 1)
302
+ last = 10 * page
303
+
304
+ if not first:
305
+ for i in msg[first:last]:
306
+ new_msg += f"{i}\n"
307
+ kb = [
308
+ [
309
+ ("Next page ▶️", f"iter_page_{plugin_name}_{(back_to_do+'_') if back_to_do else ''}{page+1}")
310
+ ]
311
+ ]
312
+ else:
313
+ first += 1
314
+ if page == total:
315
+ for i in msg[first:]:
316
+ new_msg += f"{i}\n"
317
+ kb = [
318
+ [
319
+ ("◀️ Previous page", f"iter_page_{plugin_name}_{(back_to_do+'_') if back_to_do else ''}{page-1}")
320
+ ]
321
+ ]
322
+ else:
323
+ for i in msg[first:last]:
324
+ new_msg += f"{i}\n"
325
+ kb = [
326
+ [
327
+ ("◀️ Previous page", f"iter_page_{plugin_name}_{(back_to_do+'_') if back_to_do else ''}{page-1}"),
328
+ ("Next page ▶️", f"iter_page_{plugin_name}_{(back_to_do+'_') if back_to_do else ''}{page+1}")
329
+ ]
330
+ ]
331
+ if back_to_do:
332
+ kb = ikb(kb, True, back_to_do)
333
+ else:
334
+ kb = ikb(kb)
335
+
336
+ return new_msg, kb
337
+
338
+ @Gojo.on_callback_query(filters.regex(r"^iter_page_.*[0-9]$"))
339
+ async def helppp_page_iter(c: Gojo, q: CallbackQuery):
340
+ data = q.data.split("_")
341
+ plugin_ = data[2]
342
+ try:
343
+ back_to = data[-2]
344
+ except:
345
+ back_to = None
346
+ curr_page = int(data[-1])
347
+ msg, kb = await get_divided_msg(plugin_, curr_page, back_to_do=back_to)
348
+
349
+ await q.edit_message_caption(msg, reply_markup=kb)
350
+ return
351
+
352
+
353
  @Gojo.on_callback_query(filters.regex("^bot_curr_info$"))
354
  async def give_curr_info(c: Gojo, q: CallbackQuery):
355
  start = time()
 
382
  reply_markup=ikb(help_kb, True, todo="commands"),
383
  )
384
  except MediaCaptionTooLong:
385
+ caption, kb = await get_divided_msg(f"plugins.{module}", back_to_do="commands")
386
+ await q.edit_message_caption(
387
+ caption,
388
+ parse_mode=enums.ParseMode.MARKDOWN,
389
+ reply_markup=kb
390
+ )
391
  await q.answer()
392
  return
393
 
 
 
 
394
 
395
  @Gojo.on_callback_query(filters.regex("^give_bot_staffs$"))
396
  async def give_bot_staffs(c: Gojo, q: CallbackQuery):
397
+ DEV_USERS = get_support_staff("dev")
398
+ SUDO_USERS = get_support_staff("sudo")
399
  try:
400
  owner = await c.get_users(OWNER_ID)
401
  reply = f"<b>🌟 Owner:</b> {(await mention_html(owner.first_name, OWNER_ID))} (<code>{OWNER_ID}</code>)\n"
Powers/plugins/web_con.py CHANGED
@@ -1,20 +1,21 @@
1
  import asyncio
2
  import os
 
3
  from traceback import format_exc
4
 
5
  from pyrogram import filters
6
  from pyrogram.types import CallbackQuery
7
  from pyrogram.types import InlineKeyboardButton as IKB
8
  from pyrogram.types import InlineKeyboardMarkup as IKM
9
- from pyrogram.types import Message
10
 
11
- from Powers import (LOGGER, RMBG, Audd, genius_lyrics, is_audd,
12
- is_genius_lyrics, is_rmbg)
13
  from Powers.bot_class import Gojo
14
  from Powers.utils.custom_filters import command
15
  from Powers.utils.http_helper import *
16
  from Powers.utils.sticker_help import toimage
17
  from Powers.utils.web_helpers import *
 
18
 
19
  # @Gojo.on_message(command(["songname","insong","songinfo","whichsong","rsong","reversesong"]))
20
  # • /whichsong (/songname, /songinfo, /insong, /rsong, /reversesong) : Reply to file to get the song playing in it.
@@ -254,15 +255,15 @@ async def song_down_up(c: Gojo, m: Message):
254
  except IndexError:
255
  await m.reply_text("**USAGE**\n /song [song name | link]")
256
  return
257
- if splited.startswith("https://youtube.com"):
258
- is_direct = True
259
- query = splited.split("?")[0]
 
260
  else:
261
- is_direct = False
262
- query = splited
263
  XnX = await m.reply_text("⏳")
264
  try:
265
- await youtube_downloader(c,m,query,is_direct,"a")
266
  await XnX.delete()
267
  return
268
  except KeyError:
@@ -281,15 +282,15 @@ async def video_down_up(c: Gojo, m: Message):
281
  except IndexError:
282
  await m.reply_text("**USAGE**\n /vsong [song name | link]")
283
  return
284
- if splited.startswith("https://youtube.com"):
285
- is_direct = True
286
- query = splited.split("?")[0]
 
287
  else:
288
- is_direct = False
289
- query = splited
290
  XnX = await m.reply_text("⏳")
291
  try:
292
- await youtube_downloader(c,m,query,is_direct,"v")
293
  await XnX.delete()
294
  return
295
  except KeyError:
@@ -306,27 +307,44 @@ async def download_instareels(c: Gojo, m: Message):
306
  try:
307
  reel_ = m.command[1]
308
  except IndexError:
309
- await m.reply_text("Give me an link to download it...")
310
  return
311
- if not reel_.startswith("https://www.instagram.com/reel/"):
312
- await m.reply_text("In order to obtain the requested reel, a valid link is necessary. Kindly provide me with the required link.")
 
 
 
313
  return
314
- OwO = reel_.split(".",1)
315
- Reel_ = ".dd".join(OwO)
316
- try:
317
- await m.reply_video(Reel_)
 
 
 
318
  return
319
- except Exception:
320
- try:
321
- await m.reply_photo(Reel_)
322
- return
323
- except Exception:
324
- try:
325
- await m.reply_document(Reel_)
326
- return
327
- except Exception:
328
- await m.reply_text("I am unable to reach to this reel.")
329
- return
 
 
 
 
 
 
 
 
 
 
 
330
 
331
  __PLUGIN__ = "web support"
332
 
 
1
  import asyncio
2
  import os
3
+ import shutil
4
  from traceback import format_exc
5
 
6
  from pyrogram import filters
7
  from pyrogram.types import CallbackQuery
8
  from pyrogram.types import InlineKeyboardButton as IKB
9
  from pyrogram.types import InlineKeyboardMarkup as IKM
10
+ from pyrogram.types import InputMediaPhoto, InputMediaVideo, Message
11
 
12
+ from Powers import LOGGER, RMBG, genius_lyrics, is_genius_lyrics, is_rmbg
 
13
  from Powers.bot_class import Gojo
14
  from Powers.utils.custom_filters import command
15
  from Powers.utils.http_helper import *
16
  from Powers.utils.sticker_help import toimage
17
  from Powers.utils.web_helpers import *
18
+ from Powers.utils.web_scrapper import INSTAGRAM, SCRAP_DATA
19
 
20
  # @Gojo.on_message(command(["songname","insong","songinfo","whichsong","rsong","reversesong"]))
21
  # • /whichsong (/songname, /songinfo, /insong, /rsong, /reversesong) : Reply to file to get the song playing in it.
 
255
  except IndexError:
256
  await m.reply_text("**USAGE**\n /song [song name | link]")
257
  return
258
+ _id = get_video_id(splited)
259
+ if not _id:
260
+ await m.reply_text("Invalid youtube link")
261
+ return
262
  else:
263
+ query = _id
 
264
  XnX = await m.reply_text("⏳")
265
  try:
266
+ await youtube_downloader(c,m,query, "a")
267
  await XnX.delete()
268
  return
269
  except KeyError:
 
282
  except IndexError:
283
  await m.reply_text("**USAGE**\n /vsong [song name | link]")
284
  return
285
+ _id = get_video_id(splited)
286
+ if not _id:
287
+ await m.reply_text("Invalid youtube link")
288
+ return
289
  else:
290
+ query = _id
 
291
  XnX = await m.reply_text("⏳")
292
  try:
293
+ await youtube_downloader(c,m,query,"v")
294
  await XnX.delete()
295
  return
296
  except KeyError:
 
307
  try:
308
  reel_ = m.command[1]
309
  except IndexError:
310
+ await m.reply_text("Give me an instagram link to download it...")
311
  return
312
+
313
+ insta = INSTAGRAM(reel_)
314
+
315
+ if not insta.is_correct_link():
316
+ await m.reply_text("The link you have provided is not of instagram")
317
  return
318
+
319
+ to_edit = await m.reply_text("Trying to fetch data from the link")
320
+
321
+ content = insta.get_all()
322
+
323
+ if type(content) == str:
324
+ await to_edit.edit_text(content)
325
  return
326
+ elif not content:
327
+ await to_edit.edit_text("Failed to get any media from the link")
328
+
329
+ videos = content["video"]
330
+ images = content["image"]
331
+
332
+ to_delete = await to_edit.edit_text("Found media in the link trying to download and upload them please wait")
333
+
334
+ to_send = []
335
+ if images:
336
+ scrapped_images = SCRAP_DATA(images).get_images()
337
+ for i in scrapped_images:
338
+ to_send.append(InputMediaPhoto(i))
339
+ if videos:
340
+ scrapped_videos = SCRAP_DATA(videos).get_videos()
341
+ for i in scrapped_videos:
342
+ to_send.append(InputMediaVideo(i))
343
+
344
+ await m.reply_media_group(to_send)
345
+ await to_delete.delete()
346
+ shutil.rmtree("./scrapped/")
347
+
348
 
349
  __PLUGIN__ = "web support"
350
 
Powers/utils/custom_filters.py CHANGED
@@ -154,7 +154,7 @@ async def admin_check_func(_, __, m: Message or CallbackQuery):
154
  return False
155
 
156
  # Telegram and GroupAnonyamousBot
157
- if m.sender_chat:
158
  return True
159
 
160
  if not m.from_user:
 
154
  return False
155
 
156
  # Telegram and GroupAnonyamousBot
157
+ if m.sender_chat and m.sender_chat.id == m.chat.id:
158
  return True
159
 
160
  if not m.from_user:
Powers/utils/extras.py CHANGED
@@ -518,6 +518,7 @@ DECIDE = ("Yes.", "No.", "Maybe.", "Who the hell cares?",
518
  "No one give a damn about it")
519
 
520
  INSULT_STRINGS = [
 
521
  "`Owww ... Such a stupid idiot.`",
522
  "`Don't drink and type.`",
523
  "`Command not found. Just like your brain.`",
 
518
  "No one give a damn about it")
519
 
520
  INSULT_STRINGS = [
521
+ "Tell me\nYou are gay becauce you are you or you are you that's why you are gay?"
522
  "`Owww ... Such a stupid idiot.`",
523
  "`Don't drink and type.`",
524
  "`Command not found. Just like your brain.`",
Powers/utils/sticker_help.py CHANGED
@@ -85,11 +85,10 @@ async def create_sticker(
85
  return raw.types.InputStickerSetItem(document=sticker, emoji=emoji)
86
 
87
 
88
- STICKER_DIMENSIONS = (512, 512)
89
-
90
 
91
  async def resize_file_to_sticker_size(file_path: str, length: int = 512, width: int = 512) -> str:
92
  im = Image.open(file_path)
 
93
  if (im.width, im.height) < STICKER_DIMENSIONS:
94
  size1 = im.width
95
  size2 = im.height
 
85
  return raw.types.InputStickerSetItem(document=sticker, emoji=emoji)
86
 
87
 
 
 
88
 
89
  async def resize_file_to_sticker_size(file_path: str, length: int = 512, width: int = 512) -> str:
90
  im = Image.open(file_path)
91
+ STICKER_DIMENSIONS = (length, width)
92
  if (im.width, im.height) < STICKER_DIMENSIONS:
93
  size1 = im.width
94
  size2 = im.height
Powers/utils/web_helpers.py CHANGED
@@ -6,10 +6,10 @@ from urllib import parse
6
  from pyrogram.types import InlineKeyboardButton as IKB
7
  from pyrogram.types import InlineKeyboardMarkup as IKM
8
  from pyrogram.types import Message
9
- # import yt_dlp
10
- from pytube import YouTube
11
- from youtubesearchpython.__future__ import Video, VideosSearch
12
 
 
13
  from Powers.bot_class import LOGGER, MESSAGE_DUMP, Gojo
14
  from Powers.utils.http_helper import *
15
  from Powers.utils.sticker_help import resize_file_to_sticker_size
@@ -45,6 +45,15 @@ async def get_file_size(file: Message):
45
  size = size/1024
46
  return f"{round(size)} gb"
47
 
 
 
 
 
 
 
 
 
 
48
 
49
  def get_duration_in_sec(dur: str):
50
  duration = dur.split(":")
@@ -57,14 +66,9 @@ def get_duration_in_sec(dur: str):
57
  # Gets yt result of given query.
58
 
59
 
60
- async def song_search(query, is_direct, max_results=1):
61
  yt_dict = {}
62
  try:
63
- if is_direct:
64
- vid = Video.getInfo(query)
65
- query = vid["title"]
66
- else:
67
- query = query
68
  videos = VideosSearch(query, max_results)
69
  results = await videos.next()
70
  except Exception as e:
@@ -93,7 +97,7 @@ async def song_search(query, is_direct, max_results=1):
93
  "uploader": i["channel"]["name"]
94
  }
95
  try:
96
- thumb = {"thumbnail": i["richThumbnail"]["url"]}
97
  except Exception:
98
  thumb = {"thumbnail": None}
99
  dict_form.update(thumb)
@@ -103,45 +107,6 @@ async def song_search(query, is_direct, max_results=1):
103
  pass
104
  return yt_dict
105
 
106
- """song_opts = {
107
- "format": "bestaudio",
108
- "addmetadata": True,
109
- "key": "FFmpegMetadata",
110
- "writethumbnail": True,
111
- "prefer_ffmpeg": True,
112
- "geo_bypass": True,
113
- "nocheckcertificate": True,
114
- "postprocessors": [
115
- {
116
- "key": "FFmpegExtractAudio",
117
- "preferredcodec": "mp3",
118
- "preferredquality": "480",
119
- }
120
- ],
121
- "outtmpl": "%(id)s.mp3",
122
- "quiet": True,
123
- "logtostderr": False,
124
- }
125
-
126
-
127
- video_opts = {
128
- "format": "best",
129
- "addmetadata": True,
130
- "key": "FFmpegMetadata",
131
- "prefer_ffmpeg": True,
132
- "geo_bypass": True,
133
- "nocheckcertificate": True,
134
- "postprocessors": [
135
- {
136
- "key": "FFmpegVideoConvertor",
137
- "preferedformat": "mp4",
138
- }
139
- ],
140
- "outtmpl": "%(id)s.mp4",
141
- "logtostderr": False,
142
- "quiet": True,
143
- }"""
144
-
145
 
146
  async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, type_: str):
147
  if type_ == "a":
@@ -164,6 +129,9 @@ async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, t
164
  except KeyError:
165
  return
166
  yt = YouTube(query)
 
 
 
167
  dicti = dicti[1]
168
  f_name = dicti["title"]
169
  views = dicti["views"]
@@ -204,19 +172,18 @@ Downloaded by: @{c.me.username}
204
  if song:
205
  audio_stream = yt.streams.filter(only_audio=True).first()
206
  f_path = audio_stream.download()
207
- # file_path = f"./youtube_downloads/{f_name.strip()}.mp3"
208
- file_path = f"./{f_name.strip()}.mp3"
209
  os.rename(f_path, file_path)
210
- await m.reply_audio(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, title=f_name)
211
- # os.remove(f_path)
212
  os.remove(file_path)
213
  os.remove(thumb)
214
  return
215
  elif video:
216
  video_stream = yt.streams.get_highest_resolution()
217
  file_path = video_stream.download()
218
- # file_path = f"./youtube_downloads/{f_name}.mp4"
 
219
  await m.reply_video(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb)
220
- os.remove(file_path)
221
  os.remove(thumb)
222
  return
 
6
  from pyrogram.types import InlineKeyboardButton as IKB
7
  from pyrogram.types import InlineKeyboardMarkup as IKM
8
  from pyrogram.types import Message
9
+ from pytube import YouTube, extract
10
+ from youtubesearchpython.__future__ import VideosSearch
 
11
 
12
+ from Powers import youtube_dir
13
  from Powers.bot_class import LOGGER, MESSAGE_DUMP, Gojo
14
  from Powers.utils.http_helper import *
15
  from Powers.utils.sticker_help import resize_file_to_sticker_size
 
45
  size = size/1024
46
  return f"{round(size)} gb"
47
 
48
+ def get_video_id(url):
49
+ try:
50
+ _id = extract.video_id(url)
51
+ if not _id:
52
+ return None
53
+ else:
54
+ return _id
55
+ except:
56
+ return None
57
 
58
  def get_duration_in_sec(dur: str):
59
  duration = dur.split(":")
 
66
  # Gets yt result of given query.
67
 
68
 
69
+ async def song_search(query, max_results=1):
70
  yt_dict = {}
71
  try:
 
 
 
 
 
72
  videos = VideosSearch(query, max_results)
73
  results = await videos.next()
74
  except Exception as e:
 
97
  "uploader": i["channel"]["name"]
98
  }
99
  try:
100
+ thumb = {"thumbnail": i["thumbnails"][0]["url"]}
101
  except Exception:
102
  thumb = {"thumbnail": None}
103
  dict_form.update(thumb)
 
107
  pass
108
  return yt_dict
109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
 
111
  async def youtube_downloader(c: Gojo, m: Message, query: str, is_direct: bool, type_: str):
112
  if type_ == "a":
 
129
  except KeyError:
130
  return
131
  yt = YouTube(query)
132
+ if yt.age_restricted:
133
+ await m.reply_text("This video is age restricted")
134
+ return
135
  dicti = dicti[1]
136
  f_name = dicti["title"]
137
  views = dicti["views"]
 
172
  if song:
173
  audio_stream = yt.streams.filter(only_audio=True).first()
174
  f_path = audio_stream.download()
175
+ file_path = f"{youtube_dir}{f_name.strip()}.mp3"
 
176
  os.rename(f_path, file_path)
177
+ await m.reply_audio(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb, title=f_name,performer=uploader)
 
178
  os.remove(file_path)
179
  os.remove(thumb)
180
  return
181
  elif video:
182
  video_stream = yt.streams.get_highest_resolution()
183
  file_path = video_stream.download()
184
+ new_file_path = f"{youtube_dir}{f_name}.mp4"
185
+ os.rename(file_path, new_file_path)
186
  await m.reply_video(file_path, caption=cap, reply_markup=kb, duration=vid_dur, thumb=thumb)
187
+ os.remove(new_file_path)
188
  os.remove(thumb)
189
  return
Powers/utils/web_scrapper.py ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import time
4
+ from typing import List
5
+
6
+ import requests
7
+ from selenium import webdriver
8
+ from selenium.webdriver.chrome.options import Options
9
+ from selenium.webdriver.chrome.service import Service
10
+ from selenium.webdriver.common.by import By
11
+ from selenium.webdriver.support.expected_conditions import \
12
+ presence_of_element_located
13
+ from selenium.webdriver.support.wait import WebDriverWait
14
+
15
+ from Powers import *
16
+
17
+
18
+ class SCRAP_DATA:
19
+ """Class to get and handel scrapped data"""
20
+
21
+ def __init__(self, urls: List[str] or str) -> None:
22
+ self.urls = urls
23
+ self.path = "./scrapped/"
24
+ if not os.path.isdir(self.path):
25
+ os.makedirs("./scrapped/")
26
+
27
+ def get_images(self) -> list:
28
+ images = []
29
+ if isinstance(self.urls, str):
30
+ requested = requests.get(self.urls)
31
+ try:
32
+ name = self.path + f"img_{time.time()}.jpg"
33
+ with open(name, "wb") as f:
34
+ f.write(requested.content)
35
+ images.append(name)
36
+ except Exception as e:
37
+ LOGGER.error(e)
38
+ requested.close()
39
+ else:
40
+ for i in self.urls:
41
+ if i:
42
+ requested = requests.get(i)
43
+ else:
44
+ continue
45
+ try:
46
+ name = self.path + f"img_{time.time()}.jpg"
47
+ with open(name, "wb") as f:
48
+ f.write(requested.content)
49
+ images.append(name)
50
+ except Exception as e:
51
+ LOGGER.error(e)
52
+ requested.close()
53
+ continue
54
+ return images
55
+
56
+ def get_videos(self) -> list:
57
+ videos = []
58
+ if isinstance(self.urls, str):
59
+ if i:
60
+ requested = requests.get(i)
61
+ else:
62
+ return []
63
+ try:
64
+ name = self.path + f"vid_{time.time()}.mp4"
65
+ with open(name, "wb") as f:
66
+ f.write(requested.content)
67
+ videos.append(name)
68
+ except Exception as e:
69
+ LOGGER.error(e)
70
+ requested.close()
71
+ else:
72
+ for i in self.urls:
73
+ if i:
74
+ requested = requests.get(i)
75
+ else:
76
+ continue
77
+ try:
78
+ name = self.path + f"vid_{time.time()}.mp4"
79
+ with open(name, "wb") as f:
80
+ f.write(requested.content)
81
+ videos.append(name)
82
+ except Exception as e:
83
+ LOGGER.error(e)
84
+ requested.close()
85
+ continue
86
+ return videos
87
+
88
+
89
+ class DRIVER:
90
+ """Class to make selenium driver"""
91
+
92
+ def __init__(self) -> None:
93
+ self.BIN = CHROME_BIN
94
+ self.CHROME_DRIVER = CHROME_DRIVER
95
+
96
+ def initialize_driver(self):
97
+ if not self.BIN:
98
+ LOGGER.error(
99
+ "ChromeBinaryErr: No binary path found! Install Chromium or Google Chrome.")
100
+ return (
101
+ None,
102
+ "ChromeBinaryErr: No binary path found! Install Chromium or Google Chrome.",
103
+ )
104
+
105
+ try:
106
+ options = Options()
107
+ options.binary_location = self.BIN
108
+ options.add_argument("--disable-dev-shm-usage")
109
+ options.add_argument("--ignore-certificate-errors")
110
+ options.add_argument("--disable-gpu")
111
+ options.add_argument("--headless=new")
112
+ options.add_argument("--test-type")
113
+ options.add_argument("--no-sandbox")
114
+
115
+ service = Service(self.CHROME_DRIVER)
116
+ driver = webdriver.Chrome(options, service)
117
+ return driver, None
118
+ except Exception as e:
119
+ LOGGER.error(f"ChromeDriverErr: {e}")
120
+ return None, f"ChromeDriverErr: {e}"
121
+
122
+ def driver_close(self, driver: webdriver.Chrome):
123
+ driver.close()
124
+ driver.quit()
125
+
126
+
127
+ class INSTAGRAM(DRIVER):
128
+ """Class to scrap data from instagram"""
129
+
130
+ def __init__(self, url: str) -> None:
131
+ self.url = url
132
+ self.article = "article._aa6a"
133
+ self.ul_class = "_acay"
134
+ self.image_class = "x5yr21d"
135
+ self.video_class = "x1lliihq"
136
+ self.next_button = "button._afxw"
137
+ self.return_dict = {"image": [], "video": []}
138
+ super().__init__()
139
+
140
+ def is_correct_link(self):
141
+ return bool((re.compile(r"^https?://(?:www\.)?instagram\.com/")).match(self.url))
142
+
143
+ def get_all(self):
144
+ driver, error = self.initialize_driver()
145
+ if not driver:
146
+ return error
147
+
148
+ driver.get(self.url)
149
+ wait = WebDriverWait(driver, 30)
150
+ if "reel" in self.url:
151
+ element = wait.until(
152
+ presence_of_element_located((By.TAG_NAME, "video")))
153
+ reels = element.get_attribute("src")
154
+ self.driver_close(driver)
155
+ self.return_dict.get("video").append(reels)
156
+ return self.return_dict
157
+ elif bool((re.compile(r"^https?://(?:www\.)?instagram\.com/p/")).match(self.url)):
158
+ image_links = []
159
+ video_links = []
160
+ try:
161
+ element = wait.until(presence_of_element_located(
162
+ (By.CLASS_NAME, self.ul_class)))
163
+
164
+ while True:
165
+ sub_element = element.find_elements(
166
+ By.CLASS_NAME, self.image_class)
167
+ for i in sub_element:
168
+ url = i.get_attribute("src")
169
+ image_links.append(url)
170
+
171
+ sub_element = element.find_elements(
172
+ By.CLASS_NAME, self.video_class)
173
+ for i in sub_element:
174
+ url = i.get_attribute("src")
175
+ video_links.append(url)
176
+
177
+ try:
178
+ driver.find_element(
179
+ By.CSS_SELECTOR, self.next_button).click()
180
+ except: # Failed to either find the element or click on next i.e. no more media left in post
181
+ break
182
+ except:
183
+ element = wait.until(presence_of_element_located(
184
+ (By.CSS_SELECTOR, self.article)))
185
+ try:
186
+ sub_element = element.find_element(By.TAG_NAME, "img")
187
+ image_links.append(sub_element.get_attribute("src"))
188
+ except:
189
+ sub_element = element.find_element(By.TAG_NAME, "video")
190
+ video_links.append(sub_element.get_attribute("src"))
191
+
192
+ self.driver_close(driver)
193
+ # To remove duplicates here I am converting into set
194
+ if image_links:
195
+ image_links = list(set(image_links))
196
+ if video_links:
197
+ video_links = list(set(video_links))
198
+ for i in video_links:
199
+ image_links.remove(i)
200
+
201
+ self.return_dict.get("image").extend(image_links)
202
+ self.return_dict.get("video").extend(video_links)
203
+ return self.return_dict
204
+
205
+ else:
206
+ return {}
207
+
Powers/vars.py CHANGED
@@ -1,3 +1,4 @@
 
1
  from os import getcwd
2
 
3
  from prettyconf import Configuration
@@ -34,9 +35,11 @@ class Config:
34
  int(i)
35
  for i in config(
36
  "WHITELIST_USERS",
37
- default="",
38
  ).split(None)
39
  ]
 
 
40
  GENIUS_API_TOKEN = config("GENIUS_API", default=None)
41
  # AuDD_API = config("AuDD_API",default=None)
42
  RMBG_API = config("RMBG_API", default=None)
@@ -80,3 +83,5 @@ class Development:
80
  TIME_ZONE = 'Asia/Kolkata'
81
  BDB_URI = ""
82
  WORKERS = 8
 
 
 
1
+ from email.policy import default
2
  from os import getcwd
3
 
4
  from prettyconf import Configuration
 
35
  int(i)
36
  for i in config(
37
  "WHITELIST_USERS",
38
+ default=""
39
  ).split(None)
40
  ]
41
+ CHROME_BIN = config("CHROME_BIN", "/app/.apt/usr/bin/google-chrome")
42
+ CHROME_DRIVER = config("CHROME_DRIVER", default="/app/.chromedriver/bin/chromedriver")
43
  GENIUS_API_TOKEN = config("GENIUS_API", default=None)
44
  # AuDD_API = config("AuDD_API",default=None)
45
  RMBG_API = config("RMBG_API", default=None)
 
83
  TIME_ZONE = 'Asia/Kolkata'
84
  BDB_URI = ""
85
  WORKERS = 8
86
+ CHROME_BIN = "/app/.apt/usr/bin/google-chrome"
87
+ CHROME_DRIVER = "/app/.chromedriver/bin/chromedriver"
README.md CHANGED
@@ -213,6 +213,10 @@ If all works well, the bot should send a message to the MESSAGE_DUMP Group!--->
213
 
214
  `WHITELIST_USERS`: A space-separated list of user IDs whitelisted, cannot be restricted.
215
 
 
 
 
 
216
  ⚠️ **Note:** In case you are passing more than one value separate them using whitespace (space) for example If I want to pass more than one PREFIX_HANDLER
217
  I'll pass it like `'/' '.' '!'` this.
218
 
 
213
 
214
  `WHITELIST_USERS`: A space-separated list of user IDs whitelisted, cannot be restricted.
215
 
216
+ `CHROME_BIN`: Location of your chrome bin.
217
+
218
+ `CHROME_DRIVER`: Location of your chrome driver.
219
+
220
  ⚠️ **Note:** In case you are passing more than one value separate them using whitespace (space) for example If I want to pass more than one PREFIX_HANDLER
221
  I'll pass it like `'/' '.' '!'` this.
222
 
app.json CHANGED
@@ -104,6 +104,16 @@
104
  "required": false,
105
  "value": "8"
106
  },
 
 
 
 
 
 
 
 
 
 
107
  "ENV": {
108
  "description": "Setting this to ANYTHING will enable environment variables. Leave it as it is",
109
  "required": true,
@@ -114,6 +124,15 @@
114
  {
115
  "url":"https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest"
116
  },
 
 
 
 
 
 
 
 
 
117
  {
118
  "url": "heroku/python"
119
  }
 
104
  "required": false,
105
  "value": "8"
106
  },
107
+ "CHROME_DRIVER": {
108
+ "description": "Location of chrome driver",
109
+ "required": false,
110
+ "value": "/app/.chromedriver/bin/chromedriver"
111
+ },
112
+ "CHROME_BIN" : {
113
+ "description": "Location of chrome bin",
114
+ "required": false,
115
+ "value": "/app/.apt/usr/bin/google-chrome"
116
+ },
117
  "ENV": {
118
  "description": "Setting this to ANYTHING will enable environment variables. Leave it as it is",
119
  "required": true,
 
124
  {
125
  "url":"https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest"
126
  },
127
+ {
128
+ "url": "https://github.com/chrismytton/heroku-buildpack-jq"
129
+ },
130
+ {
131
+ "url":"https://github.com/heroku/heroku-buildpack-google-chrome"
132
+ },
133
+ {
134
+ "url":"https://github.com/heroku/heroku-buildpack-chromedriver"
135
+ },
136
  {
137
  "url": "heroku/python"
138
  }
requirements.txt CHANGED
@@ -27,6 +27,7 @@ regex==2023.12.25; python_version >= "3.6"
27
  requests==2.31.0
28
  rfc3986==1.5.0; python_version >= "3.7"
29
  search-engine-parser==0.6.8
 
30
  six==1.16.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0"
31
  sniffio==1.3.0; python_full_version >= "3.6.2" and python_version >= "3.7"
32
  soupsieve==2.4; python_version >= "3.6" and python_full_version >= "3.6.0"
 
27
  requests==2.31.0
28
  rfc3986==1.5.0; python_version >= "3.7"
29
  search-engine-parser==0.6.8
30
+ selenium==4.18.1
31
  six==1.16.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0"
32
  sniffio==1.3.0; python_full_version >= "3.6.2" and python_version >= "3.7"
33
  soupsieve==2.4; python_version >= "3.6" and python_full_version >= "3.6.0"