Skip to content

Commit 04a2cc5

Browse files
committed
Use the dominant colour of a user avatar for info embed
1 parent f7cf9d3 commit 04a2cc5

File tree

2 files changed

+61
-22
lines changed

2 files changed

+61
-22
lines changed

core/thread.py

Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
import discord
2-
from discord.ext import commands
1+
from urllib.parse import urlparse
2+
import traceback
33
import datetime
44
import asyncio
55
import functools
66
import string
77
import re
8+
import io
9+
10+
import discord
11+
from discord.ext import commands
12+
13+
from core.decorators import asyncexecutor
14+
from colorthief import ColorThief
815

916
class Thread:
1017
'''Represents a discord modmail thread'''
@@ -39,11 +46,13 @@ def close(self):
3946

4047
async def _edit_thread_message(self, channel, message_id, message):
4148
async for msg in channel.history():
42-
if msg.embeds:
43-
embed = msg.embeds[0]
44-
if f'Moderator - {message_id}' in embed.footer.text:
49+
if not msg.embeds:
50+
continue
51+
embed = msg.embeds[0]
52+
if embed and embed.author:
53+
if message_id == int(re.findall('\d+', embed.author.url)[0]):
4554
if ' - (Edited)' not in embed.footer.text:
46-
embed.set_footer(text=embed.footer.text + ' - (Edited)')
55+
embed.set_footer(text=embed.footer.text + ' - (Edited)')
4756
embed.description = message
4857
await msg.edit(embed=embed)
4958
break
@@ -80,6 +89,8 @@ async def send(self, message, destination=None, from_mod=False, delete_message=T
8089
description=message.content,
8190
timestamp=message.created_at
8291
)
92+
93+
em.set_author(name=str(author), icon_url=author.avatar_url, url=f'https://{message.id}.id') # store message id in hidden url
8394

8495
image_types = ['.png', '.jpg', '.gif', '.jpeg', '.webp']
8596
is_image_url = lambda u: any(urlparse(u).path.endswith(x) for x in image_types)
@@ -100,12 +111,10 @@ async def send(self, message, destination=None, from_mod=False, delete_message=T
100111

101112
if from_mod:
102113
em.color=discord.Color.green()
103-
em.set_author(name=str(author), icon_url=author.avatar_url)
104-
em.set_footer(text=f'Moderator - {message.id}')
114+
em.set_footer(text=f'Moderator')
105115
else:
106116
em.color=discord.Color.gold()
107-
em.set_author(name=str(author), icon_url=author.avatar_url)
108-
em.set_footer(text=f'User - {message.id}')
117+
em.set_footer(text=f'User')
109118

110119
await destination.trigger_typing()
111120
await destination.send(embed=em)
@@ -211,13 +220,14 @@ async def create(self, recipient, *, creator=None):
211220

212221
thread.channel = channel
213222

214-
log_url, log_data = await asyncio.gather(
223+
log_url, log_data, dc = await asyncio.gather(
215224
self.bot.modmail_api.get_log_url(recipient, channel, creator or recipient),
216-
self.bot.modmail_api.get_user_logs(recipient.id)
225+
self.bot.modmail_api.get_user_logs(recipient.id),
226+
self.get_dominant_color(recipient.avatar_url)
217227
)
218228

219229
log_count = len(log_data)
220-
info_embed = self._format_info_embed(recipient, creator, log_url, log_count)
230+
info_embed = self._format_info_embed(recipient, creator, log_url, log_count, dc)
221231

222232
topic = f'User ID: {recipient.id}'
223233
mention = self.bot.config.get('MENTION', '@here') if not creator else None
@@ -233,6 +243,39 @@ async def create(self, recipient, *, creator=None):
233243
async def find_or_create(self, recipient):
234244
return await self.find(recipient=recipient) or await self.create(recipient)
235245

246+
@staticmethod
247+
def valid_image_url(url):
248+
'''Checks if a url leads to an image.'''
249+
types = ['.png', '.jpg', '.gif', '.webp']
250+
parsed = urlparse(url)
251+
if any(parsed.path.endswith(i) for i in types):
252+
return url.replace(parsed.query, 'size=128')
253+
return False
254+
255+
@asyncexecutor()
256+
def _do_get_dc(self, image, quality):
257+
with io.BytesIO(image) as f:
258+
return ColorThief(f).get_color(quality=quality)
259+
260+
async def get_dominant_color(self, url=None, quality=10):
261+
'''
262+
Returns the dominant color of an image from a url
263+
(misc)
264+
'''
265+
url = self.valid_image_url(url)
266+
267+
if not url:
268+
raise ValueError('Invalid image url passed.')
269+
try:
270+
async with self.bot.session.get(url) as resp:
271+
image = await resp.read()
272+
color = await self._do_get_dc(image, quality)
273+
except Exception as e:
274+
traceback.print_exc()
275+
return discord.Color.blurple()
276+
else:
277+
return discord.Color.from_rgb(*color)
278+
236279
def _format_channel_name(self, author):
237280
'''Sanitises a username for use with text channel names'''
238281
name = author.name.lower()
@@ -243,27 +286,22 @@ def _format_channel_name(self, author):
243286
new_name += '-x' # two channels with same name
244287
return new_name
245288

246-
def _format_info_embed(self, user, creator, log_url, log_count=None):
289+
def _format_info_embed(self, user, creator, log_url, log_count, dc):
247290
'''Get information about a member of a server
248291
supports users from the guild or not.'''
249292
server = self.bot.guild
250293
member = self.bot.guild.get_member(user.id)
251294
avi = user.avatar_url
252295
time = datetime.datetime.utcnow()
253-
desc = f'{creator.mention} has created a thread with {user.mention}' if creator else f'{user.mention} has started a thread.'
296+
desc = f'{creator.mention} has created a thread with {user.mention}' if creator else f'{user.mention} has started a thread:'
254297
key = log_url.split('/')[-1]
255298
desc = f'{desc} [`{key}`]({log_url})'
256-
color = discord.Color.blurple()
257299

258300
if member:
259301
roles = sorted(member.roles, key=lambda c: c.position)
260302
rolenames = ' '.join([r.mention for r in roles if r.name != "@everyone"])
261-
# member_number = sorted(server.members, key=lambda m: m.joined_at).index(member) + 1
262-
for role in roles:
263-
if str(role.color) != "#000000":
264-
color = role.color
265303

266-
em = discord.Embed(colour=color, description=desc, timestamp=time)
304+
em = discord.Embed(colour=dc, description=desc, timestamp=time)
267305

268306
days = lambda d: (' day ago.' if d == '1' else ' days ago.')
269307

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ git+https://github.com/Rapptz/discord.py@rewrite
22
colorama
33
cachetools
44
python-dateutil
5-
python-box
5+
python-box
6+
colorthief

0 commit comments

Comments
 (0)