Karma
commited on
Commit
·
fa3be38
1
Parent(s):
c3d4e11
Create quotely.py
Browse files- Mikobot/plugins/quotely.py +294 -0
Mikobot/plugins/quotely.py
ADDED
@@ -0,0 +1,294 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# <============================================== IMPORTS =========================================================>
|
2 |
+
import base64
|
3 |
+
import os
|
4 |
+
from random import choice
|
5 |
+
|
6 |
+
from aiohttp import ContentTypeError
|
7 |
+
from PIL import Image
|
8 |
+
from telethon.tl import types
|
9 |
+
from telethon.utils import get_display_name, get_peer_id
|
10 |
+
|
11 |
+
from Mikobot import DEV_USERS
|
12 |
+
from Mikobot.events import register
|
13 |
+
|
14 |
+
# <=======================================================================================================>
|
15 |
+
|
16 |
+
|
17 |
+
# <================================================ CLASS & FUNCTION =======================================================>
|
18 |
+
class Quotly:
|
19 |
+
_API = "https://bot.lyo.su/quote/generate"
|
20 |
+
_entities = {
|
21 |
+
types.MessageEntityPhone: "phone_number",
|
22 |
+
types.MessageEntityMention: "mention",
|
23 |
+
types.MessageEntityBold: "bold",
|
24 |
+
types.MessageEntityCashtag: "cashtag",
|
25 |
+
types.MessageEntityStrike: "strikethrough",
|
26 |
+
types.MessageEntityHashtag: "hashtag",
|
27 |
+
types.MessageEntityEmail: "email",
|
28 |
+
types.MessageEntityMentionName: "text_mention",
|
29 |
+
types.MessageEntityUnderline: "underline",
|
30 |
+
types.MessageEntityUrl: "url",
|
31 |
+
types.MessageEntityTextUrl: "text_link",
|
32 |
+
types.MessageEntityBotCommand: "bot_command",
|
33 |
+
types.MessageEntityCode: "code",
|
34 |
+
types.MessageEntityPre: "pre",
|
35 |
+
}
|
36 |
+
|
37 |
+
async def _format_quote(self, event, reply=None, sender=None, type_="private"):
|
38 |
+
async def telegraph(file_):
|
39 |
+
file = file_ + ".png"
|
40 |
+
Image.open(file_).save(file, "PNG")
|
41 |
+
files = {"file": open(file, "rb").read()}
|
42 |
+
uri = (
|
43 |
+
"https://telegra.ph"
|
44 |
+
+ (
|
45 |
+
await async_searcher(
|
46 |
+
"https://telegra.ph/upload", post=True, data=files, re_json=True
|
47 |
+
)
|
48 |
+
)[0]["src"]
|
49 |
+
)
|
50 |
+
os.remove(file)
|
51 |
+
os.remove(file_)
|
52 |
+
return uri
|
53 |
+
|
54 |
+
reply = (
|
55 |
+
{
|
56 |
+
"name": get_display_name(reply.sender) or "Deleted Account",
|
57 |
+
"text": reply.raw_text,
|
58 |
+
"chatId": reply.chat_id,
|
59 |
+
}
|
60 |
+
if reply
|
61 |
+
else {}
|
62 |
+
)
|
63 |
+
|
64 |
+
is_fwd = event.fwd_from
|
65 |
+
name, last_name = None, None
|
66 |
+
|
67 |
+
if sender and sender.id not in DEV_USERS:
|
68 |
+
id_ = get_peer_id(sender)
|
69 |
+
name = get_display_name(sender)
|
70 |
+
elif not is_fwd:
|
71 |
+
id_ = event.sender_id
|
72 |
+
sender = await event.get_sender()
|
73 |
+
name = get_display_name(sender)
|
74 |
+
else:
|
75 |
+
id_, sender = None, None
|
76 |
+
name = is_fwd.from_name
|
77 |
+
if is_fwd.from_id:
|
78 |
+
id_ = get_peer_id(is_fwd.from_id)
|
79 |
+
try:
|
80 |
+
sender = await event.client.get_entity(id_)
|
81 |
+
name = get_display_name(sender)
|
82 |
+
except ValueError:
|
83 |
+
pass
|
84 |
+
if sender and hasattr(sender, "last_name"):
|
85 |
+
last_name = sender.last_name
|
86 |
+
|
87 |
+
entities = (
|
88 |
+
[
|
89 |
+
{
|
90 |
+
"type": self._entities[type(entity)],
|
91 |
+
**{k: v for k, v in entity.to_dict().items() if k != "_"},
|
92 |
+
}
|
93 |
+
for entity in event.entities
|
94 |
+
]
|
95 |
+
if event.entities
|
96 |
+
else []
|
97 |
+
)
|
98 |
+
|
99 |
+
message = {
|
100 |
+
"entities": entities,
|
101 |
+
"chatId": id_,
|
102 |
+
"avatar": True,
|
103 |
+
"from": {
|
104 |
+
"id": id_,
|
105 |
+
"first_name": (name or (sender.first_name if sender else None))
|
106 |
+
or "Deleted Account",
|
107 |
+
"last_name": last_name,
|
108 |
+
"username": sender.username if sender else None,
|
109 |
+
"language_code": "en",
|
110 |
+
"title": name,
|
111 |
+
"name": name or "Unknown",
|
112 |
+
"type": type_,
|
113 |
+
},
|
114 |
+
"text": event.raw_text,
|
115 |
+
"replyMessage": reply,
|
116 |
+
}
|
117 |
+
|
118 |
+
if event.document and event.document.thumbs:
|
119 |
+
file_ = await event.download_media(thumb=-1)
|
120 |
+
uri = await telegraph(file_)
|
121 |
+
message["media"] = {"url": uri}
|
122 |
+
|
123 |
+
return message
|
124 |
+
|
125 |
+
async def create_quotly(
|
126 |
+
self,
|
127 |
+
event,
|
128 |
+
url="https://quote-api.example.com/generate",
|
129 |
+
reply={},
|
130 |
+
bg=None,
|
131 |
+
sender=None,
|
132 |
+
OQAPI=True,
|
133 |
+
file_name="quote.webp",
|
134 |
+
):
|
135 |
+
if not isinstance(event, list):
|
136 |
+
event = [event]
|
137 |
+
if OQAPI:
|
138 |
+
url = Quotly._API
|
139 |
+
bg = bg or "#1b1429"
|
140 |
+
content = {
|
141 |
+
"type": "quote",
|
142 |
+
"format": "webp",
|
143 |
+
"backgroundColor": bg,
|
144 |
+
"width": 512,
|
145 |
+
"height": 768,
|
146 |
+
"scale": 2,
|
147 |
+
"messages": [
|
148 |
+
await self._format_quote(message, reply=reply, sender=sender)
|
149 |
+
for message in event
|
150 |
+
],
|
151 |
+
}
|
152 |
+
try:
|
153 |
+
request = await async_searcher(url, post=True, json=content, re_json=True)
|
154 |
+
except ContentTypeError as er:
|
155 |
+
if url != self._API:
|
156 |
+
return await self.create_quotly(
|
157 |
+
self._API, post=True, json=content, re_json=True
|
158 |
+
)
|
159 |
+
raise er
|
160 |
+
|
161 |
+
if request.get("ok"):
|
162 |
+
with open(file_name, "wb") as file:
|
163 |
+
image = base64.decodebytes(request["result"]["image"].encode("utf-8"))
|
164 |
+
file.write(image)
|
165 |
+
return file_name
|
166 |
+
raise Exception(str(request))
|
167 |
+
|
168 |
+
|
169 |
+
quotly = Quotly()
|
170 |
+
|
171 |
+
|
172 |
+
async def async_searcher(
|
173 |
+
url: str,
|
174 |
+
post: bool = None,
|
175 |
+
headers: dict = None,
|
176 |
+
params: dict = None,
|
177 |
+
json: dict = None,
|
178 |
+
data: dict = None,
|
179 |
+
ssl=None,
|
180 |
+
re_json: bool = False,
|
181 |
+
re_content: bool = False,
|
182 |
+
real: bool = False,
|
183 |
+
*args,
|
184 |
+
**kwargs
|
185 |
+
):
|
186 |
+
try:
|
187 |
+
import aiohttp
|
188 |
+
except ImportError:
|
189 |
+
raise DependencyMissingError(
|
190 |
+
"'aiohttp' is not installed!\nThis function requires aiohttp to be installed."
|
191 |
+
)
|
192 |
+
|
193 |
+
async with aiohttp.ClientSession(headers=headers) as client:
|
194 |
+
data = await (
|
195 |
+
client.post(url, json=json, data=data, ssl=ssl, *args, **kwargs)
|
196 |
+
if post
|
197 |
+
else client.get(url, params=params, ssl=ssl, *args, **kwargs)
|
198 |
+
)
|
199 |
+
return await (
|
200 |
+
data.json() if re_json else data.read() if re_content else data.text()
|
201 |
+
)
|
202 |
+
|
203 |
+
|
204 |
+
@register(pattern="^/q(?: |$)(.*)")
|
205 |
+
async def quott_(event):
|
206 |
+
match = event.pattern_match.group(1).strip()
|
207 |
+
if not event.is_reply:
|
208 |
+
return await event.reply("Please reply to a message.")
|
209 |
+
|
210 |
+
msg = await event.reply("Creating quote, please wait.")
|
211 |
+
reply = await event.get_reply_message()
|
212 |
+
replied_to, reply_ = None, None
|
213 |
+
|
214 |
+
if match:
|
215 |
+
spli_ = match.split(maxsplit=1)
|
216 |
+
if (spli_[0] in ["r", "reply"]) or (
|
217 |
+
spli_[0].isdigit() and int(spli_[0]) in range(1, 21)
|
218 |
+
):
|
219 |
+
if spli_[0].isdigit():
|
220 |
+
if not event.client.is_bot:
|
221 |
+
reply_ = await event.client.get_messages(
|
222 |
+
event.chat_id,
|
223 |
+
min_id=event.reply_to_msg_id - 1,
|
224 |
+
reverse=True,
|
225 |
+
limit=int(spli_[0]),
|
226 |
+
)
|
227 |
+
else:
|
228 |
+
id_ = reply.id
|
229 |
+
reply_ = []
|
230 |
+
for msg_ in range(id_, id_ + int(spli_[0])):
|
231 |
+
msh = await event.client.get_messages(event.chat_id, ids=msg_)
|
232 |
+
if msh:
|
233 |
+
reply_.append(msh)
|
234 |
+
else:
|
235 |
+
replied_to = await reply.get_reply_message()
|
236 |
+
try:
|
237 |
+
match = spli_[1]
|
238 |
+
except IndexError:
|
239 |
+
match = None
|
240 |
+
|
241 |
+
user = None
|
242 |
+
|
243 |
+
if not reply_:
|
244 |
+
reply_ = reply
|
245 |
+
|
246 |
+
if match:
|
247 |
+
match = match.split(maxsplit=1)
|
248 |
+
|
249 |
+
if match:
|
250 |
+
if match[0].startswith("@") or match[0].isdigit():
|
251 |
+
try:
|
252 |
+
match_ = await event.client.parse_id(match[0])
|
253 |
+
user = await event.client.get_entity(match_)
|
254 |
+
except ValueError:
|
255 |
+
pass
|
256 |
+
match = match[1] if len(match) == 2 else None
|
257 |
+
else:
|
258 |
+
match = match[0]
|
259 |
+
|
260 |
+
if match == "random":
|
261 |
+
match = choice(all_col)
|
262 |
+
|
263 |
+
try:
|
264 |
+
file = await quotly.create_quotly(
|
265 |
+
reply_, bg=match, reply=replied_to, sender=user
|
266 |
+
)
|
267 |
+
except Exception as er:
|
268 |
+
return await msg.edit(str(er))
|
269 |
+
|
270 |
+
message = await reply.reply("", file=file)
|
271 |
+
os.remove(file)
|
272 |
+
await msg.delete()
|
273 |
+
return message
|
274 |
+
|
275 |
+
|
276 |
+
# <=================================================== HELP ====================================================>
|
277 |
+
|
278 |
+
|
279 |
+
__mod_name__ = "QUOTELY"
|
280 |
+
|
281 |
+
__help__ = """
|
282 |
+
» /q : Create quote.
|
283 |
+
|
284 |
+
» /q r : Get replied quote.
|
285 |
+
|
286 |
+
» /q 2 ᴛᴏ 8 : Get multiple quotes.
|
287 |
+
|
288 |
+
» /q < any colour name > : Create any coloured quotes.
|
289 |
+
|
290 |
+
➠ Example:
|
291 |
+
|
292 |
+
» /q red , /q blue etc.
|
293 |
+
"""
|
294 |
+
# <================================================ END =======================================================>
|