mirror of
https://github.com/artiemis/artemis.git
synced 2026-02-14 08:31:55 +00:00
139 lines
4.3 KiB
Python
139 lines
4.3 KiB
Python
from __future__ import annotations
|
|
|
|
import re
|
|
from typing import Any, Optional
|
|
|
|
import discord
|
|
from anilist.types import Anime, Character, Manga
|
|
|
|
from utils.common import trim
|
|
|
|
ANILIST_COLOR = 0x02A9FF
|
|
FOOTER = "Powered by AniList APIv2"
|
|
|
|
media_formats_map = {
|
|
"TV": "TV",
|
|
"TV_SHORT": "TV Short",
|
|
"MOVIE": "Movie",
|
|
"SPECIAL": "Special",
|
|
"OVA": "OVA",
|
|
"ONA": "ONA",
|
|
"MUSIC": "Music",
|
|
"MANGA": "Manga",
|
|
"NOVEL": "Novel",
|
|
"ONE_SHOT": "One Shot",
|
|
}
|
|
|
|
|
|
class BaseEmbed(discord.Embed):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(color=ANILIST_COLOR, *args, **kwargs)
|
|
self.set_footer(text=FOOTER)
|
|
|
|
|
|
def get(obj: Any, prop: str, default: Optional[str] = None):
|
|
return getattr(obj, prop, default)
|
|
|
|
|
|
def get_character_summary(character: Character) -> Optional[str]:
|
|
if not get(character, "description"):
|
|
return "No description available."
|
|
|
|
clean, spoilers = [], []
|
|
description = character.description
|
|
|
|
def repl(m):
|
|
spoilers.append(f"||{m.group(1)}||")
|
|
return ""
|
|
|
|
description = re.sub(r"~!(.+?)!~", repl, description, re.S)
|
|
|
|
lines = description.split("\n")
|
|
lines = [line for line in lines if line]
|
|
|
|
for line in lines:
|
|
if re.search(r"^__.+(:__|__:|__.+:)|^\*\*.+(:\*\*|\*\*:|\*\*.+:)", line):
|
|
continue
|
|
else:
|
|
clean.append(line.strip())
|
|
|
|
if clean:
|
|
ret = clean[0]
|
|
if len(ret) < 100 and len(clean) > 1:
|
|
ret += f"\n{clean[1]}"
|
|
return trim(ret, 512)
|
|
elif spoilers:
|
|
return spoilers[0]
|
|
else:
|
|
return "No description available."
|
|
|
|
|
|
def build_anilist_embed(result: Anime | Manga) -> discord.Embed:
|
|
title = get(result.title, "english", result.title.romaji)
|
|
description = result.description.split("<br>")[0] if get(result, "description") else ""
|
|
description = re.sub(r"<.+?>", "", description)
|
|
|
|
source = result.source.replace("_", " ").title() if get(result, "source") else "N/A"
|
|
status = result.status.replace("_", " ").title() if get(result, "status") else "N/A"
|
|
start_date: Any = get(result, "start_date")
|
|
url = result.url
|
|
mid = result.id
|
|
|
|
embed = BaseEmbed(title=title, url=url, description=description)
|
|
embed.set_image(url=f"https://img.anili.st/media/{mid}")
|
|
embed.add_field(name="Source", value=source)
|
|
embed.add_field(name="Status", value=status)
|
|
|
|
if start_date and get(start_date, "year"):
|
|
embed.add_field(name="Release Year", value=start_date.year, inline=True)
|
|
|
|
if result is Anime:
|
|
nextairing = get(result, "next_airing", None)
|
|
episodes = get(result, "episodes") or get(nextairing, "episode")
|
|
duration = get(result, "duration")
|
|
|
|
media_format = media_formats_map.get(result.format)
|
|
embed.add_field(name="Type", value=media_format)
|
|
|
|
if episodes:
|
|
embed.add_field(name="Episodes", value=episodes)
|
|
if duration:
|
|
duration = (
|
|
str(duration) + " mins per ep." if media_format == "TV" else str(duration) + " mins"
|
|
)
|
|
embed.add_field(name="Duration", value=duration)
|
|
elif result is Manga:
|
|
volumes = get(result, "volumes")
|
|
chapters = get(result, "chapters")
|
|
|
|
if volumes:
|
|
embed.add_field(name="Volumes", value=volumes)
|
|
if chapters:
|
|
embed.add_field(name="Chapters", value=chapters)
|
|
return embed
|
|
|
|
|
|
def build_character_embed(character: Character) -> discord.Embed:
|
|
name = character.name.full
|
|
if get(character.name, "native"):
|
|
name += f" ({character.name.native})"
|
|
url = character.url
|
|
image = character.image.large if get(character, "image") else None
|
|
media = character.media if get(character, "media") else None
|
|
description = get_character_summary(character) or ""
|
|
|
|
if media:
|
|
media_joined = "**Featured in:**\n"
|
|
for entry in media[:3]:
|
|
title = entry["title"].get("english") or entry["title"].get("romaji")
|
|
entry_url = f"https://anilist.co/{entry['type'].lower()}/{entry['id']}"
|
|
media_joined += f"[{title}]({entry_url})\n"
|
|
if len(media) > 3:
|
|
media_joined += f"[**+ {len(media) - 3} more**]({url})"
|
|
description += f"\n\n{media_joined}"
|
|
|
|
embed = BaseEmbed(title=name, url=url, description=description)
|
|
if image:
|
|
embed.set_image(url=image)
|
|
return embed
|