-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathemoji_container.py
175 lines (143 loc) · 7.65 KB
/
emoji_container.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import asyncio
from collections import Counter
from io import BytesIO
import nextcord.utils
from nextcord import Guild, Emoji
from PIL import Image, ImageFont, ImageDraw
from logger import *
class EmojiContainer:
def __init__(self):
self.letter_emoji_map = {'a': ['🇦', '🅰️'], 'b': ['🇧', '🅱️'], 'c': ['🇨'], 'd': ['🇩'], 'e': ['🇪'],
'f': ['🇫'], 'g': ['🇬'], 'h': ['🇭'], 'i': ['🇮', 'ℹ️'], 'j': ['🇯'], 'k': ['🇰'],
'l': ['🇱'], 'm': ['🇲'], 'n': ['🇳'], 'o': ['🇴', '🅾️'], 'p': ['🇵', '🅿️'],
'q': ['🇶'], 'r': ['🇷'], 's': ['🇸'], 't': ['🇹'], 'u': ['🇺'], 'v': ['🇻'],
'w': ['🇼'], 'x': ['🇽'], 'y': ['🇾'], 'z': ['🇿'],
'0': ['0️⃣'], '1': ['1️⃣'], '2': ['2️⃣'], '3': ['3️⃣'], '4': ['4️⃣'], '5': ['5️⃣'],
'6': ['6️⃣'], '7': ['7️⃣'], '8': ['8️⃣'], '9': ['9️⃣'],
'!': ['❗', '❕'], '?': ['❓', '❔']}
self.skip_letters = ['.', ',', '~', '(', ')']
self.en_guild_ids = [837690275719544904, 837697356380110860, 837690443633524770]
self.cache_guild_emoji_len = {}
self.emojis = None # Use only for emojis other than Korean
extra_emoji_num = 3
extra_vowel_num = 2
for i in range(1, extra_emoji_num + 1):
for c in "abcdefghijklmnopqrstuvwxyz":
self.letter_emoji_map[c].insert(0, "#" + c + "_" * i)
for i in range(extra_emoji_num + 1, extra_emoji_num + extra_vowel_num + 1):
for c in "aeiou":
self.letter_emoji_map[c].insert(0, "#" + c + "_" * i)
@staticmethod
def is_korean_letter(c: str) -> bool:
return len(c) == 1 and (ord(c) in range(ord('가'), ord('힣') + 1) or ord(c) in range(ord('ㄱ'), ord('ㅣ') + 1))
def get_emoji(self, name: str or Emoji) -> Emoji:
if type(name) is str and name.startswith('#'):
return list(filter(lambda x: x.name == name[1:] and x.guild_id in self.en_guild_ids, self.emojis))[0]
else:
return name
def initialize_cache(self, cache_guilds: list, emojis: list):
self.emojis = emojis
self.cache_guild_emoji_len = dict([(guild, len(guild.emojis)) for guild in cache_guilds])
for cache_guild in cache_guilds:
for emoji in cache_guild.emojis:
self.letter_emoji_map[chr(int(emoji.name))] = [emoji]
async def create_emoji(self, c: str, letters_to_keep: str, target_guild: Guild):
if target_guild is None:
from db_models.words.models import CustomEmoji
for emoji in CustomEmoji.objects.order_by('times_used'):
emoji_name = emoji.letter
if chr(emoji_name) not in letters_to_keep:
emoji = list(filter(lambda x: x.name == chr(emoji_name)
and nextcord.utils.get(self.cache_guild_emoji_len.keys(), id=x.guild_id),
self.emojis))
if emoji:
emoji = emoji[0]
target_guild = emoji.guild
Logger.log("Deleting emoji", emoji.name, '({})'.format(chr(emoji.name)),
emoji.id, emoji.guild_id)
await emoji.delete()
break
else:
raise
with Image.open('data/korean_emojis/base.png') as base_img:
font = ImageFont.truetype("data/korean_emojis/TmoneyRoundWindRegular.ttf", 100, encoding="utf-8")
text_image = Image.new("RGBA", base_img.size, (255, 255, 255, 0))
draw_context = ImageDraw.Draw(text_image)
byte_arr = BytesIO()
draw_context.text((16, 15), c, fill=(255, 255, 255, 255), font=font)
emoji_image = Image.alpha_composite(base_img, text_image)
emoji_image.save(byte_arr, format="PNG")
emoji = await target_guild.create_custom_emoji(name=str(ord(c)), image=bytes(byte_arr.getvalue()))
Logger.log("Created emoji", ord(c), '({})'.format(chr(ord(c))), emoji.id, emoji.guild_id)
self.letter_emoji_map[c] = [emoji]
return emoji
def get_target_guild(self):
for guild, emoji_len in self.cache_guild_emoji_len.items():
if emoji_len < 50:
self.cache_guild_emoji_len[guild] += 1
return guild
async def get_emojis_for_saying(self, letters: str) -> tuple:
from db_models.words.models import CustomEmoji
for c in letters:
if EmojiContainer.is_korean_letter(c):
emoji, _ = CustomEmoji.objects.get_or_create(letter=c)
emoji.times_used += 1
emoji.save()
to_return = []
to_create = []
for c in letters:
if c in self.skip_letters:
continue
if c.isspace():
to_return.append(identity_returner(c))
elif c in self.letter_emoji_map:
to_return.append(identity_returner(self.get_emoji(self.letter_emoji_map[c][0])))
elif EmojiContainer.is_korean_letter(c):
if c in to_create:
to_return.append(identity_returner(c))
else:
to_create.append(c)
to_return.append(self.create_emoji(c, letters, self.get_target_guild()))
else:
to_return.append(identity_returner(nextcord.utils.get(self.emojis, id=840907083021025290)))
result = list(await asyncio.gather(*to_return))
for index, emoji in enumerate(result):
if type(emoji) is str and EmojiContainer.is_korean_letter(emoji):
result[index] = self.get_emoji(self.letter_emoji_map[emoji][0])
return tuple(result)
async def get_emojis_for_reaction(self, letters: str) -> tuple:
from db_models.words.models import CustomEmoji
for c in letters:
if EmojiContainer.is_korean_letter(c):
emoji, _ = CustomEmoji.objects.get_or_create(letter=c)
emoji.times_used += 1
emoji.save()
# TODO: No support for duplicate Korean letter for now
for dup_letter in [k for k, v in Counter(letters).items() if v > 1]:
if EmojiContainer.is_korean_letter(dup_letter):
return ()
letter_emoji_map_copy = self.letter_emoji_map.copy()
to_return = []
to_create = []
for c in letters:
if c in self.skip_letters or c.isspace():
continue
if len(letter_emoji_map_copy.get(c, [])) > 0:
to_return.append(identity_returner(self.get_emoji(letter_emoji_map_copy[c][0])))
letter_emoji_map_copy[c] = letter_emoji_map_copy[c][1:]
elif EmojiContainer.is_korean_letter(c):
if c in to_create:
to_return.append(identity_returner(c))
else:
to_create.append(c)
to_return.append(self.create_emoji(c, letters, self.get_target_guild()))
else:
return ()
result = list(await asyncio.gather(*to_return))
for index, emoji in enumerate(result):
if type(emoji) is str and EmojiContainer.is_korean_letter(emoji):
result[index] = self.get_emoji(self.letter_emoji_map[emoji][0])
return tuple(result)
emoji_container = EmojiContainer()
async def identity_returner(to_return):
return to_return