This commit is contained in:
leander committed 2026-10-24 05:02:23 +02:00
1 parent 4607aa7725
commit 0c0e4ff5ff
3 files changed
+80 -127

No files matched your search

+65 -102
View File
@@ -147,6 +147,26 @@ class Anime(commands.Cog):
}
return statuses.get(status, status)
def get_status_stat(self, statuses: list[dict], status: str, stat: str = "count") -> int:
"""
Gets a statistic for one list status from a user's Anilist statistics
Parameters
----------
statuses (list[dict]): The statuses statistics returned from the Anilist API
status (str): The list status, e.g. COMPLETED or PLANNING
stat (str): The statistic to get. Defaults to count
Returns
----------
(int): The statistic. 0 if the user has nothing with that status
"""
for entry in statuses:
if entry["status"] == status:
return entry[stat]
return 0
def is_nsfw_channel(self, interaction: discord.Interaction) -> bool:
"""
Checks whether the interaction's channel is age-restricted. DMs are never treated as NSFW
@@ -265,31 +285,40 @@ class Anime(commands.Cog):
return "\n".join(favortie_entities)
def construct_release_schedule_string(self, numbers: dict) -> str:
def format_fuzzy_date(self, date: dict) -> str:
"""
Formats an Anilist FuzzyDate, where any part may be missing
Parameters
----------
date (dict): The date with the keys year, month and day returned from the Anilist API
Returns
----------
(str): A Discord timestamp if the date is complete, otherwise day.month.year with ? for missing parts
"""
year, month, day = date.get("year"), date.get("month"), date.get("day")
if year and month and day:
return discord.utils.format_dt(datetime(year, month, day), style="d")
return f"{day or '?'}.{month or '?'}.{year or '?'}"
def construct_release_schedule_string(self, start_date: dict, end_date: dict) -> str:
"""
Constructs a string with the media's release schedule
Parameters
----------
numbers (dict): dict containing release date and end date
start_date (dict): The release date returned from the Anilist API
end_date (dict): The end date returned from the Anilist API
Returns
----------
(str): The constructed string
"""
# Release and end date formatting
if numbers["start_day"] != "?" and numbers["start_month"] != "?" and numbers["start_year"] != "?":
release_date = datetime(numbers["start_year"], numbers["start_month"], numbers["start_day"])
release_date = discord.utils.format_dt(release_date, style="d")
else:
release_date = f'{numbers["start_day"]}.{numbers["start_month"]}.{numbers["start_year"]}'
if numbers["end_day"] != "?" and numbers["end_month"] != "?" and numbers["end_year"] != "?":
end_date = datetime(numbers["end_year"], numbers["end_month"], numbers["end_day"])
end_date = discord.utils.format_dt(end_date, style="d")
else:
end_date = f'{numbers["end_day"]}.{numbers["end_month"]}.{numbers["end_year"]}'
release_date = self.format_fuzzy_date(start_date)
end_date = self.format_fuzzy_date(end_date)
if release_date == end_date:
date = release_date
@@ -396,21 +425,8 @@ class Anime(commands.Cog):
chapters_read = data["statistics"]["manga"]["chaptersRead"]
color = self.convert_color(data["options"]["profileColor"])
anime_statuses = {
status["status"]: {"count": status["count"]} for status in data["statistics"]["anime"]["statuses"]
}
manga_statuses = {
status["status"]: {"count": status["count"]} for status in data["statistics"]["manga"]["statuses"]
}
try:
anime_completed = anime_statuses["COMPLETED"]["count"]
except KeyError:
anime_completed = 0
try:
manga_completed = manga_statuses["COMPLETED"]["count"]
except KeyError:
manga_completed = 0
anime_completed = self.get_status_stat(data["statistics"]["anime"]["statuses"], "COMPLETED")
manga_completed = self.get_status_stat(data["statistics"]["manga"]["statuses"], "COMPLETED")
favourite_anime = self.construct_favorite_media_string(data["favourites"]["anime"]["nodes"])
favourite_manga = self.construct_favorite_media_string(data["favourites"]["manga"]["nodes"])
@@ -498,29 +514,12 @@ class Anime(commands.Cog):
episodes_watched = data["statistics"]["anime"]["episodesWatched"]
color = self.convert_color(data["options"]["profileColor"])
statuses = {
status["status"]: {"count": status["count"], "minutes": status["minutesWatched"]}
for status in data["statistics"]["anime"]["statuses"]
}
try:
completed = statuses["COMPLETED"]["count"]
except KeyError:
completed = 0
try:
watching = statuses["CURRENT"]["count"]
except KeyError:
watching = 0
try:
planning = statuses["PLANNING"]["count"]
planning_days = round(statuses["PLANNING"]["minutes"] / 1440, 1)
except KeyError:
planning = 0
planning_days = 0
try:
dropped = statuses["DROPPED"]["count"]
except KeyError:
dropped = 0
statuses = data["statistics"]["anime"]["statuses"]
completed = self.get_status_stat(statuses, "COMPLETED")
watching = self.get_status_stat(statuses, "CURRENT")
planning = self.get_status_stat(statuses, "PLANNING")
planning_days = round(self.get_status_stat(statuses, "PLANNING", "minutesWatched") / 1440, 1)
dropped = self.get_status_stat(statuses, "DROPPED")
anime_mean_score = data["statistics"]["anime"]["meanScore"]
if not anime_mean_score:
@@ -608,29 +607,12 @@ class Anime(commands.Cog):
volumes_read = data["statistics"]["manga"]["volumesRead"]
color = self.convert_color(data["options"]["profileColor"])
statuses = {
status["status"]: {"count": status["count"], "chapters": status["chaptersRead"]}
for status in data["statistics"]["manga"]["statuses"]
}
try:
completed = statuses["COMPLETED"]["count"]
except KeyError:
completed = 0
try:
reading = statuses["CURRENT"]["count"]
except KeyError:
reading = 0
try:
planning = statuses["PLANNING"]["count"]
planning_chapters = statuses["PLANNING"]["chapters"]
except KeyError:
planning = 0
planning_chapters = 0
try:
dropped = statuses["DROPPED"]["count"]
except KeyError:
dropped = 0
statuses = data["statistics"]["manga"]["statuses"]
completed = self.get_status_stat(statuses, "COMPLETED")
reading = self.get_status_stat(statuses, "CURRENT")
planning = self.get_status_stat(statuses, "PLANNING")
planning_chapters = self.get_status_stat(statuses, "PLANNING", "chaptersRead")
dropped = self.get_status_stat(statuses, "DROPPED")
manga_mean_score = data["statistics"]["manga"]["meanScore"]
if manga_mean_score == 0:
@@ -767,25 +749,14 @@ class Anime(commands.Cog):
episodes = data["episodes"]
duration = data["duration"]
numbers = {
"episodes": episodes,
"duration": duration,
"start_day": data["startDate"].get("day") if data["startDate"].get("day") else "?",
"start_month": data["startDate"].get("month") if data["startDate"].get("month") else "?",
"start_year": data["startDate"].get("year") if data["startDate"].get("year") else "?",
"end_day": data["endDate"].get("day") if data["endDate"].get("day") else "?",
"end_month": data["endDate"].get("month") if data["endDate"].get("month") else "?",
"end_year": data["endDate"].get("year") if data["endDate"].get("year") else "?",
}
date = self.construct_release_schedule_string(numbers)
date = self.construct_release_schedule_string(data["startDate"], data["endDate"])
length_string = ""
if numbers["duration"] == 1:
if duration == 1:
length_string += "minutt "
else:
length_string += "minutter "
if numbers["episodes"] == 1:
if episodes == 1:
length_string += "lang"
else:
length_string += "lange"
@@ -918,20 +889,12 @@ class Anime(commands.Cog):
staff_url = staff_member["node"]["siteUrl"]
staff_string += f"[{staff_first_name} {staff_last_name} ({staff_native_name})]({staff_url})\n"
numbers = {
"chapters": data["chapters"],
"volumes": data["volumes"],
"start_day": data["startDate"].get("day") if data["startDate"].get("day") else "?",
"start_month": data["startDate"].get("month") if data["startDate"].get("month") else "?",
"start_year": data["startDate"].get("year") if data["startDate"].get("year") else "?",
"end_day": data["endDate"].get("day") if data["endDate"].get("day") else "?",
"end_month": data["endDate"].get("month") if data["endDate"].get("month") else "?",
"end_year": data["endDate"].get("year") if data["endDate"].get("year") else "?",
}
date = self.construct_release_schedule_string(numbers)
chapters = data["chapters"]
volumes = data["volumes"]
date = self.construct_release_schedule_string(data["startDate"], data["endDate"])
chapters_string = ""
if numbers["chapters"] == 1:
if chapters == 1:
chapters_string += "kapittel"
else:
chapters_string += "kapitler"
@@ -949,7 +912,7 @@ class Anime(commands.Cog):
if staff_string:
embed.add_field(name="Laget av", value=staff_string)
embed.add_field(name="Utgivelsesdato", value=date)
embed.add_field(name="Lengde", value=f'{numbers["chapters"]} {chapters_string}\n{numbers["volumes"]} volum')
embed.add_field(name="Lengde", value=f"{chapters} {chapters_string}\n{volumes} volum")
if mean_score:
embed.add_field(name="Gj.snittsvurdering", value=f"{mean_score}/100")
embed.add_field(name="Sjangere", value=genres)
+2 -7
View File
@@ -88,7 +88,8 @@ class Errors(commands.Cog):
if isinstance(error, send_help):
return await ctx.send_help(ctx.command)
elif isinstance(error, commands.BotMissingPermissions):
f = None
if isinstance(error, commands.BotMissingPermissions):
embed = self.error_missing_perms(error.missing_permissions, "Jeg")
elif isinstance(error, commands.MissingPermissions):
embed = self.error_missing_perms(error.missing_permissions, "Du")
@@ -107,12 +108,6 @@ class Errors(commands.Cog):
f = discord.File("./src/assets/edb.png")
embed.set_image(url="attachment://edb.png")
# Yeah, this fucking sucks but I want my beautiful edb picture :_;
try:
f
except NameError:
f = None
try:
await ctx.reply(embed=embed, file=f)
except discord.errors.Forbidden:
+13 -18
View File
@@ -197,7 +197,8 @@ class LobbyView(discord.ui.View):
self.bot = bot
self.message: discord.Message | None = None
self.add_item(_KickSelectMenu(self))
self.kick_menu = _KickSelectMenu(self)
self.add_item(self.kick_menu)
async def on_timeout(self):
await self.end_lobby()
@@ -213,9 +214,7 @@ class LobbyView(discord.ui.View):
item.disabled = True
async def rerender_players(self, interaction: discord.Interaction):
self.children[-1].options = [
discord.SelectOption(label=p.display_name, value=str(p.id), emoji="🔨") for p in self.lobby.players
]
self.kick_menu.update_options()
embed = interaction.message.embeds[0].set_field_at(
0,
name=f"Spillere ({len(self.lobby.players)})",
@@ -299,24 +298,20 @@ class LobbyView(discord.ui.View):
class _KickSelectMenu(discord.ui.Select):
def __init__(self, parent_view: LobbyView):
self.parent_view = parent_view
options = [
super().__init__(placeholder="Kick en spiller", max_values=1, min_values=1)
self.update_options()
def update_options(self):
"""
Lists the lobby's current players as options
"""
self.options = [
discord.SelectOption(
label=p.display_name, value=str(p.id), emoji="🔨", description=f"Kick {p.display_name}"
)
for p in self.parent_view.lobby.players
]
super().__init__(placeholder="Kick en spiller", max_values=1, min_values=1, options=options)
# TODO: DRY
async def rerender_players(self, interaction: discord.Interaction):
self.options = [
discord.SelectOption(label=p.display_name, value=str(p.id), emoji="🔨")
for p in self.parent_view.lobby.players
]
embed = interaction.message.embeds[0].set_field_at(
0, name="Spillere", value="\n".join([f"* {p.mention}" for p in self.parent_view.lobby.players])
)
await interaction.message.edit(embed=embed, view=self.parent_view)
async def callback(self, interaction: discord.Interaction):
if interaction.user != self.parent_view.lobby.host:
@@ -338,7 +333,7 @@ class _KickSelectMenu(discord.ui.Select):
self.parent_view.lobby.players.pop(i)
break
await self.rerender_players(interaction)
await self.parent_view.rerender_players(interaction)
embed = embed_templates.success("Brukeren har blitt sparket fra lobbyen")
await interaction.response.send_message(embed=embed, ephemeral=True, delete_after=5)