Skip to content

Commit

Permalink
Merge pull request #8 from zeroquinc:simple-embeds
Browse files Browse the repository at this point in the history
feature: make toggle for more compact embeds
  • Loading branch information
zeroquinc authored May 21, 2024
2 parents 75ee0fb + 169d4cf commit d3fb78e
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 41 deletions.
1 change: 1 addition & 0 deletions config/config_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
TROPHIES_CHANNEL_ID = ''
PLATINUM_CHANNEL_ID = ''
TROPHIES_INTERVAL = 60
COMPACT_EMBED = True

# The delay before starting the tasks, useful for debugging, otherwise it will start within the first 15th minute
TASK_START_DELAY = {
Expand Down
11 changes: 11 additions & 0 deletions src/discord.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ async def create_trophy_embed(trophy, trophy_title_info, client, current, total_
embed.set_author(name="A Trophy Unlocked", icon_url=trophy_title.title_icon_url)
return embed

async def create_simple_trophy_embed(trophy, trophy_title_info, client, current, total_trophies):
trophy_title = trophy_title_info['trophy_title']
game_url = format_title(trophy_title.title_name) # format the title name into a URL
most_common_color = await get_discord_color(trophy.trophy_icon_url)
completion = current
percentage = (completion / total_trophies) * 100
embed = discord.Embed(description=f"**{trophy.trophy_name} {replace_trophy_with_emoji(trophy.trophy_type.name.lower())} {trophy.trophy_earn_rate}%**\n{trophy.trophy_detail}\n\n[{trophy_title.title_name}]({game_url})", color=most_common_color)
embed.set_thumbnail(url=trophy.trophy_icon_url)
embed.set_footer(text=f"{format_date(trophy.earned_date_time)}{completion}/{total_trophies} ({percentage:.2f}%)", icon_url=client.profile_picture_url)
return embed

async def create_platinum_embed(trophy, trophy_title_info, client, formatted_time_diff):
trophy_title = trophy_title_info['trophy_title']
game_url = format_title(trophy_title.title_name) # format the title name into a URL
Expand Down
31 changes: 17 additions & 14 deletions src/trophies.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
from datetime import timedelta
from psnawp_api import PSNAWP

from src.discord import create_trophy_embed, create_platinum_embed, send_trophy_embeds, send_platinum_embeds
from src.discord import create_trophy_embed, create_simple_trophy_embed, create_platinum_embed, send_trophy_embeds, send_platinum_embeds

from utils.datetime import calculate_total_time, get_current_time
from config.config import PSNTOKEN, TROPHIES_INTERVAL
from config.config import PSNTOKEN, TROPHIES_INTERVAL, COMPACT_EMBED

from utils.custom_logger import logger

psnawp = PSNAWP(PSNTOKEN)
profile_picture = {}

def get_client():
client = psnawp.me()
logger.info(f"Calling Sony API for profile information for user {client.online_id}")
profile_legacy = client.get_profile_legacy()
profile_picture_url = profile_legacy['profile']['personalDetail']['profilePictureUrls'][0]['profilePictureUrl']
client.profile_picture_url = profile_picture_url
online_id = client.online_id
if online_id in profile_picture:
client.profile_picture_url = profile_picture[online_id]
logger.info(f"Loaded profile picture from cache for user {online_id}")
else:
logger.info(f"Calling Sony API for profile information for user {online_id}")
profile_legacy = client.get_profile_legacy()
profile_picture_url = profile_legacy['profile']['personalDetail']['profilePictureUrls'][0]['profilePictureUrl']
client.profile_picture_url = profile_picture_url
profile_picture[online_id] = profile_picture_url
return client

def get_recent_titles(client, hours=24):
Expand Down Expand Up @@ -62,23 +69,19 @@ async def get_earned_and_recent_trophies(client, title_id, platform, TROPHIES_IN
async def create_trophy_and_platinum_embeds(client, earned_trophies, recent_trophies, total_trophies):
trophy_embeds = []
platinum_embeds = []
# Calculate total trophies earned (after filtering)
total_trophies_earned = len(earned_trophies)
# Calculate the starting count
starting_count = total_trophies_earned - len(recent_trophies)
for i, (trophy, trophy_title) in enumerate(recent_trophies):
# Pass total_trophies to create_trophy_embed function
embed = await create_trophy_embed(trophy, trophy_title, client, starting_count + i + 1, total_trophies)
if COMPACT_EMBED:
embed = await create_simple_trophy_embed(trophy, trophy_title, client, starting_count + i + 1, total_trophies)
else:
embed = await create_trophy_embed(trophy, trophy_title, client, starting_count + i + 1, total_trophies)
trophy_embeds.append((trophy.earned_date_time, embed))
if trophy.trophy_type.name.lower() == 'platinum':
# Get the oldest and newest trophy
oldest_trophy = earned_trophies[0]
newest_trophy = earned_trophies[-1]
# Calculate the time difference
time_diff = newest_trophy[0].earned_date_time - oldest_trophy[0].earned_date_time
# Format the time difference
formatted_time_diff = calculate_total_time(time_diff)
# Pass formatted_time_diff to create_platinum_embed function
embed = await create_platinum_embed(trophy, trophy_title, client, formatted_time_diff)
platinum_embeds.append((trophy.earned_date_time, embed))
return trophy_embeds, platinum_embeds
Expand Down
2 changes: 1 addition & 1 deletion utils/datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,4 @@ def format_date(date: datetime) -> str:
"""
amsterdam_tz = pytz.timezone('Europe/Amsterdam')
date = date.astimezone(amsterdam_tz)
return date.strftime("%d/%m/%y at %H:%M:%S")
return date.strftime("%d/%m/%y %H:%M:%S")
33 changes: 7 additions & 26 deletions utils/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,35 @@
import requests
from io import BytesIO
import numpy as np
from sklearn.cluster import KMeans
import asyncio

def is_colorful(color, tolerance=20, saturation_threshold=50):
def is_colorful(color):
r, g, b = color
saturation = np.std([r, g, b])
return (
saturation > saturation_threshold and
(abs(r - g) >= tolerance or abs(r - b) >= tolerance or abs(g - b) >= tolerance)
)
return np.std([r, g, b])

async def get_discord_color(image_url, num_colors=10, crop_percentage=0.5):
async def get_discord_color(image_url, crop_percentage=0.5):
loop = asyncio.get_event_loop()
return await loop.run_in_executor(
None,
get_discord_color_blocking,
image_url,
num_colors,
crop_percentage,
)

def get_discord_color_blocking(image_url, num_colors=10, crop_percentage=0.5):
def get_discord_color_blocking(image_url, crop_percentage=0.5):
response = requests.get(image_url)
img = Image.open(BytesIO(response.content))

width, height = img.size
crop_width = int(width * crop_percentage)
crop_height = int(height * crop_percentage)
left = (width - crop_width) // 2
top = (height - crop_height) // 2
right = left + crop_width
bottom = top + crop_height

img = img.crop((left, top, right, bottom))

img = img.resize((img.width // 2, img.height // 2))

img = img.convert("RGB")

img_array = np.array(img)
img_flattened = img_array.reshape(-1, 3)

kmeans = KMeans(n_clusters=num_colors)
kmeans.fit(img_flattened)

counts = np.bincount(kmeans.labels_)
sorted_colors = sorted([(count, color) for count, color in zip(counts, kmeans.cluster_centers_) if is_colorful(color)], reverse=True)

dominant_color = sorted_colors[0][1] if len(sorted_colors) != 0 else kmeans.cluster_centers_[np.argmax(counts)]

return int('0x{:02x}{:02x}{:02x}'.format(*dominant_color.astype(int)), 16)
colorfulness = np.apply_along_axis(is_colorful, 1, img_flattened)
most_colorful_color = img_flattened[np.argmax(colorfulness)]
return int('0x{:02x}{:02x}{:02x}'.format(*most_colorful_color), 16)

0 comments on commit d3fb78e

Please sign in to comment.