Captain Ezio commited on
Commit
4e42594
·
1 Parent(s): 67305b5

All new features done. To do bug hunting....

Browse files
Powers/plugins/stickers.py CHANGED
@@ -64,7 +64,7 @@ async def sticker_id_gib(c: Gojo, m: Message):
64
  async def kang(c:Gojo, m: Message):
65
  if not m.reply_to_message:
66
  return await m.reply_text("Reply to a sticker or image to kang it.")
67
- elif not (m.reply_to_message.sticker or m.reply_to_message.photo or (m.reply_to_message.document and m.reply_to_message.document.mime_type.split("/")[0]=="image")):
68
  return await m.reply_text("Reply to a sticker or image to kang it.")
69
  if not m.from_user:
70
  return await m.reply_text("You are anon admin, kang stickers in my pm.")
@@ -92,7 +92,7 @@ async def kang(c:Gojo, m: Message):
92
 
93
  # Get the corresponding fileid, resize the file if necessary
94
  try:
95
- if is_requ or m.reply_to_message.photo or (m.reply_to_message.document and m.reply_to_message.document.mime_type.split("/")[0]=="image"):
96
  sizee = (await get_file_size(m.reply_to_message)).split()
97
  if (sizee[1] == "mb" and sizee > 10) or sizee[1] == "gb":
98
  await m.reply_text("File size is too big")
@@ -113,8 +113,11 @@ async def kang(c:Gojo, m: Message):
113
  LOGGER.error(format_exc())
114
  return
115
  try:
116
- if is_requ or not m.reply_to_message.sticker:
117
  # telegram doesn't allow animated and video sticker to be kanged as we do for normal stickers
 
 
 
118
  sticker = await create_sticker(
119
  await upload_document(
120
  c, path, m.chat.id
@@ -283,27 +286,40 @@ async def get_sticker_from_file(c: Gojo, m: Message):
283
  await m.reply_text("Reply to a sticker or file")
284
  return
285
  repl = m.reply_to_message
286
- if not (repl.sticker or repl.photo or (repl.document and repl.document.mime_type.split("/")[0]=="image")):
 
287
  await m.reply_text("I only support conversion of plain stickers and images for now")
288
  return
289
- if repl.sticker and (repl.sticker.is_video or repl.sticker.is_animated):
290
- await m.reply_text("I only support conversion of plain stickers for now")
291
- return
292
  x = await m.reply_text("Converting...")
 
293
  if repl.sticker:
294
- upp = await repl.download()
295
- up = toimage(upp,is_direc=True)
296
- await x.delete()
297
- await m.reply_photo(up,caption=Caption)
298
- os.remove(up)
299
- return
 
 
 
 
 
 
 
 
300
  elif repl.photo:
301
- upp = await repl.download()
302
  up = tosticker(upp,is_direc=True)
303
  await x.delete()
304
- await m.reply_sticker(up,caption=Caption)
305
  os.remove(up)
306
  return
 
 
 
 
 
307
 
308
 
309
  __PLUGIN__ = "sticker"
 
64
  async def kang(c:Gojo, m: Message):
65
  if not m.reply_to_message:
66
  return await m.reply_text("Reply to a sticker or image to kang it.")
67
+ elif not (m.reply_to_message.animation or m.reply_to_message.sticker or m.reply_to_message.photo or (m.reply_to_message.document and m.reply_to_message.document.mime_type.split("/")[0]in["image","video"])):
68
  return await m.reply_text("Reply to a sticker or image to kang it.")
69
  if not m.from_user:
70
  return await m.reply_text("You are anon admin, kang stickers in my pm.")
 
92
 
93
  # Get the corresponding fileid, resize the file if necessary
94
  try:
95
+ if is_requ or m.reply_to_message.video or m.reply_to_message.photo or (m.reply_to_message.document and m.reply_to_message.document.mime_type.split("/")[0]=="image"):
96
  sizee = (await get_file_size(m.reply_to_message)).split()
97
  if (sizee[1] == "mb" and sizee > 10) or sizee[1] == "gb":
98
  await m.reply_text("File size is too big")
 
113
  LOGGER.error(format_exc())
114
  return
115
  try:
116
+ if is_requ or not m.reply_to_message.sticker or m.reply_to_message.animation or m.reply_to_message.video or (m.reply_to_message.document and m.reply_to_message.document.mime_type.split("/")[0] == "video"):
117
  # telegram doesn't allow animated and video sticker to be kanged as we do for normal stickers
118
+ if m.reply_to_message.animation or m.reply_to_message.video or (m.reply_to_message.document and m.reply_to_message.document.mime_type.split("/")[0] == "video"):
119
+ path = m.reply_to_message.download()
120
+ path = Vsticker(path)
121
  sticker = await create_sticker(
122
  await upload_document(
123
  c, path, m.chat.id
 
286
  await m.reply_text("Reply to a sticker or file")
287
  return
288
  repl = m.reply_to_message
289
+ to_vid = False
290
+ if not (repl.sticker.is_animated or repl.video or repl.sticker or repl.photo or (repl.document and repl.document.mime_type.split("/")[0] in ["image","video"])):
291
  await m.reply_text("I only support conversion of plain stickers and images for now")
292
  return
293
+ if repl.video or (repl.document and repl.document.mime_type.split("/")[0]=="video"):
294
+ to_vid = True
 
295
  x = await m.reply_text("Converting...")
296
+ upp = await repl.download()
297
  if repl.sticker:
298
+ if repl.sticker.is_animated:
299
+ up = tgs_to_gif(upp,True)
300
+ await x.delete()
301
+ await m.reply_animation(up,caption=Caption)
302
+ elif repl.sticker.is_video:
303
+ up = webm_to_gif(upp)
304
+ await x.delete()
305
+ await m.reply_animation(up,caption=Caption)
306
+ else:
307
+ up = toimage(upp,is_direc=True)
308
+ await x.delete()
309
+ await m.reply_photo(up,caption=Caption)
310
+ os.remove(up)
311
+ return
312
  elif repl.photo:
 
313
  up = tosticker(upp,is_direc=True)
314
  await x.delete()
315
+ await m.reply_sticker(up)
316
  os.remove(up)
317
  return
318
+
319
+ elif to_vid:
320
+ up = Vsticker(upp)
321
+ await x.delete()
322
+ await m.reply_sticker(up)
323
 
324
 
325
  __PLUGIN__ = "sticker"
Powers/utils/sticker_help.py CHANGED
@@ -12,6 +12,19 @@ from pyrogram.file_id import FileId
12
  from Powers.bot_class import Gojo
13
 
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  async def get_sticker_set_by_name(
16
  client: Gojo, name: str
17
  ) -> raw.base.messages.StickerSet:
@@ -97,7 +110,34 @@ async def resize_file_to_sticker_size(file_path: str,length:int=512,width:int=51
97
  im.save(file_pathh)
98
  os.remove(file_path)
99
  return file_pathh
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
 
103
  async def upload_document(
@@ -136,7 +176,7 @@ async def get_document_from_file_id(
136
  )
137
 
138
 
139
- async def draw_meame(image_path: str, text: str, sticker: bool, fiill: str) -> list:
140
  _split = text.split(";", 1)
141
  if len(_split) == 2:
142
  lower_text = _split[1]
 
12
  from Powers.bot_class import Gojo
13
 
14
 
15
+ async def runcmd(cmd: str) -> Tuple[str, str, int, int]:
16
+ args = shlex.split(cmd)
17
+ process = await asyncio.create_subprocess_exec(
18
+ *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
19
+ )
20
+ stdout, stderr = await process.communicate()
21
+ return (
22
+ stdout.decode("utf-8", "replace").strip(),
23
+ stderr.decode("utf-8", "replace").strip(),
24
+ process.returncode,
25
+ process.pid,
26
+ )
27
+
28
  async def get_sticker_set_by_name(
29
  client: Gojo, name: str
30
  ) -> raw.base.messages.StickerSet:
 
110
  im.save(file_pathh)
111
  os.remove(file_path)
112
  return file_pathh
113
+
114
+ async def tgs_to_gif(file, tgs=False, video=False):
115
+ if tgs:
116
+ cmd = f"lottie_convert.py '{file}' 'gojo_satoru.gif'"
117
+ elif video:
118
+ cmd = f"ffmpeg -i '{file}' -c copy 'gojo_satoru.gif'"
119
+ await runcmd(cmd)
120
+ os.remove(file)
121
+ return 'hellbot.gif'
122
+
123
+ async def webm_to_gif(file):
124
+ cmd = f"ffmpeg -i '{file}' 'goJo.gif'"
125
+ await runcmd(cmd)
126
+ os.remove(file)
127
+ return "goJo.gif"
128
 
129
+ async def Vsticker(file: str):
130
+ _width_ = file.file.width
131
+ _height_ = file.file.height
132
+ if _height_ > _width_:
133
+ _height_, _width_ = (512, -1)
134
+ else:
135
+ _height_, _width_ = (-1, 512)
136
+ await runcmd(
137
+ f"ffmpeg -to 00:00:02.900 -i '{file}' -vf scale={_width_}:{_height_} -c:v libvpx-vp9 -crf 30 -b:v 560k -maxrate 560k -bufsize 256k -an 'VideoSticker.webm'"
138
+ )
139
+ os.remove(file)
140
+ return "VideoSticker.webm"
141
 
142
 
143
  async def upload_document(
 
176
  )
177
 
178
 
179
+ async def draw_meme(image_path: str, text: str, sticker: bool, fiill: str) -> list:
180
  _split = text.split(";", 1)
181
  if len(_split) == 2:
182
  lower_text = _split[1]
Powers/utils/web_helpers.py CHANGED
@@ -1,13 +1,15 @@
1
  import json
2
  import os
 
3
  from urllib import parse
4
 
5
  import yt_dlp
6
  from pyrogram.types import InlineKeyboardButton as IKB
7
  from pyrogram.types import InlineKeyboardMarkup as IKM
8
  from pyrogram.types import Message
 
9
 
10
- from Powers.bot_class import Gojo
11
  from Powers.utils.http_helper import *
12
 
13
 
@@ -34,98 +36,25 @@ async def get_file_size(file: Message):
34
  return f"{round(size)} gb"
35
 
36
 
37
- class GOJO_YTS:
38
- """
39
- A class to fetch link of from youtube using the name provided
40
- Creadit: Hellbot
41
- """
42
- def __init__(self, search_terms: str, max_results=None):
43
- self.search_terms = search_terms
44
- self.max_results = max_results
45
- self.videos = self._search()
46
-
47
- def _search(self):
48
- encoded_search = parse.quote_plus(self.search_terms)
49
- BASE_URL = "https://youtube.com"
50
- url = f"{BASE_URL}/results?search_query={encoded_search}"
51
- response = requests.get(url).text
52
- while "ytInitialData" not in response:
53
- response = requests.get(url).text
54
- results = self._parse_html(response)
55
- if self.max_results is not None and len(results) > self.max_results:
56
- return results[: self.max_results]
57
- return results
58
-
59
- def _parse_html(self, response):
60
- results = []
61
- start = response.index("ytInitialData") + len("ytInitialData") + 3
62
- end = response.index("};", start) + 1
63
- json_str = response[start:end]
64
- data = json.loads(json_str)
65
-
66
- videos = data["contents"]["twoColumnSearchResultsRenderer"]["primaryContents"][
67
- "sectionListRenderer"
68
- ]["contents"][0]["itemSectionRenderer"]["contents"]
69
-
70
- for video in videos:
71
- res = {}
72
- if "videoRenderer" in video.keys():
73
- video_data = video.get("videoRenderer", {})
74
- res["id"] = video_data.get("videoId", None)
75
- res["thumbnails"] = [
76
- thumb.get("url", None)
77
- for thumb in video_data.get("thumbnail", {}).get("thumbnails", [{}])
78
- ]
79
- res["title"] = (
80
- video_data.get("title", {}).get("runs", [[{}]])[0].get("text", None)
81
- )
82
- res["long_desc"] = (
83
- video_data.get("descriptionSnippet", {})
84
- .get("runs", [{}])[0]
85
- .get("text", None)
86
- )
87
- res["channel"] = (
88
- video_data.get("longBylineText", {})
89
- .get("runs", [[{}]])[0]
90
- .get("text", None)
91
- )
92
- res["duration"] = video_data.get("lengthText", {}).get("simpleText", 0)
93
- res["views"] = video_data.get("viewCountText", {}).get("simpleText", 0)
94
- res["publish_time"] = video_data.get("publishedTimeText", {}).get(
95
- "simpleText", 0
96
- )
97
- res["url_suffix"] = (
98
- video_data.get("navigationEndpoint", {})
99
- .get("commandMetadata", {})
100
- .get("webCommandMetadata", {})
101
- .get("url", None)
102
- )
103
- results.append(res)
104
- return results
105
-
106
- def to_dict(self, clear_cache=True):
107
- result = self.videos
108
- if clear_cache:
109
- self.videos = ""
110
- return result
111
-
112
- def to_json(self, clear_cache=True):
113
- result = json.dumps({"videos": self.videos})
114
- if clear_cache:
115
- self.videos = ""
116
- return result
117
-
118
 
119
  # Gets yt result of given query.
120
- async def song_search(query, max_results=1):
121
- try:
122
- results = json.loads(GOJO_YTS(query, max_results=max_results).to_json())
123
- except KeyError:
124
- return
125
  yt_dict = {}
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
  nums = 1
128
- for i in results["videos"]:
129
  durr = i['duration'].split(":")
130
  if len(durr) == 3:
131
  hour_to_sec = int(durr[0])*60*60
@@ -136,12 +65,14 @@ async def song_search(query, max_results=1):
136
  total = minutes_to_sec + int(durr[1])
137
  if not (total > 600):
138
  dict_form = {
139
- "link": f"https://www.youtube.com{i['url_suffix']}",
140
- "title": i['title'],
141
- "views": i['views'],
142
- "channel": i['channel'],
143
- "duration": i['duration'],
144
- "thumbnail": i['thumbnails'][0]
 
 
145
  }
146
  yt_dict.update({nums: dict_form})
147
  nums += 1
@@ -200,51 +131,65 @@ async def youtube_downloader(c:Gojo,m:Message,query:str,is_direct:bool,type_:str
200
  video = True
201
  song = False
202
  ydl = yt_dlp.YoutubeDL(opts)
203
- if is_direct:
204
- query = query
205
- else:
206
- dicti = await song_search(query, 1)
207
- if not dicti:
208
- await m.reply_text("File with duration less than or equals to 5 minutes is allowed only")
209
- try:
210
- query = dicti[1]['link']
211
- except KeyError:
212
- z = "KeyError"
213
- return z
214
- FILE = ydl.extract_info(query,download=video)
215
- if int(FILE['duration']) > 600:
216
  await m.reply_text("File with duration less than or equals to 5 minutes is allowed only")
217
- return
218
- f_name = FILE['title']
219
- uploader = FILE['uploader']
220
- up_url = FILE['uploader_url']
221
- views = FILE['view_count']
 
 
 
 
 
 
 
 
 
 
 
 
222
  url = query
 
 
 
223
  if song:
224
  f_down = ydl.prepare_filename(FILE)
225
  f_path = f"{f_down}.mp3"
226
- thumb = f"{f_down}.webp"
227
  ydl.download([query])
 
228
  elif video:
229
  f_path = open(f"{FILE['id']}.mp4","rb")
 
230
  cap = f"""
231
- Name: `{f_name}`
232
- Views: `{views}`
 
233
  """
234
  kb = IKM(
235
  [
236
  [
237
- IKB(f"✘ {uploader.capitalize()} ✘",url=f"{up_url}"),
 
 
238
  IKB(f"✘ Youtube url ✘", url=f"{url}")
239
  ]
240
  ]
241
  )
 
 
 
 
 
242
  if video:
243
- await m.reply_video(f_path,caption=cap,reply_markup=kb,duration=int(FILE['duration']))
244
- os.remove(f"./{FILE['id']}.mp4")
 
245
  return
246
  elif song:
247
- await m.reply_audio(f_path,caption=cap,reply_markup=kb,duration=int(FILE['duration']),thumb=thumb,title=f_name)
248
  os.remove(f_path)
249
  os.remove(thumb)
250
  return
 
1
  import json
2
  import os
3
+ from traceback import format_exc
4
  from urllib import parse
5
 
6
  import yt_dlp
7
  from pyrogram.types import InlineKeyboardButton as IKB
8
  from pyrogram.types import InlineKeyboardMarkup as IKM
9
  from pyrogram.types import Message
10
+ from youtubesearchpython.__future__ import Video, VideosSearch
11
 
12
+ from Powers.bot_class import LOGGER, MESSAGE_DUMP, Gojo
13
  from Powers.utils.http_helper import *
14
 
15
 
 
36
  return f"{round(size)} gb"
37
 
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  # Gets yt result of given query.
41
+ async def song_search(query, is_direct, max_results=1):
 
 
 
 
42
  yt_dict = {}
43
+ try:
44
+ if is_direct:
45
+ vid = Video.getInfo(query)
46
+ query = vid["title"]
47
+ else:
48
+ query = query
49
+ videos = VideosSearch(query,max_results)
50
+ results = await videos.next()
51
+ except Exception as e:
52
+ LOGGER.error(e)
53
+ LOGGER.error(format_exc())
54
+ return e
55
 
56
  nums = 1
57
+ for i in results["result"]:
58
  durr = i['duration'].split(":")
59
  if len(durr) == 3:
60
  hour_to_sec = int(durr[0])*60*60
 
65
  total = minutes_to_sec + int(durr[1])
66
  if not (total > 600):
67
  dict_form = {
68
+ "link": i["link"],
69
+ "title": i["title"],
70
+ "views": i["viewCount"]["short"],
71
+ "channel": i["channel"]["link"],
72
+ "duration": i["accessibility"]['duration'],
73
+ "thumbnail": i["richThumbnail"],
74
+ "published": i["publishedTime"],
75
+ "uploader": i ["channel"]["name"]
76
  }
77
  yt_dict.update({nums: dict_form})
78
  nums += 1
 
131
  video = True
132
  song = False
133
  ydl = yt_dlp.YoutubeDL(opts)
134
+ dicti = await song_search(query, is_direct,1)
135
+ if not dicti and type(dicti) != str:
 
 
 
 
 
 
 
 
 
 
 
136
  await m.reply_text("File with duration less than or equals to 5 minutes is allowed only")
137
+ elif type(dicti) == str:
138
+ await m.reply_text(dicti)
139
+ return
140
+ try:
141
+ query = dicti[1]['link']
142
+ except KeyError:
143
+ z = "KeyError"
144
+ return z
145
+
146
+ f_name = dicti["title"]
147
+ views = dicti["views"]
148
+ up_url = dicti["channel"]
149
+ uploader = dicti["uploader"]
150
+ thumb = dicti["thumbnail"]
151
+ published_on = dicti["publishedON"]
152
+
153
+ FILE = ydl.extract_info(query,download=video)
154
  url = query
155
+ thumb_ = await c.send_photo(MESSAGE_DUMP, thumb)
156
+ thumb = await thumb_.download()
157
+ await thumb_.delete()
158
  if song:
159
  f_down = ydl.prepare_filename(FILE)
160
  f_path = f"{f_down}.mp3"
 
161
  ydl.download([query])
162
+ ext = ".mp3"
163
  elif video:
164
  f_path = open(f"{FILE['id']}.mp4","rb")
165
+ ext = ".mp4"
166
  cap = f"""
167
+ Name: `{f_name}`
168
+ Views: `{views}`
169
+ ⤷ Published date: `{published_on}`
170
  """
171
  kb = IKM(
172
  [
173
  [
174
+ IKB(f"✘ {uploader.capitalize()} ✘",url=f"{up_url}")
175
+ ],
176
+ [
177
  IKB(f"✘ Youtube url ✘", url=f"{url}")
178
  ]
179
  ]
180
  )
181
+
182
+ file_path = f_name.strip() + ext
183
+ os.rename(f_path,file_path)
184
+
185
+
186
  if video:
187
+ await m.reply_video(file_path,caption=cap,reply_markup=kb,duration=int(FILE['duration']))
188
+ os.remove(file_path)
189
+ os.remove(thumb)
190
  return
191
  elif song:
192
+ await m.reply_audio(file_path,caption=cap,reply_markup=kb,duration=int(FILE['duration']),thumb=thumb,title=f_name)
193
  os.remove(f_path)
194
  os.remove(thumb)
195
  return
Powers/vars.py CHANGED
@@ -15,7 +15,7 @@ class Config:
15
  API_ID = int(config("API_ID", default="123"))
16
  API_HASH = config("API_HASH", default=None)
17
  OWNER_ID = int(config("OWNER_ID", default=1344569458))
18
- MESSAGE_DUMP = int(config("MESSAGE_DUMP", default=-100))
19
  DEV_USERS = [
20
  int(i)
21
  for i in config(
@@ -64,7 +64,7 @@ class Development:
64
  API_ID = 12345 # Your APP_ID from Telegram
65
  API_HASH = "YOUR API HASH" # Your APP_HASH from Telegram
66
  OWNER_ID = 1344569458 # Your telegram user id defult to mine
67
- MESSAGE_DUMP = -100 # Your Private Group ID for logs
68
  DEV_USERS = []
69
  SUDO_USERS = []
70
  WHITELIST_USERS = []
 
15
  API_ID = int(config("API_ID", default="123"))
16
  API_HASH = config("API_HASH", default=None)
17
  OWNER_ID = int(config("OWNER_ID", default=1344569458))
18
+ MESSAGE_DUMP = int(config("MESSAGE_DUMP"))
19
  DEV_USERS = [
20
  int(i)
21
  for i in config(
 
64
  API_ID = 12345 # Your APP_ID from Telegram
65
  API_HASH = "YOUR API HASH" # Your APP_HASH from Telegram
66
  OWNER_ID = 1344569458 # Your telegram user id defult to mine
67
+ MESSAGE_DUMP = -100845454887 # Your Private Group ID for logs
68
  DEV_USERS = []
69
  SUDO_USERS = []
70
  WHITELIST_USERS = []
README.md CHANGED
@@ -172,6 +172,8 @@ If all works well, the bot should send a message to the MESSAGE_DUMP Group!--->
172
  `API_HASH` You can get your api hash [here](my.telegram.org)
173
 
174
  `DB_URI` Your [MongoDB](https://www.mongodb.com/) connection string.
 
 
175
  </details>
176
 
177
 
@@ -201,8 +203,6 @@ If all works well, the bot should send a message to the MESSAGE_DUMP Group!--->
201
 
202
  `SUPPORT_GROUP`: Your Telegram support group chat username that users can contact in case of a problem.
203
 
204
- `MESSAGE_DUMP`: Event logs channel where the bot will send updates. Note that it should start with `-100`.
205
-
206
  `PREFIX_HANDLER`: Something like '/' to execute commands.
207
 
208
  `SUPPORT_CHANNEL`: Your Telegram support channel username where users can see bot updates.
 
172
  `API_HASH` You can get your api hash [here](my.telegram.org)
173
 
174
  `DB_URI` Your [MongoDB](https://www.mongodb.com/) connection string.
175
+
176
+ `MESSAGE_DUMP`: Event logs channel where the bot will send updates. Note that it should start with `-100`.
177
  </details>
178
 
179
 
 
203
 
204
  `SUPPORT_GROUP`: Your Telegram support group chat username that users can contact in case of a problem.
205
 
 
 
206
  `PREFIX_HANDLER`: Something like '/' to execute commands.
207
 
208
  `SUPPORT_CHANNEL`: Your Telegram support channel username where users can see bot updates.