-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
205 lines (184 loc) · 9.72 KB
/
utils.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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# builtin imports
import time
import zoneinfo
import datetime
import discord
# 3rd party imports
import malclient
import requests
# project imports
from res.Models import *
from res.crud import *
from res.BotBase import *
from rss_parser import Parser
__weekdays__ = {'monday': 0,
"tuesday": 1,
'wednesday': 2,
"thursday": 3,
'friday': 4,
"saturday": 5,
'sunday': 6}
def calculate_release_date(mal_info: malclient.AnimeObject, episode_num) -> datetime.datetime:
"""
This is just an estimate, real times may vary
:param mal_info:
:param episode_num:
:return:
"""
assert mal_info.start_date and mal_info.broadcast
start_date = datetime.datetime.combine(mal_info.start_date, mal_info.broadcast.start_time,
tzinfo=zoneinfo.ZoneInfo("Asia/Tokyo"))
delta = datetime.timedelta(days=(episode_num - 1) * 7)
return start_date + delta
def calculate_newest_episode_release_date(mal_info: malclient.AnimeObject):
"""
This is just an estimate, real times may vary
:param mal_info:
:return:
"""
now = datetime.datetime.now(tz=zoneinfo.ZoneInfo('Asia/Tokyo'))
broadcast: malclient.Broadcast = mal_info.broadcast
day_difference = abs(now.weekday() - __weekdays__[broadcast.day_of_the_week.lower()])
day_difference = day_difference if day_difference != 0 else (0 if broadcast.start_time < now.time() else 7)
return datetime.datetime.combine(now.date(), broadcast.start_time,
tzinfo=zoneinfo.ZoneInfo('Asia/Tokyo')) - datetime.timedelta(days=day_difference)
async def render_new_channel_description(bot: Hanyasaka, channel: discord.TextChannel, role: Optional[int] = None):
series: TLSerieModel = get_serie_by_channel(bot.tl_db, channel.id)
users = get_users_by_series_id(bot.tl_db, series.id)
description = [f"**{series.title}**", ]
for user in users:
discord_user = bot.get_user(user.uid)
description.append(user.role.title() + ": " + discord_user.mention)
mal_info = bot.client.get_anime_details(series.mal_id)
episode_num = get_episodes_by_series_id(bot.tl_db, series.id)
try:
if str(episode_num[-1].status[-1]) == "1":
episode_num.append("This is placeholder entry, please ignore")
except IndexError:
pass
# TODO information about series being already finished
try:
release_date = calculate_release_date(mal_info, len(episode_num))
time_string = time.mktime(release_date.timetuple())
except Exception as e: # In particular AssertionError
time_string = None
finally:
description.append(f"Wychodzi: {f'<t:{int(time_string)}:R>' if time_string is not None else 'N/A'}")
# TODO information about series specific role
description.append(f"Role: {'' if role is None else f' <@&{role}>'}")
return "\n".join(description)
def get_xml_tree(url: str, limit: int = 3):
data = requests.get(url)
parsed = Parser(data.text, limit=limit)
return parsed.parse()
def render_nyaa_embed(series_title: str, team: str = "[SubsPlease]", *, base_url="https://nyaa.si/?page=rss&", color=0x0085fe):
url = base_url + f"q={team}+{series_title.replace(' ', '+')}"
feed = get_xml_tree(url)
embed = discord.Embed(title="Ostatnie trafienia z nyaa.si",
description='Jeśli żadne z poniższych nie odpowiada nowemu odcinkowi spróbuj ponownie później na [nyaa.si](https://nyaa.si)',
color=color)
for item in feed.feed:
publish_time = datetime.datetime.strptime(item.publish_date, '%a, %d %b %Y %H:%M:%S %z')
embed.add_field(name=f"**{item.title}**",
value=f"**Opublikowany**: <t:{int(time.mktime(publish_time.timetuple()))}:f>\n"
f"**Link do pobrania**: [Torrent]({item.link})", inline=False)
embed.set_footer(text="Ta akcja została wykonana automatycznie, błędy zgłaszaj do @Gruzin#0911")
embed.set_thumbnail(url="https://upload.wikimedia.org/wikipedia/commons/a/a0/Nyaa_Logo.png?20220727013144")
return embed
def status_embed_generator(tl_db, client: malclient.Client, title: str, guild: discord.Guild, type: Literal["compact", "complex"] = "compact"):
# fetch data from database
team: TlTeamModel = get_team_by_guild(tl_db, guild)
if not team:
return ":exclamation: Na tym serwerze nie ma zadnej grupy do tłumaczeń"
series: TLSerieModel = get_serie_by_title(tl_db, team, title)
if not series:
return ":exclamation: Nie mam serii o takim tytule"
episodes: list[EpisodeModel] = get_episodes_by_series_id(tl_db, series)
users: list[TlUserModel] = get_users_by_series_id(tl_db, series)
print(users, episodes, series, sep="\n")
mal_data: malclient.AnimeObject = client.get_anime_details(series.mal_id)
# generate embed
embed = discord.Embed(title=series.title, description=f"", color=eval(f"0x{series.color}"))
if type == "compact": # if no episodes where added present anime thumbnail and description
embed.set_image(
url=mal_data.main_picture.medium if not mal_data.main_picture.large else mal_data.main_picture.large)
if len(series.description) != 0:
embed.description += f"\n{series.description}"
elif type == "complex": # If episodes were added show their status
for i in range(mal_data.num_episodes) if mal_data.num_episodes != 0 else range(len(episodes)):
try:
assert i < len(episodes) # check if episode with this number was translated already
value = "Nieznany"
if episodes[i].status[6] == '1':
value = "Zakończony"
elif episodes[i].status[5] == '1':
value = "Wypalony"
elif episodes[i].status[4] == '1':
value = "Typesetting\nskończony"
elif episodes[i].status[3] == '1':
value = "Korekta\nskończona"
elif episodes[i].status[2] == '1':
value = "Przetłumaczony\nna Polski"
elif episodes[i].status[1] == '1':
value = "Przetłumaczony\nna Angielski"
elif episodes[i].status[0] == '1':
value = "Oryginał\ndostępny"
except AssertionError: # if not display data depending on MAL
if mal_data.start_date + datetime.timedelta(days=7 * (i + 1) - 1) > datetime.datetime.utcnow().date():
value = "Nie wypuszczony"
else:
value = "Dostępny w Japonii"
embed.add_field(name=f"Odcinek {i + 1}", value=value)
embed.set_thumbnail(url=mal_data.main_picture.medium)
embed.set_author(
name=f"Przygotowane przez {team.name}",
icon_url=guild.icon.url)
embed.description += "\n\n"
user_string = ""
for user in users:
user_string += f"{user.role.capitalize()}: <@!{user.uid}>\n"
embed.add_field(name="Zespół", value=user_string, inline=True)
embed.add_field(name="Liczba odcinków", value=f"{len(episodes)}/{mal_data.num_episodes if mal_data.num_episodes != 0 else 'N/A'}", inline=True)
return [embed, series]
def anime_embed_generator(anime: malclient.AnimeObject, user: discord.Member | discord.User):
try:
anime_embed = discord.Embed(title=anime.title,
description=f'{anime.alternative_titles["synonyms"][0]}\n\nSerie by: **{anime.studios[0].name}**',
url=f'https://www.myanimelist.net/anime/{anime.id}')
except IndexError:
try:
anime_embed = discord.Embed(title=anime.title, description=f'Serie by: **{anime.studios[0].name}**',
url=f'https://www.myanimelist.net/anime/{anime.id}', colour=0xfc8cac)
except IndexError:
anime_embed = discord.Embed(title=anime.title,
url=f'https://www.myanimelist.net/anime/{anime.id}', colour=0xfc8cac)
anime_embed.set_author(name="Pobrane z MAL",
icon_url=self.bot.user.avatar.url)
anime_embed.add_field(name=f'🎞️ Ilość odcinków: ',
value=anime.num_episodes, inline=True)
anime_embed.add_field(name=f'📺 Typ:',
value=str(anime.media_type.name).capitalize(), inline=True)
try:
anime_embed.add_field(name=f'🏆 Ocena:', value=anime.mean, inline=False)
except AttributeError:
anime_embed.add_field(name=f'🏆 Ocena:', value='N/A', inline=False)
anime_embed.add_field(name=f'✨ Gatunki:',
value=f'{", ".join([genre.name for genre in anime.genres])}', inline=False)
if anime.status != 'not_yet_aired':
anime_embed.add_field(name=f'📅 Rozpoczęta:', value=anime.start_date,
inline=True)
try:
anime_embed.add_field(name=f'📅 Zakończona:', value=anime.end_date,
inline=True)
except AttributeError:
anime_embed.add_field(name=f'📅 Zakończona: ', value='Wciąż wychodzi')
else:
anime_embed.add_field(name=f'📅 Status', value='Jeszcze nie wyemitowane', inline=False)
anime_embed.add_field(name=f'📝 Opis:',
value=f'{anime.synopsis[:1018]} {"[...]" if len(anime.synopsis) > 1019 else ""}' if len(
anime.synopsis) != 0 else "N/A", inline=False)
anime_embed.set_thumbnail(url=anime.main_picture.large)
anime_embed.set_footer(
text=f'{user.name}#{str(user.discriminator)} ({str(user.id)})',
icon_url=user.avatar.url)
return anime_embed