-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
156 lines (148 loc) · 8.13 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import discord
from discord import app_commands
from os import getenv
import aiohttp
from bs4 import BeautifulSoup
from copy import deepcopy
import aiosqlite
image_types = {'image/jpeg', 'image/png', 'image/webp'}
data_file = 'messages.db'
class MyTranslator(app_commands.Translator):
async def translate(
self,
string: app_commands.locale_str,
locale: discord.Locale,
context: app_commands.TranslationContext,
) -> str | None:
message = str(string)
if locale is discord.Locale.russian:
match message:
case 'Forward':
return 'Переслать'
case 'Instant forward':
return 'Переслать немедленно'
case 'Send the saved message(s) to another channel':
return 'Отправить сохраненное сообщение(я) в другой канал'
case 'Whether to show the original message link. Might be needed to set to off on some servers.':
return 'Показывать ли ссылку на оригинальное сообщение. Может понадобиться выключить на некоторых серверах.'
case 'Whether to send the message anonymously.':
return 'Отправлять ли сообщение анонимно.'
case 'send':
return 'отправить'
case 'preview':
return 'предпросмотр'
case 'Preview the saved message(s)':
return 'Предпросмотр сохраненных сообщений'
case 'delete':
return 'удалить'
case 'Delete the saved message(s)':
return 'Удалить сохраненное сообщение(я)'
return
async def create_send_embeds(ctx: discord.Interaction, show_original: bool=True, show_ids: bool=False) -> list[discord.Embed]:
embeds: list[discord.Embed] = []
conn = await aiosqlite.connect(data_file)
cursor = await conn.execute('SELECT * FROM Messages WHERE user_id = ? ORDER BY id', (ctx.user.id,))
messages = await cursor.fetchall()
for i, message in enumerate(messages):
await cursor.execute('SELECT filename, url, image, tenor FROM Attachments WHERE message_id = ? AND user_id = ?', (message[0], message[1]))
attachments = await cursor.fetchall()
image = discord.utils.find(lambda a: a[2] == 1, attachments)
if i == 0:
embeds.append(discord.Embed(title=f'{getenv("EMOJI") or ""} *Forwarded*' if not ctx.locale is discord.Locale.russian else f'{getenv("EMOJI") or ""} *Переслано*', description=message[3] if not image or image[3] != 1 else None))
else:
embeds.append(discord.Embed(description=message[3] if not image or image[3] != 1 else None))
if image is not None:
embeds[i].set_image(url=image[1])
for a in attachments:
if a[2] != 1:
embeds[i].add_field(name='', value=f'[{a[0]}]({a[1]})' if a[0] else a[1])
if show_original:
embeds[i].add_field(name='', value=message[2], inline=False)
if show_ids:
embeds[i].set_author(name='ID: ' + str(i+1))
await cursor.close()
await conn.close()
return embeds
# database shit
async def initiate_db(filename: str):
conn = await aiosqlite.connect(filename)
cursor = await conn.cursor()
await cursor.executescript('''
CREATE TABLE IF NOT EXISTS Messages (
id INTEGER,
user_id INTEGER,
footer TEXT,
message TEXT
);
CREATE TABLE IF NOT EXISTS Attachments (
message_id INTEGER,
user_id INTEGER,
filename TEXT,
url TEXT,
image INTEGER,
tenor INTEGER
)''')
await conn.commit()
await conn.close()
async def add_message(ctx: discord.Interaction, message: discord.Message, confirmed: bool=True):
conn = await aiosqlite.connect('messages.db')
cursor = await conn.cursor()
await cursor.execute('SELECT id FROM Messages WHERE user_id = ? ORDER BY id DESC', (ctx.user.id,))
id = await cursor.fetchone()
if id is None:
id = 1
else:
id = id[0] + 1
if message.author.id == ctx.client.user.id:
for embed in message.embeds:
await cursor.execute('INSERT INTO Messages VALUES (?, ?, ?, ?)', (id, ctx.user.id, embed.fields[-1].value if embed.fields and not embed.fields[-1].inline else None, embed.description))
if embed.image:
await cursor.execute('INSERT INTO Attachments (message_id, user_id, url, image) VALUES (?, ?, ?, 1)', (id, ctx.user.id, embed.image.url))
for a in embed.fields:
if not a.inline:
continue
await cursor.execute('INSERT INTO Attachments VALUES (?, ?, ?, ?, 0, 0)', (id, ctx.user.id, None, a.value))
id += 1
else:
await cursor.execute('INSERT INTO Messages VALUES (?, ?, ?, ?)', (id, ctx.user.id, f'-# [{message.author.name} **·** <t:{int(message.created_at.timestamp())}:t>]({message.jump_url})', message.content))
tenor = message.embeds and message.embeds[0].url is not None and message.embeds[0].url.startswith('https://tenor.com/view/')
image = discord.utils.find(lambda a: a.content_type in image_types, message.attachments)
if image is None:
if tenor:
async with aiohttp.ClientSession(headers={'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36'}) as session:
async with session.get(message.embeds[0].url) as r:
data = await r.text()
image = f"https://c.tenor.com/{BeautifulSoup(data, 'html.parser').find('meta', itemprop='contentUrl')['content'].split('/')[4]}/tenor.gif"
elif message.embeds and message.embeds[0].type == 'image':
image = message.embeds[0].url
else:
image = image.url
if image is not None:
await cursor.execute('INSERT INTO Attachments (message_id, user_id, url, image, tenor) VALUES (?, ?, ?, 1, ?)', (id, ctx.user.id, image, 1 if message.embeds and tenor and message.embeds[0].url == message.content else 0))
for attachment in message.attachments:
if attachment.url == image:
continue
await cursor.execute('INSERT INTO Attachments VALUES (?, ?, ?, ?, 0, 0)', (id, ctx.user.id, attachment.filename, attachment.url))
await conn.commit()
await conn.close()
async def delete_messages(user_id: int, message_id: int=None):
async with aiosqlite.connect(data_file) as conn:
if message_id is None:
await conn.execute('DELETE FROM Messages WHERE user_id = ?', (user_id,))
await conn.execute('DELETE FROM Attachments WHERE user_id = ?', (user_id,))
await conn.commit()
return
true_id = (await (await conn.execute('SELECT id FROM Messages WHERE user_id = ?', (user_id,))).fetchall())[message_id - 1][0]
await conn.execute('DELETE FROM Messages WHERE id = ? AND user_id = ?', (true_id, user_id))
await conn.execute('DELETE FROM Attachments WHERE message_id = ? AND user_id = ?', (true_id, user_id))
await conn.commit()
async def message_check(id: int, confirmed: bool=True) -> bool:
conn = await aiosqlite.connect(data_file)
if confirmed:
cursor = await conn.execute('SELECT id FROM Messages WHERE user_id = ?', (id,))
else:
cursor = await conn.execute('SELECT * FROM Messages WHERE user_id = ?', (id,))
message = await cursor.fetchone()
await cursor.close()
await conn.close()
return message is not None