forked from samuel-peter-chowdhury/RankingBot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Bot.py
414 lines (379 loc) Β· 26.5 KB
/
Bot.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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
import os
import discord
from dotenv import load_dotenv
from discord.ext import commands
from Service import Service
from Database import RankType
import datetime
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
GUILD_NAME = os.getenv('DISCORD_GUILD')
MATCH_PREFIX = os.getenv('MATCH_PREFIX')
MATCH_CHANNEL = os.getenv('MATCH_CHANNEL')
DEFAULT_FORMAT = os.getenv('DEFAULT_FORMAT')
POKEMON_USAGE_CHANNEL = os.getenv('POKEMON_USAGE_CHANNEL')
LADDER_CHANNEL = os.getenv('LADDER_CHANNEL')
DEV_USER = os.getenv('DEV_USER')
intents = discord.Intents.all()
intents.members = True
bot = commands.Bot(command_prefix='+', intents=intents)
service = Service()
@bot.event
async def on_ready():
guild, match_channel = get_channel_by_name(MATCH_CHANNEL)
print(f'{bot.user} is connected to the following guild:\n{guild.name}(id: 'f'{guild.id})')
print('.....Initializing.....')
latest_match_date = service.get_latest_match_date()
try:
await scan_replays(10, latest_match_date)
print('.....Bot has finished initializing.....')
except Exception as e:
print(e)
@bot.event
async def on_message(message):
if message.channel.name == MATCH_CHANNEL and MATCH_PREFIX in message.content:
try:
links = get_links(message.content)
for link in links:
response = service.process_match(link)
if service.ladder_enabled:
if response:
await message.channel.send(embed=generate_embed('πͺ Ladder Update πͺ', service.latest_rank_update_text[RankType.MONTH], 0x5C2C06))
else:
await message.channel.send(embed=generate_embed('π Warning π', 'Match already processed', 0xE60019))
await update_usage_stats()
await update_ladder_stats()
except Exception as e:
print(e)
await message.channel.send(embed=BOT_WARNING_EMBED)
await bot.process_commands(message)
@bot.command(name='ranking', help='Use this command to get rankings. Ensure that all parameters are entered in the correct order!')
async def ranking(ctx, rank_type=commands.parameter(default='month', description='This parameter dictates whether the returned rankings are based on the current month or all time. Takes either "month" or "all" as a value.'), unranked=commands.parameter(default='ranked', description='This parameter dictates whether the returned rankings are based on ranked players (15 games or more) or all players. Takes either "ranked" or "unranked" as a value.'), limit=commands.parameter(default=20, description='This parameter dictates how many players will be returned in the rankings. Takes any integer as a value.'), format=commands.parameter(default=DEFAULT_FORMAT, description='This parameter dictates which format the rankings are based on. Takes any format as a value (e.g. "gen9nationaldexag", "gen9customgame", "gen9doublescustomgame", etc).')):
try:
if service.ladder_enabled:
if rank_type == 'all':
rank_text = service.generate_rank_text(RankType.ALL_TIME, None, unranked == 'unranked', limit, format)
else:
rank_text = service.generate_rank_text(RankType.MONTH, datetime.datetime.now(datetime.UTC), unranked == 'unranked', limit, format)
await ctx.channel.send(embed=generate_embed('π Rankings π', rank_text, 0x8B0000))
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='past_ranking', help='Use this command to get past rankings. Ensure that all parameters are entered in the correct order!')
async def past_ranking(ctx, month=commands.parameter(default='01', description='This parameter dictates which month the past rankings are based on. Takes a two digit number as a value (e.g. "01", "02", "12", etc).'), year=commands.parameter(default='2023', description='This parameter dictates which year the past rankings are based on. Takes a four digit number as a value (e.g. "2023", "2024", etc).'), unranked=commands.parameter(default='ranked', description='This parameter dictates whether the returned rankings are based on ranked players (15 games or more) or all players. Takes either "ranked" or "unranked" as a value.'), limit=commands.parameter(default=20, description='This parameter dictates how many players will be returned in the rankings. Takes any integer as a value.'), format=commands.parameter(default=DEFAULT_FORMAT, description='This parameter dictates which format the rankings are based on. Takes any format as a value (e.g. "gen9nationaldexag", "gen9customgame", "gen9doublescustomgame", etc).')):
try:
rank_text = service.generate_rank_text(RankType.MONTH, datetime.datetime(year=int(year), month=int(month), day=1, tzinfo=datetime.timezone.utc), unranked == 'unranked', limit, format)
await ctx.channel.send(embed=generate_embed(f'β Past Rankings ({month}/{year}) β', rank_text, 0xCD7F32))
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='show_rank', help='Use this command to get past rankings. Ensure that all parameters are entered in the correct order!')
async def show_rank(ctx, username=commands.parameter(default=None, description='This parameter dictates which user to show the rank for. Takes any showdown username as a value.'), rank_type=commands.parameter(default='month', description='This parameter dictates whether the returned rankings are based on the current month or all time. Takes either "month" or "all" as a value.'), format=commands.parameter(default=DEFAULT_FORMAT, description='This parameter dictates which format the rankings are based on. Takes any format as a value (e.g. "gen9nationaldexag", "gen9customgame", "gen9doublescustomgame", etc).')):
try:
if service.ladder_enabled:
if rank_type == 'all':
rank_text = service.get_user_rank(username.lower(), RankType.ALL_TIME, None, format)
else:
rank_text = service.get_user_rank(username.lower(), RankType.MONTH, datetime.datetime.now(datetime.UTC), format)
await ctx.channel.send(embed=generate_embed(f'β {username} Rank β', rank_text, 0x4169E1))
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='pokemon_usage', help='Use this command to get pokemon usage. Ensure that all parameters are entered in the correct order!')
async def pokemon_usage(ctx, username=commands.parameter(default='all', description='This parameter dictates which user to show pokemon usage for, or for all users. Takes any showdown username or "all" as a value.'), usage_type=commands.parameter(default='most', description='This parameter dictates which teams from the set of replays that should be taken into account; all teams, winning teams, or losing teams. Takes either "most", "win", or "lose" as a value.'), rank_type=commands.parameter(default='month', description='This parameter dictates whether the returned pokemon usages are based on the current month or all time. Takes either "month" or "all" as a value.'), limit=commands.parameter(default=5, description='This parameter dictates how many pokemon will be returned in the usage list. Takes any integer as a value.'), format=commands.parameter(default=DEFAULT_FORMAT, description='This parameter dictates which format the pokemon usages are based on. Takes any format as a value (e.g. "gen9nationaldexag", "gen9customgame", "gen9doublescustomgame", etc).')):
try:
if username == 'all':
if rank_type == 'all':
usage_text = service.get_all_pokemon_usage(usage_type, RankType.ALL_TIME, None, limit, format)
else:
usage_text = service.get_all_pokemon_usage(usage_type, RankType.MONTH, datetime.datetime.now(datetime.UTC), limit, format)
else:
if rank_type == 'all':
usage_text = service.get_pokemon_usage(username.lower(), usage_type, RankType.ALL_TIME, None, limit, format)
else:
usage_text = service.get_pokemon_usage(username.lower(), usage_type, RankType.MONTH, datetime.datetime.now(datetime.UTC), limit, format)
embed = generate_embed(f'π {"All Time" if username == "all" else username} Pokemon Usage π', usage_text, 0x1DB954)
embed.set_image(url=f'https://play.pokemonshowdown.com/sprites/ani/{usage_text.split("**")[1].split("**")[0].lower().replace(".", "").replace(" ", "")}.gif')
await ctx.channel.send(embed=embed)
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='pokemon_usage_one', help='Use this command to get pokemon usage for a single pokemon. Ensure that all parameters are entered in the correct order!')
async def pokemon_usage_one(ctx, pokemon=commands.parameter(default=None, description='This parameter dictates which pokemon should be returned. Takes a pokemon name as a value.'), usage_type=commands.parameter(default='most', description='This parameter dictates which teams from the set of replays that should be taken into account; all teams, winning teams, or losing teams. Takes either "most", "win", or "lose" as a value.'), rank_type=commands.parameter(default='month', description='This parameter dictates whether the returned pokemon usage is based on the current month or all time. Takes either "month" or "all" as a value.'), format=commands.parameter(default=DEFAULT_FORMAT, description='This parameter dictates which format the pokemon usage is based on. Takes any format as a value (e.g. "gen9nationaldexag", "gen9customgame", "gen9doublescustomgame", etc).')):
try:
if rank_type == 'all':
usage_text = service.get_pokemon_usage_one(pokemon, usage_type, RankType.ALL_TIME, None, format)
else:
usage_text = service.get_pokemon_usage_one(pokemon, usage_type, RankType.MONTH, datetime.datetime.now(datetime.UTC), format)
embed = generate_embed(f'π² {pokemon} Usage π²', usage_text, 0xFFD700)
if '**' in usage_text:
embed.set_image(url=f'https://play.pokemonshowdown.com/sprites/ani/{usage_text.split("**")[1].split("**")[0].lower().replace(".", "").replace(" ", "")}.gif')
await ctx.channel.send(embed=embed)
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='past_pokemon_usage', help='Use this command to get past pokemon usage. Ensure that all parameters are entered in the correct order!')
async def past_pokemon_usage(ctx, username=commands.parameter(default='all', description='This parameter dictates which user to show pokemon usage for, or for all users. Takes any showdown username or "all" as a value.'), usage_type=commands.parameter(default='most', description='This parameter dictates which teams from the set of replays that should be taken into account; all teams, winning teams, or losing teams. Takes either "most", "win", or "lose" as a value.'), month=commands.parameter(default='01', description='This parameter dictates which month the past usages are based on. Takes a two digit number as a value (e.g. "01", "02", "12", etc).'), year=commands.parameter(default='2023', description='This parameter dictates which year the past usages are based on. Takes a four digit number as a value (e.g. "2023", "2024", etc).'), limit=commands.parameter(default=5, description='This parameter dictates how many pokemon will be returned in the usage list. Takes any integer as a value.'), format=commands.parameter(default=DEFAULT_FORMAT, description='This parameter dictates which format the pokemon usages are based on. Takes any format as a value (e.g. "gen9nationaldexag", "gen9customgame", "gen9doublescustomgame", etc).')):
try:
if username == 'all':
usage_text = service.get_all_pokemon_usage(usage_type, RankType.MONTH, datetime.datetime(year=int(year), month=int(month), day=1, tzinfo=datetime.timezone.utc), limit, format)
else:
usage_text = service.get_pokemon_usage(username.lower(), usage_type, RankType.MONTH, datetime.datetime(year=int(year), month=int(month), day=1, tzinfo=datetime.timezone.utc), limit, format)
embed = generate_embed(f'πβ {"All Time" if username == "all" else username} Pokemon Usage ({month}/{year}) βπ', usage_text, 0x1DB954)
embed.set_image(url=f'https://play.pokemonshowdown.com/sprites/ani/{usage_text.split("**")[1].split("**")[0].lower().replace(".", "").replace(" ", "")}.gif')
await ctx.channel.send(embed=embed)
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='rival', help='Use this command to get rival. Ensure that all parameters are entered in the correct order!')
async def rival(ctx, username=commands.parameter(default=None, description='This parameter dictates which user to show rivals for. Takes any showdown username as a value.'), rival_type=commands.parameter(default='most', description='This parameter dictates which teams from the set of replays that should be taken into account; all teams, winning teams, or losing teams. Takes either "most", "win", or "lose" as a value.'), rank_type=commands.parameter(default='month', description='This parameter dictates whether the returned rival is based on the current month or all time. Takes either "month" or "all" as a value.'), limit=commands.parameter(default=5, description='This parameter dictates how many rivals will be returned in the usage list. Takes any integer as a value.'), format=commands.parameter(default=DEFAULT_FORMAT, description='This parameter dictates which format the rivals are based on. Takes any format as a value (e.g. "gen9nationaldexag", "gen9customgame", "gen9doublescustomgame", etc).')):
try:
if rank_type == 'all':
rival_text = service.get_rival(username.lower(), rival_type, RankType.ALL_TIME, None, limit, format)
else:
rival_text = service.get_rival(username.lower(), rival_type, RankType.MONTH, datetime.datetime.now(datetime.UTC), limit, format)
await ctx.channel.send(embed=generate_embed(f'π {username} Rival π', rival_text, 0xA020F0))
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='num_matches', help='Use this command to get the number of matches between dates. Ensure that all parameters are entered in the correct order!')
async def num_matches(ctx, date_1=commands.parameter(default=None, description='This parameter dictates the start date to begin counting matches. Takes a date as a value (e.g. "02/06/24"). Defaults to start of current day.'), date_2=commands.parameter(default=None, description='This parameter dictates the end date to stop counting matches. Takes a date as a value (e.g. "02/06/24"). Defaults to end of current day.')):
try:
if date_1 is None:
start_1 = datetime.datetime.now(datetime.UTC)
else:
start_1 = datetime.datetime.strptime(date_1, '%d/%m/%y')
date_1 = datetime.datetime(year=start_1.year, month=start_1.month, day=start_1.day, tzinfo=datetime.timezone.utc)
if date_2 is None:
start_2 = datetime.datetime.now(datetime.UTC)
else:
start_2 = datetime.datetime.strptime(date_2, '%d/%m/%y')
date_2 = datetime.datetime(year=start_2.year, month=start_2.month, day=start_2.day, hour=23, minute=59, second=59, tzinfo=datetime.timezone.utc)
num_text = service.get_num_matches_between(date_1, date_2)
await ctx.channel.send(embed=generate_embed(f':hash: Number of Matches ({date_1.date()} - {date_2.date()}) :hash:', f'{num_text} matches played', 0xADD8E6))
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='p2p_history', help='Use this command to get the number of matches between dates. Ensure that all parameters are entered in the correct order!')
async def p2p_history(ctx, username_1=commands.parameter(default=None, description='This parameter dictates which user should be selected. Takes any showdown username as a value.'), username_2=commands.parameter(default=None, description='This parameter dictates which other user should be selected. Takes any showdown username as a value.'), date=commands.parameter(default=None, description='This parameter dictates the start date to begin looking at matches. Takes a date as a value (e.g. "02/06/24"). Defaults to start of current day.')):
try:
if date is None:
start = datetime.datetime.now(datetime.UTC)
else:
start = datetime.datetime.strptime(date, '%d/%m/%y')
date = datetime.datetime(year=start.year, month=start.month, day=start.day, tzinfo=datetime.timezone.utc)
history_text = service.get_p2p_history(username_1.lower(), username_2.lower(), date)
await ctx.channel.send(embed=generate_embed(f':dart: Player-To-Player History ({username_1} vs. {username_2} - {date.date()}) :dart:', history_text, 0xADD8E6))
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='toggle_ladder', help='Use this command to toggle ladder. Ensure that all parameters are entered in the correct order!')
async def toggle_ladder(ctx):
try:
if ctx.author.name == DEV_USER:
service.ladder_enabled = not service.ladder_enabled
await ctx.channel.send(f'Clod\'s Ladder is now {"enabled" if service.ladder_enabled else "disabled"}.')
else:
await ctx.channel.send(embed=DEV_ONLY_WARNING_EMBED)
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='update_pokemon_usage', help='Use this command to update the pokemon usage. Ensure that all parameters are entered in the correct order!')
async def update_pokemon_usage(ctx):
try:
if ctx.author.name == DEV_USER:
await update_usage_stats()
else:
await ctx.channel.send(embed=DEV_ONLY_WARNING_EMBED)
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='update_ladder', help='Use this command to update the ladder. Ensure that all parameters are entered in the correct order!')
async def update_ladder(ctx):
try:
if ctx.author.name == DEV_USER:
await update_ladder_stats()
else:
await ctx.channel.send(embed=DEV_ONLY_WARNING_EMBED)
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='override_rank', help='Use this command to override rank. Ensure that all parameters are entered in the correct order!')
async def override_rank(ctx, username=commands.parameter(default=None, description='This parameter dictates which user to show the rank for. Takes any showdown username as a value.'), rank_type=commands.parameter(default='month', description='This parameter dictates whether the returned rankings are based on the current month or all time. Takes either "month" or "all" as a value.'), format=commands.parameter(default=DEFAULT_FORMAT, description='This parameter dictates which format the rankings are based on. Takes any format as a value (e.g. "gen9nationaldexag", "gen9customgame", "gen9doublescustomgame", etc).'), value=commands.parameter(default=1000, description='This parameter dictates which value to override the rank with. Takes any value.')):
try:
if ctx.author.name == DEV_USER:
if rank_type == 'all':
service.override_rank(username.lower(), RankType.ALL_TIME, format, None, value)
else:
service.override_rank(username.lower(), RankType.MONTH, format, datetime.datetime.now(datetime.UTC), value)
await ctx.channel.send(embed=generate_embed(f'πͺ¬ Rank Override πͺ¬', f'{username}\'s rank changed to {value}', 0x0096FF))
else:
await ctx.channel.send(embed=DEV_ONLY_WARNING_EMBED)
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='remove_replay', help='Use this command to remove a replay. Ensure that all parameters are entered in the correct order!')
async def remove_replay(ctx, replay_id=commands.parameter(default=None, description='This parameter dictates which replay to remove. Takes any showdown replay id.')):
try:
if ctx.author.name == DEV_USER:
service.remove_match(replay_id)
await ctx.channel.send(embed=generate_embed(f'πͺ¬ Replay Removed πͺ¬', f'{replay_id} removed from database', 0x0096FF))
else:
await ctx.channel.send(embed=DEV_ONLY_WARNING_EMBED)
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='scan_all_replays', help='Use this command to scan all replays. Ensure that all parameters are entered in the correct order!')
async def scan_all_replays(ctx, day=None, month=None, year=None):
try:
if ctx.author.name == DEV_USER:
if not month or not year:
await scan_replays()
else:
await scan_replays(10, datetime.datetime(year=int(year), month=int(month), day=(1 if day is None else int(day))))
else:
await ctx.channel.send(embed=DEV_ONLY_WARNING_EMBED)
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='scan_thread', help='Use this command to scan a specific thread. Ensure that all parameters are entered in the correct order!')
async def scan_thread(ctx, thread, channel=MATCH_CHANNEL):
try:
if ctx.author.name == DEV_USER:
guild = discord.utils.get(bot.guilds, name=GUILD_NAME)
match_channel = discord.utils.get(guild.text_channels, name=channel)
match_thread = discord.utils.get(match_channel.threads, name=thread)
messages = [message async for message in match_thread.history(limit=None, oldest_first=True)]
scan_messages(messages, 10)
else:
await ctx.channel.send(embed=DEV_ONLY_WARNING_EMBED)
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='ping', help='Use this command to ping a specific role. Ensure that all parameters are entered in the correct order!')
async def ping(ctx, role, message):
try:
if role.lower() != 'here' and role.lower() != 'everyone':
discord_role = discord.utils.get(ctx.guild.roles, name=role)
await ctx.channel.send(f'{discord_role.mention} {message}')
else:
await ctx.channel.send(embed=BAD_ROLE_WARNING_EMBED)
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='glad', help='Use this command to ping a the 35 Gladiator role. Ensure that all parameters are entered in the correct order!')
async def ping_gladiator(ctx, message=None):
try:
discord_role = discord.utils.get(ctx.guild.roles, name='35 Gladiator')
await ctx.channel.send(f'{discord_role.mention}{" " + message if message else ""}')
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='spec', help='Use this command to ping a the 35 Spectator role. Ensure that all parameters are entered in the correct order!')
async def ping_spectator(ctx, message=None):
try:
discord_role = discord.utils.get(ctx.guild.roles, name='35 Spectator')
await ctx.channel.send(f'{discord_role.mention}{" " + message if message else ""}')
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='doub', help='Use this command to ping a the 35 Double role. Ensure that all parameters are entered in the correct order!')
async def ping_double(ctx, message=None):
try:
discord_role = discord.utils.get(ctx.guild.roles, name='35 Double')
await ctx.channel.send(f'{discord_role.mention}{" " + message if message else ""}')
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
@bot.command(name='baby', help='Use this command to ping a the 35 Baby role. Ensure that all parameters are entered in the correct order!')
async def ping_baby(ctx, message=None):
try:
discord_role = discord.utils.get(ctx.guild.roles, name='35 Baby')
await ctx.channel.send(f'{discord_role.mention}{" " + message if message else ""}')
except Exception as e:
print(e)
await ctx.channel.send(embed=BOT_WARNING_EMBED)
return
def get_links(message):
links = []
tokens = message.split(MATCH_PREFIX)[1:]
for token in tokens:
links.append(MATCH_PREFIX + token.split('\n')[0].split(' ')[0].split('>')[0].split('?')[0].strip())
return links
def generate_embed(title, content, color):
embed = discord.Embed(title=title, description=content, color=color)
return embed
def get_channel_by_name(channel):
guild = discord.utils.get(bot.guilds, name=GUILD_NAME)
return guild, next((x for x in guild.text_channels if x.name == channel), None)
async def update_usage_stats():
guild, usage_channel = get_channel_by_name(POKEMON_USAGE_CHANNEL)
messages = [message async for message in usage_channel.history(limit=1, oldest_first=False)]
usage_text = service.get_all_pokemon_usage('most', RankType.MONTH, datetime.datetime.now(datetime.UTC), 20, DEFAULT_FORMAT)
embed = generate_embed(f'π Monthly Pokemon Usage π', usage_text, 0x1DB954)
embed.set_image(url=f'https://play.pokemonshowdown.com/sprites/ani/{usage_text.split("**")[1].split("**")[0].lower().replace(".", "").replace(" ", "")}.gif')
try:
await messages[0].edit(embed=embed)
except:
await usage_channel.send(embed=embed)
async def update_ladder_stats():
guild, usage_channel = get_channel_by_name(LADDER_CHANNEL)
messages = [message async for message in usage_channel.history(limit=1, oldest_first=False)]
rank_text = service.generate_rank_text(RankType.MONTH, datetime.datetime.now(datetime.UTC), False, 20, DEFAULT_FORMAT)
if len(rank_text.split('\n')) < 20:
rank_text = service.generate_rank_text(RankType.MONTH, datetime.datetime.now(datetime.UTC), True, 20, DEFAULT_FORMAT)
embed = generate_embed('π Monthly Rankings π', rank_text, 0x8B0000)
try:
await messages[0].edit(embed=embed)
except:
await usage_channel.send(embed=embed)
async def scan_replays(print_interval=100, date=None):
guild, match_channel = get_channel_by_name(MATCH_CHANNEL)
print(f'.....Scanning for replays{" after " + date.strftime("%m/%d/%Y") if date else ""}.....')
if date:
messages = [message async for message in match_channel.history(limit=None, after=date, oldest_first=True)]
else:
messages = [message async for message in match_channel.history(limit=None, oldest_first=True)]
scan_messages(messages, print_interval)
def scan_messages(messages, print_interval):
count = len(messages)
print(f'.....Scanning {count} messages.....')
processed_matches = 0
already_processed_matches = 0
for idx, message in enumerate(messages):
if idx % print_interval == 0:
print(f'.....{idx} / {count} messages scanned.....')
if MATCH_PREFIX in message.content:
links = get_links(message.content)
for link in links:
response = service.process_match(link)
if response:
processed_matches += 1
print(f'**New** match processed ({processed_matches}): {link}')
else:
already_processed_matches += 1
print(f'Match already processed ({already_processed_matches}): {link}')
print(f'.....Bot has finished scanning ({processed_matches} new matches, {already_processed_matches} already processed).....')
BOT_WARNING_EMBED = generate_embed(f'β Bot Warning β ', 'Something went wrong', 0x3B3B3B)
DEV_ONLY_WARNING_EMBED = generate_embed(f'β Bot Warning β ', 'Sorry, this command is for developers only', 0x3B3B3B)
BAD_ROLE_WARNING_EMBED = generate_embed(f'β Bot Warning β ', 'Sorry, this role is not allowed', 0x3B3B3B)