Added random_gif() Moved back from exception-handler cog to local error handling Updated !keepers to be season agnostic Added new !sync param to update and clear local guild Added error checking to !player command
2709 lines
118 KiB
Python
2709 lines
118 KiB
Python
import copy
|
|
import math
|
|
|
|
import discord
|
|
import pydantic
|
|
import re
|
|
|
|
from discord import app_commands
|
|
from discord.ext import tasks
|
|
from discord.app_commands import Choice
|
|
|
|
from helpers import *
|
|
from db_calls import db_get, db_patch, get_team_by_abbrev, get_team_by_owner, put_player, get_player_by_name, db_post, \
|
|
db_delete
|
|
from typing import Literal, Optional
|
|
|
|
logger = logging.getLogger('discord_app')
|
|
|
|
class BatStat(pydantic.BaseModel):
|
|
player_id: int
|
|
team_id: int
|
|
pos: str
|
|
pa: int = 0
|
|
ab: int = 0
|
|
run: int = 0
|
|
hit: int = 0
|
|
rbi: int = 0
|
|
double: int = 0
|
|
triple: int = 0
|
|
hr: int = 0
|
|
bb: int = 0
|
|
so: int = 0
|
|
hbp: int = 0
|
|
sac: int = 0
|
|
ibb: int = 0
|
|
gidp: int = 0
|
|
sb: int = 0
|
|
cs: int = 0
|
|
bphr: int = 0
|
|
bpfo: int = 0
|
|
bp1b: int = 0
|
|
bplo: int = 0
|
|
xba: int = 0
|
|
xbt: int = 0
|
|
xch: int = 0
|
|
xhit: int = 0
|
|
error: int = 0
|
|
pb: int = 0
|
|
sbc: int = 0
|
|
csc: int = 0
|
|
roba: int = 0
|
|
robs: int = 0
|
|
raa: int = 0
|
|
rto: int = 0
|
|
week: int
|
|
game: int
|
|
season: int
|
|
|
|
|
|
class PitStat(pydantic.BaseModel):
|
|
player_id: int
|
|
team_id: int
|
|
ip: float = 0.0
|
|
hit: int = 0
|
|
run: int = 0
|
|
erun: int = 0
|
|
so: int = 0
|
|
bb: int = 0
|
|
hbp: int = 0
|
|
wp: int = 0
|
|
balk: int = 0
|
|
hr: int = 0
|
|
gs: int = 0
|
|
win: int = 0
|
|
loss: int = 0
|
|
hold: int = 0
|
|
sv: int = 0
|
|
bsv: int = 0
|
|
ir: int = 0
|
|
irs: int = 0
|
|
week: int
|
|
game: int
|
|
season: int
|
|
|
|
|
|
class Players(commands.Cog):
|
|
def __init__(self, bot):
|
|
self.bot = bot
|
|
self.player_list = {}
|
|
self.scorecards = {}
|
|
self.voice_channels = []
|
|
|
|
self.build_master_player_list.start()
|
|
self.live_scorecard_loop.start()
|
|
|
|
async def cog_command_error(self, ctx, error):
|
|
logger.error(msg=error, stack_info=True, exc_info=True)
|
|
await ctx.send(f'{error}\n\nRun !help <command_name> to see the command requirements')
|
|
|
|
async def slash_error(self, ctx, error):
|
|
logger.error(msg=error, stack_info=True, exc_info=True)
|
|
await ctx.send(f'{error[:1600]}')
|
|
|
|
# async def cog_command_error(self, ctx, error):
|
|
# await ctx.send(f'{error}\n\nRun !help <command_name> to see the command requirements')
|
|
|
|
# async def slash_error(self, ctx, error):
|
|
# await ctx.send(f'{error}')
|
|
|
|
# @commands.Cog.listener()
|
|
# async def on_app_command_error(self, interaction, error):
|
|
# command = interaction.app_command
|
|
# ctx = interaction.context
|
|
#
|
|
# await ctx.send(f"An error occurred while executing the {command} command: {error}")
|
|
|
|
async def get_dice_embed(self, channel, title, message):
|
|
team = None
|
|
try:
|
|
current = await db_get('current')
|
|
team_abbrev = re.split('-', channel.name)
|
|
if len(team_abbrev[0]) <= 4 and team_abbrev not in ['the', 'city']:
|
|
tquery = await db_get('teams', params=[('season', current['season']), ('team_abbrev', team_abbrev[0])])
|
|
if tquery['count'] > 0:
|
|
team = tquery['teams'][0]
|
|
except (ValueError, AttributeError, requests.ReadTimeout) as e:
|
|
logger.info(f'{type(e)}: {e}')
|
|
|
|
if team is not None:
|
|
embed = discord.Embed(
|
|
color=int(team["dice_color"], 16) if team["dice_color"] else int(team["color"], 16)
|
|
)
|
|
else:
|
|
embed = discord.Embed(
|
|
color=int('0x000000', 16)
|
|
)
|
|
|
|
if title and message:
|
|
embed.add_field(name=title, value=message)
|
|
|
|
return embed
|
|
|
|
async def game_scorebug(self, sheets_data, include_images: bool = True, full_length: bool = True):
|
|
away_team = await db_get('teams', object_id=sheets_data.get_value('B5'))
|
|
home_team = await db_get('teams', object_id=sheets_data.get_value('B6'))
|
|
logger.info(f'getting gamestate / full_length: {full_length}')
|
|
all_data = sheets_data.get_values('B2', 'S20', include_tailing_empty_rows=True)
|
|
# game_state = sheets_data.get_values('B2', 'G8', include_tailing_empty_rows=True)
|
|
game_state = [
|
|
all_data[0][:6], all_data[1][:6], all_data[2][:6], all_data[3][:6],
|
|
all_data[4][:6], all_data[5][:6], all_data[6][:6]
|
|
]
|
|
logger.info(f'gamestate: {game_state}')
|
|
header = game_state[0][0]
|
|
is_final = header[-5:] == 'FINAL'
|
|
# inning_desc = {header.split(" - ")[1]}
|
|
away_score = game_state[3][2]
|
|
home_score = game_state[4][2]
|
|
which_half = game_state[3][4]
|
|
logger.info(f'getting runners')
|
|
|
|
# runners = sheets_data.get_values('K11', 'L14', include_tailing_empty_rows=True)
|
|
runners = [
|
|
all_data[9][9:11], all_data[10][9:11], all_data[11][9:11], all_data[12][9:11]
|
|
]
|
|
logger.info(f'runners: {runners}')
|
|
logger.info(f'getting matchups')
|
|
|
|
this_embed = get_team_embed(
|
|
# title=f'[{away_team["sname"]}]({get_team_url(away_team)}) @ '
|
|
# f'[{home_team["sname"]}]({get_team_url(home_team)}) - {header.split(" - ")[1]}',
|
|
title=header,
|
|
team=away_team if away_score > home_score else home_team,
|
|
thumbnail=False
|
|
)
|
|
|
|
def get_ascii_scorebug():
|
|
occupied = '●'
|
|
unoccupied = '○'
|
|
|
|
first_base = unoccupied if runners[1][0] == '' else occupied
|
|
second_base = unoccupied if runners[2][0] == '' else occupied
|
|
third_base = unoccupied if runners[3][0] == '' else occupied
|
|
half = '▲' if which_half == 'Top' else '▼'
|
|
|
|
if not is_final:
|
|
so = sheets_data.get_value('F6')
|
|
inning = f'{half} {game_state[3][5]}'
|
|
outs = f'{so} Out{"s" if so != "1" else ""}'
|
|
else:
|
|
inning = f'F/{game_state[3][5] if which_half == "Bot" else int(game_state[3][5]) - 1}'
|
|
outs = ''
|
|
|
|
return f'```\n' \
|
|
f'{away_team["abbrev"]: ^4}{away_score: ^3} {second_base}' \
|
|
f'{inning: >10}\n' \
|
|
f'{home_team["abbrev"]: ^4}{home_score: ^3} {third_base} ' \
|
|
f'{first_base}{outs: >8}\n```'
|
|
|
|
this_embed.add_field(
|
|
name='Game State',
|
|
value=get_ascii_scorebug(),
|
|
inline=False
|
|
)
|
|
|
|
logger.info(f'Checking if not full_length')
|
|
if not full_length:
|
|
logger.info(f'not full_length, returning now')
|
|
return this_embed
|
|
|
|
# matchups = sheets_data.get_values('K3', 'O6', include_tailing_empty_rows=True)
|
|
matchups = [
|
|
all_data[1][9:14], all_data[2][9:14], all_data[3][9:14], all_data[4][9:14],
|
|
]
|
|
logger.info(f'matchups: {matchups}')
|
|
|
|
p_name = matchups[0][0]
|
|
this_embed.add_field(
|
|
name='Pitcher',
|
|
value=f'[{p_name}]({get_player_url({"season": away_team["season"], "name": p_name})})\n'
|
|
f'{matchups[0][2]}'
|
|
)
|
|
b_name = matchups[1][0]
|
|
this_embed.add_field(
|
|
name='Batter',
|
|
value=f'{matchups[1][3]}. '
|
|
f'[{b_name}]({get_player_url({"season": away_team["season"], "name": b_name})})'
|
|
f' - {matchups[1][4]}\n'
|
|
f'{matchups[1][2]}'
|
|
)
|
|
if include_images:
|
|
this_embed.set_thumbnail(url=matchups[0][1])
|
|
this_embed.set_image(url=matchups[1][1])
|
|
|
|
on_first = runners[1][0]
|
|
on_second = runners[2][0]
|
|
on_third = runners[3][0]
|
|
|
|
if len(on_first) + len(on_second) + len(on_third) > 0:
|
|
br_string = f''
|
|
if len(on_first) > 0:
|
|
br_string += f'On First: [{runners[1][0]}]({get_player_url({"season": away_team["season"], "name": runners[1][0]})})\n'
|
|
if len(on_second) > 0:
|
|
br_string += f'On Second: [{runners[2][0]}]({get_player_url({"season": away_team["season"], "name": runners[2][0]})})\n'
|
|
if len(on_third) > 0:
|
|
br_string += f'On Third: [{runners[3][0]}]({get_player_url({"season": away_team["season"], "name": runners[3][0]})})\n'
|
|
|
|
this_embed.add_field(name=' ', value=' ', inline=False)
|
|
this_embed.add_field(
|
|
name='Baserunners',
|
|
value=br_string
|
|
)
|
|
this_embed.add_field(
|
|
name='Catcher',
|
|
value=f'[{runners[0][0]}]({get_player_url({"season": away_team["season"], "name": runners[0][0]})})'
|
|
)
|
|
|
|
if not is_final:
|
|
inning_sum = sheets_data.get_values('R3', 'S20')
|
|
i_string = ''
|
|
for line in inning_sum:
|
|
i_string += f'- Play {line[0]}: {line[1]}\n'
|
|
this_embed.add_field(
|
|
name='Inning Summary',
|
|
value=i_string,
|
|
inline=False
|
|
)
|
|
|
|
return this_embed
|
|
|
|
@tasks.loop(count=1)
|
|
async def build_master_player_list(self):
|
|
# logger.info(f'build_master_player_list - getting current')
|
|
current = await db_get('current')
|
|
# logger.info(f'build_master_player_list - getting all_players')
|
|
p_query = await db_get('players', timeout=8, params=[('season', current['season'])])
|
|
# logger.info(f'build_master_player_list - building player_list')
|
|
self.player_list = {x['name'].lower(): x['id'] for x in p_query['players']}
|
|
logger.info(f'player list count: {len(self.player_list)}')
|
|
logger.debug(f'player list: {self.player_list}')
|
|
|
|
@build_master_player_list.before_loop
|
|
async def before_build_master_player_list(self):
|
|
await self.bot.wait_until_ready()
|
|
|
|
@tasks.loop(minutes=3)
|
|
async def live_scorecard_loop(self):
|
|
guild = self.bot.get_guild(int(os.environ.get('GUILD_ID')))
|
|
|
|
score_channel = discord.utils.get(guild.text_channels, name='live-sba-scores')
|
|
player_role = get_role(score_channel, SBA_PLAYERS_ROLE_NAME, bot=self.bot)
|
|
|
|
try:
|
|
if len(self.voice_channels) > 0:
|
|
all_embeds = []
|
|
for x in self.scorecards.values():
|
|
logger.info(f'looping through scorecards')
|
|
await asyncio.sleep(1)
|
|
logger.info(f'creating embeds')
|
|
all_embeds.append(await self.game_scorebug(x, include_images=False))
|
|
|
|
logger.info(f'embeds: {all_embeds}')
|
|
if len(all_embeds) > 0:
|
|
# Clear old messages
|
|
async for message in score_channel.history(limit=25):
|
|
await message.delete()
|
|
|
|
await score_channel.set_permissions(player_role, read_messages=True)
|
|
await score_channel.send(content=None, embeds=all_embeds)
|
|
return
|
|
|
|
# game_strings = []
|
|
# for x in self.scorecards.values():
|
|
# await asyncio.sleep(1)
|
|
# this_string = x.get_value('A1')
|
|
# if ' F' not in this_string:
|
|
# game_strings.append(this_string)
|
|
#
|
|
# if len(game_strings) > 0:
|
|
# # Clear old messages
|
|
# async for message in score_channel.history(limit=25):
|
|
# await message.delete()
|
|
#
|
|
# embed = get_team_embed('SBa Scoreboard')
|
|
# embed.add_field(name='Live Games', value="\n\n".join(game_strings))
|
|
# embed.set_footer(
|
|
# text=f'SBa Season {SBA_SEASON}',
|
|
# icon_url=LOGO
|
|
# )
|
|
# await score_channel.set_permissions(player_role, read_messages=True)
|
|
# await score_channel.send(content=None, embed=embed)
|
|
# return
|
|
|
|
self.scorecards = {}
|
|
await score_channel.set_permissions(player_role, read_messages=False)
|
|
|
|
except Exception as e:
|
|
await send_to_channel(self.bot, 'commissioners-office', f'Could not update live scorecard:\n\n{e}')
|
|
logger.error(f'Could not update live scorecard: {e}')
|
|
|
|
@live_scorecard_loop.before_loop
|
|
async def before_live_scorecard_loop(self):
|
|
await self.bot.wait_until_ready()
|
|
|
|
@staticmethod
|
|
async def update_injuries(ctx):
|
|
current = await db_get('current')
|
|
injury_log = discord.utils.get(ctx.guild.text_channels, name='injury-log')
|
|
|
|
# Build new messages
|
|
# inj_by_team = {'Black Bears': [Player Objs], 'Questants': [Player Objs]}
|
|
# inj_by_week = {'Week 1': [Player Objs], 'Week 2': [Player Objs]}
|
|
inj_team = {}
|
|
inj_week = {}
|
|
i_query = await db_get('injuries', params=[
|
|
('season', current['season']), ('is_active', True), ('sort', 'return-asc')
|
|
])
|
|
|
|
for x in i_query['injuries']:
|
|
player = x['player']
|
|
this_team = await get_major_team(player['team'])
|
|
|
|
if this_team['sname'] not in inj_team.keys():
|
|
inj_team[this_team['sname']] = [player]
|
|
else:
|
|
inj_team[this_team['sname']].append(player)
|
|
|
|
if f'Week {x["end_week"]}' not in inj_week.keys():
|
|
inj_week[f'Week {x["end_week"]}'] = [player]
|
|
else:
|
|
inj_week[f'Week {x["end_week"]}'].append(player)
|
|
|
|
team_embed = discord.Embed(title='Current Injuries by Team')
|
|
team_embed.description = 'Player Name (Return Date)'
|
|
team_embed.set_thumbnail(url=LOGO)
|
|
# for team in inj_by_team:
|
|
for team in inj_team:
|
|
team_string = ''
|
|
for player in inj_team[team]:
|
|
team_string += f'{player["name"]} ({player["il_return"]})\n'
|
|
team_embed.add_field(name=team, value=team_string)
|
|
|
|
week_embed = discord.Embed(title='Current Injuries by Return Week')
|
|
week_embed.description = 'Player Name (Return Date)'
|
|
week_embed.set_thumbnail(url=LOGO)
|
|
# for week in inj_by_week:
|
|
for week in inj_week:
|
|
week_string = ''
|
|
for player in inj_week[week]:
|
|
week_string += f'{player["name"]} ({player["il_return"]})\n'
|
|
week_embed.add_field(name=week, value=week_string)
|
|
|
|
# Clear old messages
|
|
async for message in injury_log.history(limit=25):
|
|
await message.delete()
|
|
|
|
# Send new messages
|
|
await injury_log.send(content=None, embed=team_embed)
|
|
await injury_log.send(content=None, embed=week_embed)
|
|
|
|
@staticmethod
|
|
def team_stan_line(stan, s_type: str = 'div'):
|
|
if stan["wins"] + stan["losses"] == 0:
|
|
winpct = f'{0:.3f}'
|
|
else:
|
|
winpct = f'{stan["wins"] / (stan["wins"] + stan["losses"]):.3f}'
|
|
team_string = f'{stan["team"]["abbrev"]: <4} {stan["wins"]: >2}-{stan["losses"]: <2} {winpct} '
|
|
|
|
if s_type == 'div':
|
|
if stan["div_gb"] is None:
|
|
gb = '--'
|
|
else:
|
|
gb = stan["div_gb"]
|
|
team_string += f'{gb: >5}'
|
|
|
|
if stan["div_e_num"] is None:
|
|
team_string += f' -- '
|
|
else:
|
|
e_num = stan["div_e_num"] if stan["div_e_num"] > 0 else 'E'
|
|
team_string += f' {e_num: >2} '
|
|
else:
|
|
if stan["wc_gb"] is None:
|
|
# This is a division leader - return nothing and continue
|
|
return ''
|
|
else:
|
|
gb = stan["wc_gb"] if stan["wc_gb"] >= 0.0 else f'--'
|
|
if stan["wc_e_num"]:
|
|
e_num = stan["wc_e_num"]
|
|
elif stan["wc_e_num"] == 0:
|
|
e_num = 'E'
|
|
else:
|
|
e_num = '--'
|
|
team_string += f'{gb: >4} {e_num: >2} '
|
|
|
|
team_string += f'{stan["run_diff"]: >4}\n'
|
|
|
|
return team_string
|
|
|
|
@staticmethod
|
|
async def game_progress(current):
|
|
# s_query = await db_get('schedules', params=[
|
|
# ('season', current['season']), ('week_start', current['week']), ('week_end', current['week'])
|
|
# ])
|
|
# r_query = await db_get('results', params=[
|
|
# ('season', current['season']), ('week_start', current['week']), ('week_end', current['week'])
|
|
# ])
|
|
gp_query = await db_get('games', params=[
|
|
('season', current['season']), ('week', current['week']), ('played', True), ('short_output', True)
|
|
])
|
|
all_query = await db_get('games', params=[
|
|
('season', current['season']), ('week', current['week']), ('short_output', True)
|
|
])
|
|
|
|
return {'games_played': gp_query['count'], 'game_count': all_query['count']}
|
|
|
|
@commands.Cog.listener(name='on_message')
|
|
async def on_message_listener(self, message):
|
|
# if 'bad man' in message.content:
|
|
# await message.channel.send(
|
|
# 'https://cdn.discordapp.com/attachments/619600872782954539/682411826335711268/image0.jpg'
|
|
# )
|
|
if message.author.bot or isinstance(message.channel, discord.DMChannel):
|
|
return
|
|
|
|
tm = message.content.lower()
|
|
|
|
if tm in ['shut up, jack', 'shut up jack']:
|
|
await message.channel.send('Shut up, Jack')
|
|
return
|
|
# elif message.content[-3:] == '...':
|
|
# await message.channel.send('https://media.tenor.com/images/423f15eef7688d3010c4d83a16902574/tenor.gif')
|
|
# return
|
|
elif 'DELIBERAT' in message.content:
|
|
await message.channel.send('https://tenor.com/view/fbi-swat-jelleton-gif-14190942')
|
|
elif 'domo sux' in tm or 'domo sucks' in tm or 'fuck domo' in tm or 'fuck you domo' in tm:
|
|
await message.add_reaction('🖕')
|
|
elif 'joe momma' in tm or 'joe mama' in tm:
|
|
await message.channel.send('https://tenor.com/view/shaq-big-dunk-basketball-chris-dudley-shaquille-'
|
|
'o-neal-gif-13864249')
|
|
elif 'i\'m dad' in tm or 'im dad' in tm:
|
|
await message.channel.send(
|
|
'https://tenor.com/view/dad-jokes-aht-aht-dad-jokes-aht-aht-ha-ha-ha-knee-slapper-gif-26152690'
|
|
)
|
|
elif '||' in tm:
|
|
split_text = tm.split('||')
|
|
spoiler_text = split_text[1]
|
|
if len(split_text) > 3 and 'z' not in spoiler_text:
|
|
chance = 'Low'
|
|
elif 8 <= len(spoiler_text) <= 10:
|
|
chance = 'High'
|
|
elif 'z' in spoiler_text:
|
|
chance = 'Medium'
|
|
else:
|
|
d1000 = random.randint(1, 1000)
|
|
if d1000 <= 300:
|
|
chance = 'Low'
|
|
elif d1000 <= 600:
|
|
chance = 'Medium'
|
|
elif d1000 <= 900:
|
|
chance = 'High'
|
|
elif d1000 <= 950:
|
|
chance = 'Miniscule'
|
|
elif d1000 <= 980:
|
|
chance = 'Throbbing'
|
|
else:
|
|
chance = 'Deez Nuts'
|
|
|
|
ping_role = get_role(message, 'Deez Watch', self.bot)
|
|
await message.channel.send(f'{ping_role.mention} there is a **{chance}** chance this is a deez nuts joke.')
|
|
|
|
# elif 'fifa' in tm or 'soccer' in tm or 'world cup' in tm or 'the wc' in tm or 'this wc' in tm or 'futbol' in tm:
|
|
# randint = random.randint(1, 5)
|
|
# if randint == 5:
|
|
# await message.channel.send(f'||{message.content}\n{message.author.name}, apparently||\n\n'
|
|
# f'Ugh, I can\'t with this soccer talk.')
|
|
# await message.delete()
|
|
# else:
|
|
# await message.channel.send(random_soccer())
|
|
|
|
if message.channel.name in ['trade-block', 'jacks-trading-post']:
|
|
count = 0
|
|
async for x in message.channel.history():
|
|
if x.author.id == message.author.id and x.id != message.id:
|
|
count += 1
|
|
await x.delete()
|
|
if count > 1:
|
|
await message.author.send(f'I have deleted your previous {count} trade-block messages to '
|
|
f'keep it clean.')
|
|
elif count == 1:
|
|
await message.author.send('I deleted your last trade-block message to help keep it clean.')
|
|
|
|
# if len(message.content) == 1 and not message.content.isnumeric() and message.content.lower() != 'k':
|
|
# logger.info(
|
|
# f'Found spam from **{message.author.nick}** in **{message.channel.name}**: {message.content}'
|
|
# )
|
|
# if 'shitpost' not in message.channel.name and 'sbb' not in message.channel.name:
|
|
# await send_to_channel(
|
|
# self.bot,
|
|
# 'commissioners-office',
|
|
# f'Just deleted this message from **{message.author.nick}** in **{message.channel.name}**:'
|
|
# f'\n\n{message.content}'
|
|
# )
|
|
# await message.delete()
|
|
# await message.author.send(
|
|
# f'Hi there. I just deleted your \'{message.content}\' message from #{message.channel.name}. I am '
|
|
# f'told to delete 1-character messages due to spam.'
|
|
# )
|
|
|
|
# @staticmethod
|
|
# def get_standings_embed(current, progress, al_standings, nl_standings):
|
|
# embed = discord.Embed(title=f'Season {current["season"]} | Week {current["week"]} | '
|
|
# f'{progress["games_played"]}/{progress["game_count"]} games played',
|
|
# color=0xB70000)
|
|
# embed.add_field(name=f'**Full Standings**', value=SBA_STANDINGS_URL, inline=False)
|
|
# embed.add_field(name=f'**American League**', value=al_standings, inline=False)
|
|
# embed.add_field(name=f'**National League**', value=nl_standings, inline=False)
|
|
#
|
|
# return embed
|
|
|
|
@commands.command(name='team', aliases=['roster', 'myboys', 'mybois'], help='Get team overview')
|
|
async def team_command(self, ctx, team_abbrev: str = None):
|
|
current = await db_get('current')
|
|
|
|
# Get Team
|
|
if team_abbrev is not None:
|
|
team = await get_team_by_abbrev(team_abbrev, current['season'])
|
|
else:
|
|
team = await get_team_by_owner(season=current['season'], owner_id=ctx.author.id)
|
|
|
|
# Create team embed
|
|
embed = get_team_embed(f'{team["lname"]} Overview', team)
|
|
|
|
# Get standings
|
|
if team['abbrev'][-2:].lower() != 'il':
|
|
try:
|
|
s_query = await db_get(f'standings/team/{team["id"]}')
|
|
if s_query is not None:
|
|
team_standings = s_query
|
|
overview_string = f'Record: {team_standings["wins"]}-{team_standings["losses"]} ' \
|
|
f'({team_standings["run_diff"]} RD)\n' \
|
|
f'Pythag Record: {team_standings["pythag_wins"]}-{team_standings["pythag_losses"]}\n'
|
|
division_string = ''
|
|
if team_standings['div_gb']:
|
|
division_string += f'{team_standings["div_gb"]} GB in ' \
|
|
f'{team_standings["team"]["division"]["league_abbrev"]} ' \
|
|
f'{team_standings["team"]["division"]["division_name"]} / ' \
|
|
f'{team_standings["wc_gb"]} GB in ' \
|
|
f'{team_standings["team"]["division"]["league_abbrev"]} WC\n'
|
|
else:
|
|
division_string += f'1st in {team_standings["team"]["division"]["league_abbrev"]} ' \
|
|
f'{team_standings["team"]["division"]["division_name"]}\n'
|
|
|
|
overview_string += division_string
|
|
overview_string += f'Last 8: ({team_standings["last8_wins"]}-{team_standings["last8_losses"]}) / ' \
|
|
f'Streak: {team_standings["streak_wl"].upper()}{team_standings["streak_num"]}'
|
|
|
|
embed.add_field(name=f'{team["sname"]} Overview', value=overview_string, inline=False)
|
|
except (ValueError, TypeError) as e:
|
|
logger.info(f'Could not pull standings for season {team["season"]} {team["abbrev"]}')
|
|
|
|
# Get player info
|
|
il_players = None
|
|
if team['abbrev'][-2:].lower() != 'il':
|
|
il_team = await get_team_by_abbrev(team['abbrev'], current['season'])
|
|
p_query = await db_get('players', params=[
|
|
('season', current['season']), ('team_id', il_team['id']), ('sort', 'cost-desc')
|
|
])
|
|
il_players = p_query['players']
|
|
|
|
p_query = await db_get('players', params=[
|
|
('season', current['season']), ('team_id', team['id']), ('sort', 'cost-desc')
|
|
])
|
|
players = p_query['players']
|
|
il_wara = 0
|
|
active_wara = 0
|
|
|
|
if il_players:
|
|
for x in il_players:
|
|
il_wara += x['wara']
|
|
|
|
if players:
|
|
count = 0
|
|
top_player_string = ''
|
|
|
|
for x in players:
|
|
if count < 5:
|
|
top_player_string += f'{x["pos_1"]} {x["name"]} ({x["wara"]:.2f})\n'
|
|
active_wara += x['wara']
|
|
count += 1
|
|
|
|
embed.add_field(name='Core Players', value=top_player_string)
|
|
embed.add_field(name='Total sWAR', value=f'{active_wara:.2f}')
|
|
if il_wara > 0:
|
|
embed.add_field(name='Injured sWAR', value=f'{il_wara:.2f}')
|
|
|
|
s_query = await db_get('schedules', params=[
|
|
('season', current['season']), ('team_abbrev', team['abbrev']), ('week_start', current['week']),
|
|
('week_end', current['week']+2 if current['week']+2 > 0 else 2), ('short_output', False)
|
|
])
|
|
if s_query['count'] > 0:
|
|
team_schedule = s_query['schedules']
|
|
this_week_string = ''
|
|
upcoming_string = ''
|
|
|
|
full_sched = sorted(team_schedule, key=lambda y: y['id'])
|
|
logger.info(f'full_sched: {full_sched}')
|
|
|
|
for matchup in full_sched:
|
|
st_abbrev = matchup['awayteam']['abbrev']
|
|
if matchup['hometeam'] == team:
|
|
st_abbrev = matchup['awayteam']['abbrev']
|
|
|
|
r_query = await db_get('standings', params=[('season', current['season']), ('team_abbrev', st_abbrev)])
|
|
opp_record = None if r_query['count'] == 0 else r_query['standings'][0]
|
|
|
|
if matchup['week'] == current['week']:
|
|
if matchup['hometeam'] == team:
|
|
this_week_string += f'Week {current["week"]}: vs ' \
|
|
f'{matchup["awayteam"]["lname"]} ' \
|
|
f'({opp_record["wins"]}-{opp_record["losses"]})\n'
|
|
else:
|
|
this_week_string += f'Week {current["week"]}: @ {matchup["hometeam"]["lname"]} ' \
|
|
f'({opp_record["wins"]}-{opp_record["losses"]})\n'
|
|
else:
|
|
if matchup['hometeam'] == team:
|
|
upcoming_string += f'Week {matchup["week"]}: vs ' \
|
|
f'{matchup["awayteam"]["lname"]} ' \
|
|
f'({opp_record["wins"]}-{opp_record["losses"]})\n'
|
|
else:
|
|
upcoming_string += f'Week {matchup["week"]}: @ ' \
|
|
f'{matchup["hometeam"]["lname"]} ' \
|
|
f'({opp_record["wins"]}-{opp_record["losses"]})\n'
|
|
|
|
if len(this_week_string) > 0:
|
|
embed.add_field(name='This Week', value=this_week_string, inline=False)
|
|
if len(upcoming_string) > 0:
|
|
embed.add_field(name='Upcoming Schedule', value=upcoming_string, inline=False)
|
|
|
|
# Add roster link
|
|
embed.add_field(
|
|
name=f'{team["abbrev"]} Roster Page',
|
|
value=f'https://sba.manticorum.com/teams/{current["season"]}/{team["abbrev"]}',
|
|
inline=False
|
|
)
|
|
|
|
await ctx.send(content=None, embed=embed)
|
|
|
|
@commands.command(name='player', aliases=['card'], help='Get player overview')
|
|
async def player_command(self, ctx, *, name):
|
|
current = await db_get('current')
|
|
season = current['season']
|
|
|
|
# if 'strider' in name.lower():
|
|
# await ctx.send(f'Ope. Strider has been reserved for Cal.')
|
|
|
|
name_reg = re.compile(r'(s\d+)* *(.*)', re.IGNORECASE)
|
|
player_search = name_reg.search(name)
|
|
logger.info(f'player_search: {player_search}')
|
|
logger.info(f'player_search.group(): {player_search.group()} / group(1): {player_search.group(1)} '
|
|
f'/ group(2): {player_search.group(2)}')
|
|
|
|
async with ctx.typing():
|
|
# No season is included
|
|
if not player_search.group(1):
|
|
try:
|
|
p_name = await fuzzy_player_search(ctx, ctx.channel, self.bot, name, self.player_list.keys())
|
|
except ValueError as e:
|
|
logger.error(e)
|
|
await ctx.send(f'{name} not found')
|
|
return
|
|
player = await db_get('players', object_id=self.player_list[p_name])
|
|
# Season is included
|
|
else:
|
|
season = int(player_search.group(1)[1:])
|
|
|
|
p_query = await db_get('players', params=[('season', season), ('name', player_search.group(2))])
|
|
if p_query['count'] == 0:
|
|
p_query = await db_get('players', params=[('season', season), ('short_output', True)])
|
|
if p_query['count'] == 0:
|
|
await ctx.send(f'I did not find any players in season {season}')
|
|
return
|
|
|
|
try:
|
|
p_name = await fuzzy_player_search(
|
|
ctx, ctx.channel, self.bot, player_search.group(2).strip(),
|
|
[x['name'].lower() for x in p_query['players']]
|
|
)
|
|
except ValueError as e:
|
|
logger.error(e)
|
|
await ctx.send(f'{name} not found')
|
|
return
|
|
p_query2 = await db_get('players', params=[('season', season), ('name', p_name)])
|
|
player = p_query2['players'][0]
|
|
|
|
embeds = [await get_player_embed(player, current, ctx, season)]
|
|
if player['image2']:
|
|
embed = get_team_embed(f'{player["name"]}', player["team"], thumbnail=False)
|
|
embed.set_image(url=player['image2'])
|
|
embeds.append(embed)
|
|
|
|
await ctx.send(content=None, embeds=embeds)
|
|
|
|
@commands.command(name='career', help='Get player\'s career stats')
|
|
async def career_command(self, ctx, *, name):
|
|
await ctx.send(f'That mother fucker Cal hasn\'t updated this command for the new API. Go check out Josef\'s '
|
|
f'[sba-reference.com](https://docs.google.com/spreadsheets/d/1_dqBFeLPjRk-6hlVE29AmlL1jnsFJq'
|
|
f'xutySveFn4LJc/edit?usp=sharing) sheet in the meantime.')
|
|
await ctx.send(random_gif('god dammit'))
|
|
return
|
|
|
|
# Get BattingCareer
|
|
b = await get_battingcareer(name)
|
|
# Get PitchingCareer
|
|
p = await get_pitchingcareer(name)
|
|
if not b and not p:
|
|
await ctx.send('Who? Please splel berter')
|
|
return
|
|
|
|
player = {
|
|
'name': b['name'] if b else p['name'],
|
|
}
|
|
|
|
# Build custom embed
|
|
embed = get_team_embed(f'{player["name"]} Career Stats')
|
|
embed.color = int('0xa6ce39', 16)
|
|
player_photo = await get_player_headshot(b['name'])
|
|
if player_photo:
|
|
embed.set_thumbnail(url=player_photo)
|
|
player_pages = f'[SBa]({get_player_url(player)}) / ' \
|
|
f'[BBRef]({get_player_url(player, "bbref")})'
|
|
embed.add_field(name='Player Page', value=player_pages)
|
|
|
|
batting_string = None
|
|
pitching_string = None
|
|
|
|
if b:
|
|
if b['ab'] > 0:
|
|
singles = b['hit'] - b['hr'] - b['triple'] - b['double']
|
|
avg = b['hit'] / b['ab']
|
|
obp = (b['hit'] + b['bb'] + b['ibb'] + b['hbp']) / b['pa']
|
|
slg = ((b['hr'] * 4) + (b['triple'] * 3) + (b['double'] * 2) + singles) / b['ab']
|
|
ops = obp + slg
|
|
woba = ((b['bb'] * .69) + (b['hbp'] * .72) + (singles * .89) + (b['double'] * 1.27) +
|
|
(b['triple'] * 1.62) + (b['hr'] * 2.1)) / (b['pa'] - b['hbp'] - b['sac'])
|
|
ab = f'{b["ab"]:.0f}'
|
|
run = f'{b["run"]:.0f}'
|
|
hit = f'{b["hit"]:.0f}'
|
|
double = f'{b["double"]:.0f}'
|
|
triple = f'{b["triple"]:.0f}'
|
|
hr = f'{b["hr"]:.0f}'
|
|
rbi = f'{b["rbi"]:.0f}'
|
|
sb = f'{b["sb"]:.0f}'
|
|
cs = f'{b["cs"]:.0f}'
|
|
so = f'{b["so"]:.0f}'
|
|
|
|
batting_string = f'```\n' \
|
|
f' AVG OBP SLG OPS\n' \
|
|
f' {avg:.3f} {obp:.3f} {slg:.3f} {ops:.3f}\n``````\n' \
|
|
f' AB R H HR RBI SB\n' \
|
|
f'{ab: ^4} {run: ^3} {hit: ^3} {hr: >3} {rbi: >3} ' \
|
|
f'{sb: >3}\n```'
|
|
|
|
if p:
|
|
if p['ip'] > 0:
|
|
win = f'{p["win"]:.0f}'
|
|
loss = f'{p["loss"]:.0f}'
|
|
save = f'{p["sv"]:.0f}'
|
|
era = f'{(p["erun"] * 9) / p["ip"]:.2f}'
|
|
game = f'{p["game"]:.0f}'
|
|
gs = f'{p["gs"]:.0f}'
|
|
ip = f'{p["ip"]:.0f}'
|
|
if p["ip"] % 1 == 0:
|
|
ip += '.0'
|
|
elif str(p["ip"] % 1)[2] == '3':
|
|
ip += '.1'
|
|
else:
|
|
ip += '.2'
|
|
so = f'{p["so"]:.0f}'
|
|
whip = f'{(p["bb"] + p["hit"]) / p["ip"]:.2f}'
|
|
pitching_string = f'```\n' \
|
|
f' W-L SV ERA IP SO WHIP\n' \
|
|
f'{win: >2}-{loss: <2} {save: >2} {era: >5} {ip: ^5} ' \
|
|
f'{so: ^4} {whip: >4}\n```'
|
|
|
|
if batting_string and pitching_string:
|
|
if b['ab'] > p['ip']:
|
|
embed.add_field(name='Batting Stats', value=batting_string, inline=False)
|
|
else:
|
|
embed.add_field(name='Pitching Stats', value=pitching_string, inline=False)
|
|
elif batting_string:
|
|
embed.add_field(name='Batting Stats', value=batting_string, inline=False)
|
|
elif pitching_string:
|
|
embed.add_field(name='Pitching Stats', value=pitching_string, inline=False)
|
|
|
|
await ctx.send(content=None, embed=embed)
|
|
|
|
@commands.command(name='schedule', help='This week and next')
|
|
async def schedule_command(self, ctx, week: Optional[int] = None):
|
|
current = await db_get('current')
|
|
|
|
if week is not None:
|
|
schedule_week = week
|
|
elif current['week'] < 1:
|
|
schedule_week = 1
|
|
else:
|
|
schedule_week = current['week']
|
|
|
|
g1_query = await db_get('games', params=[
|
|
('season', current['season']), ('week_start', schedule_week), ('week_end', schedule_week)
|
|
])
|
|
g2_query = await db_get('games', params=[
|
|
('season', current['season']), ('week_start', schedule_week + 1), ('week_end', schedule_week + 1)
|
|
])
|
|
|
|
games_played = 0
|
|
games_wk1, games_wk2 = {}, {}
|
|
|
|
for x in g1_query['games']:
|
|
if x['away_score'] is not None:
|
|
games_played += 1
|
|
|
|
game_id = f'{x["away_team"]["id"]}-{x["home_team"]["id"]}'
|
|
if game_id not in games_wk1:
|
|
games_wk1[game_id] = {
|
|
'away_wins': 0, 'home_wins': 0, 'away_team': x["away_team"], 'home_team': x["home_team"]
|
|
}
|
|
|
|
if x['away_score'] is not None:
|
|
if x['away_score'] > x['home_score']:
|
|
games_wk1[game_id]['away_wins'] += 1
|
|
else:
|
|
games_wk1[game_id]['home_wins'] += 1
|
|
|
|
for x in g2_query['games']:
|
|
game_id = f'{x["away_team"]["id"]}-{x["home_team"]["id"]}'
|
|
if game_id not in games_wk2:
|
|
games_wk2[game_id] = {
|
|
'away_wins': 0, 'home_wins': 0, 'away_team': x["away_team"], 'home_team': x["home_team"]
|
|
}
|
|
|
|
embed = get_team_embed(f'Season {current["season"]} | Week {schedule_week} | '
|
|
f'{games_played}/{g1_query["count"]} games played')
|
|
|
|
embed.add_field(name='Full Schedule',
|
|
value=SBA_SCHEDULE_URL,
|
|
inline=False)
|
|
|
|
string_this_week_0 = ''
|
|
string_this_week_1 = ''
|
|
count = 0
|
|
for x in games_wk1.values():
|
|
this_line = f'`({x["away_wins"]}) {x["away_team"]["abbrev"]: >4}` ' \
|
|
f'{await team_emoji(ctx, x["away_team"])} @ ' \
|
|
f'{await team_emoji(ctx, x["home_team"])} ' \
|
|
f'`{x["home_team"]["abbrev"]: <4} ({x["home_wins"]})`\n'
|
|
|
|
if count > 7:
|
|
string_this_week_1 += this_line
|
|
else:
|
|
string_this_week_0 += this_line
|
|
|
|
count += 1
|
|
|
|
string_next_week_0 = ''
|
|
string_next_week_1 = ''
|
|
count = 0
|
|
for x in games_wk2.values():
|
|
this_line = f'`{x["away_team"]["abbrev"]: >4}` {await team_emoji(ctx, x["away_team"])} @ ' \
|
|
f'{await team_emoji(ctx, x["home_team"])} `{x["home_team"]["abbrev"]: <4}`\n'
|
|
|
|
if count > 7:
|
|
string_next_week_1 += this_line
|
|
else:
|
|
string_next_week_0 += this_line
|
|
|
|
count += 1
|
|
|
|
if len(string_this_week_0) > 0:
|
|
embed.add_field(
|
|
name=f'**Week {schedule_week} Games:**',
|
|
value=string_this_week_0,
|
|
inline=False
|
|
)
|
|
await ctx.send(content=None, embed=embed)
|
|
|
|
if len(string_this_week_1) > 0:
|
|
if len(embed.fields) > 1:
|
|
embed.remove_field(0)
|
|
embed.set_field_at(
|
|
index=0,
|
|
name=f'**Week {schedule_week} Part 2:**',
|
|
value=string_this_week_1,
|
|
inline=False
|
|
)
|
|
await ctx.send(content=None, embed=embed)
|
|
|
|
if len(string_next_week_0) > 0:
|
|
if len(embed.fields) > 1:
|
|
embed.remove_field(0)
|
|
embed.set_field_at(
|
|
index=0,
|
|
name=f'**Week {schedule_week + 1} Games:**',
|
|
value=string_next_week_0,
|
|
inline=False
|
|
)
|
|
embed.title = f'Season {current["season"]} | Week {schedule_week + 1}'
|
|
await ctx.send(content=None, embed=embed)
|
|
if len(string_next_week_1) > 0:
|
|
if len(embed.fields) > 1:
|
|
embed.remove_field(0)
|
|
embed.set_field_at(
|
|
index=0,
|
|
name=f'**Week {schedule_week + 1} Part 2:**',
|
|
value=string_next_week_1,
|
|
inline=False
|
|
)
|
|
await ctx.send(content=None, embed=embed)
|
|
|
|
@commands.command(name='weather', help='Roll ballpark weather')
|
|
async def weather_command(self, ctx, team_abbrev=None):
|
|
current = await db_get('current')
|
|
|
|
if team_abbrev is not None:
|
|
t_query = await db_get('teams', params=[('season', current['season']), ('team_abbrev', team_abbrev)])
|
|
else:
|
|
t_query = await db_get('teams', params=[
|
|
('season', current['season']), ('team_abbrev', ctx.channel.name.split('-')[0])
|
|
])
|
|
if t_query['count'] == 0:
|
|
t_query = await db_get('teams', params=[('season', current['season']), ('owner_id', ctx.author.id)])
|
|
|
|
if t_query['count'] == 0:
|
|
await ctx.send(f'I could not find a weather chart for you.')
|
|
|
|
team = t_query['teams'][0]
|
|
d_twenty = random.randint(1, 20)
|
|
embed = get_team_embed('Weather Chart', team, thumbnail=False)
|
|
embed.set_image(url=team['stadium'])
|
|
embed.add_field(name=f'Weather roll for {ctx.author.name}',
|
|
value=f'```md\n# {d_twenty}\nDetails:[1d20 ({d_twenty})]\n```')
|
|
|
|
await ctx.send(content=None, embed=embed)
|
|
|
|
async def get_division_standings(self, current) -> discord.Embed:
|
|
d1_query = await db_get('standings', params=[
|
|
('season', current['season']), ('division_abbrev', 'SWW')
|
|
])
|
|
div_one = d1_query['standings']
|
|
d2_query = await db_get('standings', params=[
|
|
('season', current['season']), ('division_abbrev', 'BBVW')
|
|
])
|
|
div_two = d2_query['standings']
|
|
d3_query = await db_get('standings', params=[
|
|
('season', current['season']), ('division_abbrev', 'WN')
|
|
])
|
|
div_three = d3_query['standings']
|
|
d4_query = await db_get('standings', params=[
|
|
('season', current['season']), ('division_abbrev', 'PP')
|
|
])
|
|
div_four = d4_query['standings']
|
|
|
|
div_one_standings = f'```\nTeam W-L PCT GB E# RD\n'
|
|
for team in div_one:
|
|
div_one_standings += self.team_stan_line(team)
|
|
div_one_standings += f'\n```'
|
|
|
|
div_two_standings = f'```\nTeam W-L PCT GB E# RD\n'
|
|
for team in div_two:
|
|
div_two_standings += self.team_stan_line(team)
|
|
div_two_standings += f'\n```'
|
|
|
|
div_three_standings = f'```\nTeam W-L PCT GB E# RD\n'
|
|
for team in div_three:
|
|
div_three_standings += self.team_stan_line(team)
|
|
div_three_standings += f'\n```'
|
|
|
|
div_four_standings = f'```\nTeam W-L PCT GB E# RD\n'
|
|
for team in div_four:
|
|
div_four_standings += self.team_stan_line(team)
|
|
div_four_standings += f'\n```'
|
|
|
|
progress = await self.game_progress(current)
|
|
|
|
embed = discord.Embed(title=f'Season {current["season"]} | Week {current["week"]} | '
|
|
f'{progress["games_played"]}/{progress["game_count"]} games played',
|
|
color=0xB70000)
|
|
embed.add_field(name=f'**Full Standings**', value=SBA_STANDINGS_URL, inline=False)
|
|
embed.add_field(name=f'**Ice Cream**', value=div_one_standings, inline=False)
|
|
embed.add_field(name=f'**Hobgoblins**', value=div_two_standings, inline=False)
|
|
embed.add_field(name=f'**Dinger Central**', value=div_three_standings, inline=False)
|
|
embed.add_field(name=f'**Milkshakes**', value=div_four_standings, inline=False)
|
|
|
|
return embed
|
|
|
|
async def get_wildcard_standings(self, current) -> discord.Embed:
|
|
a_query = await db_get('standings', params=[
|
|
('season', current['season']), ('league_abbrev', 'SBa')
|
|
])
|
|
al_teams = a_query['standings']
|
|
# n_query = await db_get('standings', params=[
|
|
# ('season', current['season']), ('league_abbrev', 'nl')
|
|
# ])
|
|
# nl_teams = n_query['standings']
|
|
|
|
al_wildcard = f'```\nTeam W-L PCT GB E# RD\n'
|
|
for team in al_teams:
|
|
al_wildcard += self.team_stan_line(team, s_type='wc')
|
|
al_wildcard += '```'
|
|
|
|
# nl_wildcard = f'```\nTeam W-L PCT GB E# RD\n'
|
|
# for team in nl_teams:
|
|
# nl_wildcard += self.team_stan_line(team, s_type='wc')
|
|
# nl_wildcard += '```'
|
|
|
|
progress = await self.game_progress(current)
|
|
|
|
embed = discord.Embed(title=f'Season {current["season"]} | Week {current["week"]} | '
|
|
f'{progress["games_played"]}/{progress["game_count"]} games played',
|
|
color=0xB70000)
|
|
embed.add_field(name=f'**Full Standings**', value=SBA_STANDINGS_URL, inline=False)
|
|
embed.add_field(name=f'**AL Wildcard**', value=al_wildcard, inline=False)
|
|
# embed.add_field(name=f'**NL Wildcard**', value=nl_wildcard, inline=False)
|
|
|
|
return embed
|
|
|
|
async def standings_button_loop(self, ctx, start: Literal['division', 'wildcard']):
|
|
async with ctx.typing():
|
|
current = await db_get('current')
|
|
div_embed = await self.get_division_standings(current)
|
|
wc_embed = await self.get_wildcard_standings(current)
|
|
logger.info(f'div_embed: {div_embed}\nwc_embed: {wc_embed}')
|
|
|
|
view = Pagination(responders=[ctx.author], timeout=15)
|
|
view.left_button.label = 'Division'
|
|
view.right_button.label = 'Wildcard'
|
|
if start == 'division':
|
|
embed = div_embed
|
|
view.left_button.disabled = True
|
|
else:
|
|
embed = wc_embed
|
|
view.right_button.disabled = True
|
|
st_message = await ctx.send(content=None, embed=embed, view=view)
|
|
|
|
while True:
|
|
await view.wait()
|
|
|
|
if view.value:
|
|
logger.info(f'standings_button_loop - view.value: {view.value}')
|
|
if view.value == 'cancel':
|
|
await st_message.edit(view=None)
|
|
return
|
|
elif view.value == 'left':
|
|
start = 'division'
|
|
elif view.value == 'right':
|
|
start = 'wildcard'
|
|
else:
|
|
await st_message.edit(view=None)
|
|
return
|
|
|
|
view = Pagination(responders=[ctx.author], timeout=15)
|
|
view.left_button.label = 'Division'
|
|
view.right_button.label = 'Wildcard'
|
|
if start == 'division':
|
|
embed = div_embed
|
|
view.left_button.disabled = True
|
|
else:
|
|
embed = wc_embed
|
|
view.right_button.disabled = True
|
|
|
|
logger.info(f'standings_button_loop - start: {start} / embed == div_embed? {embed == div_embed} / '
|
|
f'embed == wc_embed {embed == wc_embed}')
|
|
await st_message.delete()
|
|
st_message = await ctx.send(content=None, embed=embed, view=view)
|
|
|
|
@commands.command(name='standings', help='Current standings')
|
|
async def standings_command(self, ctx):
|
|
await self.standings_button_loop(ctx, 'division')
|
|
|
|
@commands.command(name='wildcard', aliases=['wc'], help='Current wildcard')
|
|
async def wildcard_command(self, ctx):
|
|
await self.standings_button_loop(ctx, 'wildcard')
|
|
|
|
@app_commands.command(name='setinjury', description='Set the return date for injured player')
|
|
@app_commands.describe(
|
|
player_name='Name of injured player',
|
|
this_week='The current SBa week',
|
|
this_game='The game number in which the player got injured',
|
|
inj_games='The number of games the player will miss'
|
|
)
|
|
@app_commands.checks.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def set_injury_slash(
|
|
self, interaction: discord.Interaction, player_name: str, this_week: int, this_game: int, inj_games: int):
|
|
if interaction.guild_id != 613880856032968834:
|
|
await interaction.response.send_message(f'This must be run in the SBa server.')
|
|
return
|
|
|
|
await interaction.response.defer()
|
|
current = await db_get('current')
|
|
|
|
p_query = await db_get('players', params=[('name', player_name), ('season', current['season'])])
|
|
if p_query['count'] == 0:
|
|
await interaction.edit_original_response(content=f'I did not find anybody named **{player_name}**.')
|
|
return
|
|
|
|
player = p_query['players'][0]
|
|
|
|
# Check if player is on owner's team
|
|
team = await get_team_by_owner(current['season'], interaction.user.id)
|
|
if not player['team'] == team and not player['team']['abbrev'][:len(team['abbrev'])] == team['abbrev']:
|
|
await interaction.edit_original_response(
|
|
content=f'Is this some kind of tom foolery? {player["name"]} is on {player["team"]["abbrev"]} aka '
|
|
f'not your team. I\'m watching you.'
|
|
)
|
|
return
|
|
|
|
i_query = await db_get('injuries', params=[('player_id', player['id']), ('is_active', True)])
|
|
if i_query['count'] > 0:
|
|
await interaction.edit_original_response(content=f'Hm. It looks like {player["name"]} is already hurt.')
|
|
return
|
|
|
|
out_weeks = math.floor(inj_games / 4)
|
|
out_games = inj_games % 4
|
|
|
|
return_week = this_week + out_weeks
|
|
return_game = this_game + 1 + out_games
|
|
if this_game + 1 + out_games > 4:
|
|
return_week += 1
|
|
return_game -= 4
|
|
|
|
return_date = f'w{return_week:>02}g{return_game:>02}'
|
|
player['il_return'] = return_date
|
|
if await put_player(player):
|
|
embed = get_team_embed(f'Injury Update', team=team)
|
|
embed.add_field(
|
|
name=f'{player["name"]}',
|
|
value=f'{team["sname"]} {player["pos_1"]} {player["name"]} is injured until {return_date}'
|
|
)
|
|
|
|
await db_post('injuries', payload={
|
|
'season': current['season'],
|
|
'player_id': player['id'],
|
|
'total_games': inj_games,
|
|
'start_week': this_week if this_game != 4 else this_week + 1,
|
|
'start_game': this_game + 1 if this_game != 4 else 1,
|
|
'end_week': return_week,
|
|
'end_game': return_game
|
|
})
|
|
await interaction.edit_original_response(content=random_salute_gif())
|
|
await send_to_channel(self.bot, 'sba-network-news', content=None, embed=embed)
|
|
await self.update_injuries(interaction)
|
|
else:
|
|
await interaction.edit_original_response(content='Well that didn\'t work.')
|
|
|
|
@app_commands.command(name='clearinjury', description='Clear the injury for a player')
|
|
@app_commands.describe(player_name='Name of injured player')
|
|
@app_commands.checks.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def clear_injury_slash(self, interaction: discord.Interaction, player_name: str):
|
|
await interaction.response.defer()
|
|
current = await db_get('current')
|
|
|
|
p_query = await db_get('players', params=[('name', player_name), ('season', current['season'])])
|
|
if p_query['count'] == 0:
|
|
await interaction.response.send_message(f'I did not find anybody named **{player_name}**.')
|
|
return
|
|
|
|
player = p_query['players'][0]
|
|
i_query = await db_get('injuries', params=[('player_id', player['id']), ('is_active', True)])
|
|
|
|
if not player['il_return'] and i_query['count'] == 0:
|
|
await interaction.edit_original_response(content='Huh? He isn\'t injured, numb nuts.')
|
|
return
|
|
|
|
team = await get_team_by_owner(current['season'], interaction.user.id)
|
|
if not player['team'] == team and not player['team']['abbrev'][:len(team['abbrev'])] == team['abbrev']:
|
|
await interaction.edit_original_response(
|
|
content=f'Is this some kind of tom foolery? {player["name"]} is on {player["team"]["abbrev"]} aka '
|
|
f'not your team. I\'m watching you.'
|
|
)
|
|
return
|
|
|
|
old_injury = player['il_return']
|
|
view = Confirm(responders=[interaction.user])
|
|
await interaction.edit_original_response(
|
|
content=f'{player["name"]}\'s return was set for {player["il_return"]}. Is he eligible to play again?',
|
|
view=view
|
|
)
|
|
await view.wait()
|
|
|
|
if view.value:
|
|
player['il_return'] = None
|
|
await interaction.edit_original_response(
|
|
content='Okay. Working on it...',
|
|
view=None
|
|
)
|
|
player['il_return'] = None
|
|
if await put_player(player):
|
|
embed = get_team_embed(f'Injury Update', team=team)
|
|
embed.add_field(
|
|
name=f'{player["name"]}',
|
|
value=f'{team["sname"]} {player["pos_1"]} {player["name"]}\'s injury ({old_injury}) has ended'
|
|
)
|
|
|
|
await db_patch('injuries', object_id=i_query['injuries'][0]['id'], params=[('is_active', False)])
|
|
await interaction.edit_original_response(
|
|
content=random_conf_gif(),
|
|
view=None
|
|
)
|
|
await send_to_channel(self.bot, 'sba-network-news', content=None, embed=embed)
|
|
await self.update_injuries(interaction)
|
|
else:
|
|
await interaction.edit_original_response(content='Well that didn\'t work.')
|
|
else:
|
|
await interaction.edit_original_response(
|
|
content='You keep thinking on it.',
|
|
view=None
|
|
)
|
|
|
|
@commands.command(name='links', aliases=['scorecards', 'scorecard', 'link', 'resources', 'resource'],
|
|
help='Links for league resources')
|
|
async def scorecard_command(self, ctx):
|
|
await ctx.send(
|
|
'# SCORECARD\n'
|
|
'<https://docs.google.com/spreadsheets/d/1HjPRBec0FzeWBmvr2P3PUQRXA71fvQR7LPLcGP6UwxI>\n'
|
|
'# REFERENCES\n'
|
|
'**Rules Reference**:\n<https://docs.google.com/document/d/1wDaQefxFL7h2Fk4Cx1jf4wTJ-kfx7Bl9_0OGViLjIJ8/'
|
|
'edit?usp=sharing>\n'
|
|
'**League Guidelines**:\n<https://docs.google.com/document/d/1PG9KFkIMp3pAf26GPtMmQR65l6h311nYACbv8GB_3q8/'
|
|
'edit?usp=sharing>\n'
|
|
'**Scouting Reference**:\n<https://docs.google.com/spreadsheets/d/1jt-dgSEYKG_wvUyj-tmhmUbqyl3QnQc9uZBhY'
|
|
'2oJmOc/edit?usp=sharing>'
|
|
)
|
|
|
|
@commands.command(name='rest', help='Pitcher rest charts', hidden=True)
|
|
async def rest_command(self, ctx):
|
|
# sp_rest_url = 'https://lh3.googleusercontent.com/pw/ACtC-3eeRv52FZIUZNNafBBpwxJIx_OViLYHbsyi129GkJkIiv7r-X3O' \
|
|
# 'In9_mfkr9GVl2NbLhCJ9j1IQD5DX75bLwX0gVAFExkGNolnngKck9yx6g-qjQ6QoXkc2t821UwxGoRNbZadxfd3wUn32a' \
|
|
# 'zdQnJxnZw=w419-h703-no?authuser=0'
|
|
# rp_rest_url = 'https://lh3.googleusercontent.com/pw/ACtC-3eU_nNLYv2KLJTCom9BUSkjY-kD-VBumaiPYQxzfDB23yvkozLc' \
|
|
# 'Qt9ai-xIwXe7CsGJ61qKgv6s6-lJp3_LRImwDFfP2VzUyPDFjE3P_CiuL6FsZCrzIBylQdLBXtxEsVmnGeSLv1WtJ--Wf' \
|
|
# '3KzZVoOkQ=w525-h453-no?authuser=0'
|
|
#
|
|
# sp_embed = discord.Embed(title='SP Rest Chart')
|
|
# sp_embed.set_image(url=sp_rest_url)
|
|
# await ctx.send(content=None, embed=sp_embed)
|
|
#
|
|
# rp_embed = discord.Embed(title='RP Rest Chart')
|
|
# rp_embed.set_image(url=rp_rest_url)
|
|
# await ctx.send(content=None, embed=rp_embed)
|
|
# await ctx.send('For full rules, see <https://sombaseball.ddns.net/rules#pitcher-endurance>')
|
|
await ctx.send('This command has been deprecated - please run `/charts rest`')
|
|
|
|
@app_commands.command(name='sba-submit', description='Submit scorecard and game result')
|
|
@app_commands.checks.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def submit_slash(self, interaction: discord.Interaction, sheet_url: str):
|
|
current = await db_get('current')
|
|
|
|
# Go get scorecard
|
|
await interaction.response.send_message(content='I\'ll go grab that card now...')
|
|
logger.info(f'Checking scorecard {sheet_url}')
|
|
|
|
# Try to get card
|
|
try:
|
|
sheets = pygsheets.authorize(service_file='storage/major-domo-service-creds.json')
|
|
scorecard = sheets.open_by_url(sheet_url)
|
|
except Exception as e:
|
|
logger.error(f'Failed to access scorecard {sheet_url}: {e}')
|
|
await interaction.edit_original_response(content='Is that sheet public? I can\'t access it.')
|
|
return
|
|
|
|
# Get outline data from the sheet
|
|
await asyncio.sleep(1)
|
|
setup_tab = scorecard.worksheet_by_title('Setup')
|
|
|
|
scorecard_version = setup_tab.get_value('V35')
|
|
if int(scorecard_version) != current['bet_week']:
|
|
await interaction.edit_original_response(
|
|
content=f'It looks like this scorecard is out of date. Did you create a new card at the start of the '
|
|
f'game? If you did, let Cal know about this error. If not, I\'ll need you to use an up to '
|
|
f'date card.'
|
|
)
|
|
return
|
|
|
|
g_data = setup_tab.get_values('C3', 'D7')
|
|
# setup_vals = setup_tab.get_values('B7', 'R33')
|
|
week_num = g_data[1][0]
|
|
game_num = g_data[2][0]
|
|
at_abbrev = g_data[3][0]
|
|
ht_abbrev = g_data[4][0]
|
|
away_mgr_name = g_data[3][1]
|
|
home_mgr_name = g_data[4][1]
|
|
away_team = await get_team_by_abbrev(at_abbrev, current['season'])
|
|
home_team = await get_team_by_abbrev(ht_abbrev, current['season'])
|
|
logger.info(f'away_manager: {away_mgr_name} / home_manager: {home_mgr_name}')
|
|
if away_team['manager2'] is not None and away_team['manager2']['name'].lower() == away_mgr_name.lower():
|
|
away_manager = away_team['manager2']
|
|
else:
|
|
away_manager = away_team['manager1']
|
|
if home_team['manager2'] is not None and home_team['manager2']['name'].lower() == home_mgr_name.lower():
|
|
home_manager = home_team['manager2']
|
|
else:
|
|
home_manager = home_team['manager1']
|
|
|
|
logger.info(f'gdata: {g_data}\nweek/game: {week_num}/{game_num}')
|
|
|
|
# Confirm submitting GM
|
|
if await get_team_by_owner(current['season'], interaction.user.id) not in [home_team, away_team] and \
|
|
interaction.user.id != self.bot.owner_id:
|
|
await interaction.edit_original_response(
|
|
content=f'{await get_emoji(interaction, "squint")} Only a GM of the two teams can submit scorecards.'
|
|
)
|
|
return
|
|
|
|
# Confirm teams and matchup
|
|
dupe_g_query = await db_get('games', params=[
|
|
('season', current['season']), ('week', week_num), ('game_num', game_num),
|
|
('away_team_id', away_team['id']), ('home_team_id', home_team['id'])
|
|
])
|
|
if dupe_g_query['count'] != 0:
|
|
dupe_game = dupe_g_query['games'][0]
|
|
view = Confirm(responders=[interaction.user], timeout=30)
|
|
await interaction.edit_original_response(
|
|
content=f'This game has already been played! Would you like me to wipe the old one and re-submit?',
|
|
view=view
|
|
)
|
|
await view.wait()
|
|
|
|
if view.value:
|
|
await interaction.edit_original_response(
|
|
content='Okay, let me wipe the old shit...',
|
|
view=None
|
|
)
|
|
try:
|
|
await db_delete('plays/game', object_id=dupe_game['id'])
|
|
except ValueError as e:
|
|
logger.error(f'No plays for game {dupe_game["id"]}')
|
|
try:
|
|
await db_delete('decisions/game', object_id=dupe_game['id'])
|
|
except ValueError as e:
|
|
logger.error(f'No decisions for game {dupe_game["id"]}')
|
|
await db_post(f'games/wipe/{dupe_game["id"]}')
|
|
else:
|
|
await interaction.edit_original_response(
|
|
content='You think on it some more and get back to me later.',
|
|
view=None
|
|
)
|
|
return
|
|
|
|
g_query = await db_get('games', params=[
|
|
('season', current['season']), ('week', week_num), ('away_team_id', away_team['id']),
|
|
('home_team_id', home_team['id']), ('played', False)
|
|
])
|
|
if g_query['count'] == 0:
|
|
await interaction.edit_original_response(
|
|
content=f'I don\'t see any games between {away_team["abbrev"]} and {home_team["abbrev"]} '
|
|
f'in week {week_num}.'
|
|
)
|
|
return
|
|
this_game = g_query['games'][0]
|
|
logger.info(f'this_game: {this_game}')
|
|
|
|
# TODO: check for stats and wipe
|
|
logger.info(f'checking for old stats')
|
|
|
|
await interaction.edit_original_response(content='Here I go sheetsing again...', view=None)
|
|
logger.info(f'sba-submit - reading scorecard')
|
|
playtable = scorecard.worksheet_by_title('Playtable')
|
|
all_plays = playtable.get_values('B3', 'BW300')
|
|
logger.debug(f'all_plays: {all_plays}')
|
|
|
|
play_keys = [
|
|
'play_num', 'batter_id', 'batter_pos', 'pitcher_id', 'on_base_code', 'inning_half', 'inning_num',
|
|
'batting_order', 'starting_outs', 'away_score', 'home_score', 'on_first_id', 'on_first_final',
|
|
'on_second_id', 'on_second_final', 'on_third_id', 'on_third_final', 'batter_final', 'pa', 'ab', 'run',
|
|
'e_run', 'hit', 'rbi', 'double', 'triple', 'homerun', 'bb', 'so', 'hbp', 'sac', 'ibb', 'gidp',
|
|
'bphr', 'bpfo', 'bp1b', 'bplo', 'sb', 'cs', 'outs', 'pitcher_rest_outs', 'wpa', 'catcher_id', 'defender_id',
|
|
'runner_id', 'check_pos', 'error', 'wild_pitch', 'passed_ball', 'pick_off', 'balk', 'is_go_ahead',
|
|
'is_tied', 'is_new_inning', 'inherited_runners', 'inherited_scored', 'on_hook_for_loss', 'run_differential',
|
|
'unused-manager', 'unused-pitcherpow', 'unused-pitcherrestip', 'unused-runners', 'unused-fatigue',
|
|
'unused-roundedip', 'unused-elitestart', 'unused-scenario', 'unused-winxaway', 'unused-winxhome',
|
|
'unused-pinchrunner', 'unused-order', 'hand_batting', 'hand_pitching', 're24_primary', 're24_running'
|
|
]
|
|
p_data = []
|
|
final_inning = 0
|
|
for line in all_plays:
|
|
this_data = {'game_id': this_game['id']}
|
|
for count, x in enumerate(line):
|
|
if x != '':
|
|
this_data[play_keys[count]] = x
|
|
if len(this_data.keys()) > 5:
|
|
p_data.append(this_data)
|
|
final_inning = line[6]
|
|
|
|
logger.info(f'players - final_inning: {final_inning}')
|
|
logger.info(f'p_data: {p_data}')
|
|
# Post plays
|
|
try:
|
|
resp = await db_post('plays', payload={'plays': p_data})
|
|
except ValueError as e:
|
|
logger.error(f'POST plays error: {e}')
|
|
await interaction.edit_original_response(
|
|
content=f'The following errors were found in your **wk{week_num}g{game_num}** scorecard. '
|
|
f'Please resolve them and resubmit - thanks!\n\n{e}'
|
|
)
|
|
return
|
|
|
|
# Post box score to news-ticker
|
|
try:
|
|
sc_tab = scorecard.worksheet_by_title('Scorecard')
|
|
score_table = sc_tab.get_values('BW8', 'BY9')
|
|
except pygsheets.WorksheetNotFound as e:
|
|
sc_tab = scorecard.worksheet_by_title('Box Score')
|
|
score_table = sc_tab.get_values('T6', 'V7')
|
|
logger.info(f'players - score_table: {score_table}')
|
|
# final_inning = all_plays[len(all_plays) - 1][6]
|
|
# logger.info(f'players - final_inning: {final_inning}')
|
|
|
|
# Log game result
|
|
try:
|
|
g_resp = await db_patch('games', object_id=this_game['id'], params=[
|
|
('away_score', int(score_table[0][0])), ('home_score', int(score_table[1][0])),
|
|
('away_manager_id', away_manager['id']), ('home_manager_id', home_manager['id']),
|
|
('game_num', game_num), ('scorecard_url', sheet_url)
|
|
])
|
|
except ValueError as e:
|
|
logger.error(f'PATCH game error: {e}')
|
|
await interaction.edit_original_response(
|
|
content=f'I was not able to log the game result. Go bug cal - it\'s probably his fault.'
|
|
)
|
|
await db_delete(f'plays/game', object_id=this_game['id'])
|
|
return
|
|
|
|
# Pull pitching decisions
|
|
pitching = scorecard.worksheet_by_title('Pitcherstats')
|
|
all_decisions = pitching.get_values('B3', 'O30')
|
|
logger.info(f'all_decisions: {all_decisions}')
|
|
|
|
pit_keys = [
|
|
'pitcher_id', 'rest_ip', 'is_start', 'base_rest', 'extra_rest', 'rest_required', 'win',
|
|
'loss', 'is_save', 'hold', 'b_save', 'irunners', 'irunners_scored', 'team_id'
|
|
]
|
|
pit_data = []
|
|
wp = None
|
|
lp = None
|
|
sv = None
|
|
b_sv = []
|
|
holds = []
|
|
for line in all_decisions:
|
|
this_data = {'game_id': this_game['id'], 'season': this_game['season'], 'week': this_game['week'],
|
|
'game_num': game_num}
|
|
for count, x in enumerate(line):
|
|
if x != '':
|
|
this_data[pit_keys[count]] = x
|
|
pit_data.append(this_data)
|
|
if line[6] == '1':
|
|
wp = await db_get('players', object_id=line[0])
|
|
if line[7] == '1':
|
|
lp = await db_get('players', object_id=line[0])
|
|
if line[8] == '1':
|
|
sv = await db_get('players', object_id=line[0])
|
|
if line[10] == '1':
|
|
b_sv.append(await db_get('players', object_id=line[0]))
|
|
if line[9] == '1':
|
|
holds.append(await db_get('players', object_id=line[0]))
|
|
|
|
if wp is None or lp is None:
|
|
await interaction.edit_original_response(
|
|
content='You card is missing either a Winning Pitcher or Losing Pitcher'
|
|
)
|
|
await db_delete(f'plays/game', object_id=this_game['id'], timeout=6)
|
|
return
|
|
|
|
logger.info(f'pit_data: {pit_data}')
|
|
# Post decisions
|
|
try:
|
|
d_resp = await db_post('decisions', payload={'decisions': pit_data})
|
|
except ValueError as e:
|
|
logger.error(f'POST decisions error: {e}')
|
|
await interaction.edit_original_response(
|
|
content=f'The following errors were found in your **wk{week_num}g{game_num}** scorecard. '
|
|
f'Please resolve them and resubmit - thanks!\n\n{e}'
|
|
)
|
|
await db_post(f'games/wipe/{this_game["id"]}')
|
|
await db_delete('plays/game', object_id=this_game['id'])
|
|
return
|
|
|
|
# Post scorecard to news channel
|
|
card_url = f'<{SBA_BASE_URL}/games/{current["season"]}/{week_num}/{game_num}' \
|
|
f'/{away_team["abbrev"]}/{home_team["abbrev"]}>'
|
|
extras = ''
|
|
if int(final_inning) > 9:
|
|
extras = f' F/{final_inning}'
|
|
embed = get_team_embed(
|
|
f'{away_team["sname"]} {score_table[0][0]} @ '
|
|
f'{score_table[1][0]} {home_team["sname"]}{extras}',
|
|
team=away_team if int(score_table[0][0]) > int(score_table[1][0]) else home_team
|
|
)
|
|
embed.description = f'Week {week_num} | Game {game_num}'
|
|
|
|
embed.add_field(
|
|
name='Box Score',
|
|
value=f'```\n'
|
|
f'Team | R | H | E |\n'
|
|
f'{away_team["abbrev"]: <4} | {score_table[0][0]: >2} | {score_table[0][1]: >2} | '
|
|
f'{score_table[0][2]: >2} |\n'
|
|
f'{home_team["abbrev"]: <4} | {score_table[1][0]: >2} | {score_table[1][1]: >2} | '
|
|
f'{score_table[1][2]: >2} |\n'
|
|
f'```',
|
|
inline=False
|
|
)
|
|
|
|
pitching_string = f'WP: {wp["name"]}\n' \
|
|
f'LP: {lp["name"]}\n' \
|
|
f'{"HD: " if len(holds) > 0 else ""}'
|
|
|
|
hold_string = ''
|
|
count = 1
|
|
for x in holds:
|
|
hold_string += f'{x["name"]}'
|
|
if count < len(holds):
|
|
hold_string += ', '
|
|
count += 1
|
|
if len(hold_string) > 0:
|
|
hold_string = f'{hold_string}\n'
|
|
pitching_string += hold_string
|
|
|
|
if sv is not None:
|
|
pitching_string += f'SV: {sv["name"]}'
|
|
|
|
embed.add_field(name='Pitching', value=pitching_string, inline=False)
|
|
|
|
# Key Plays pull
|
|
logger.info(f'pull highlight stats for embed')
|
|
p_query = await db_get('plays', params=[
|
|
('game_id', this_game['id']), ('sort', 'wpa-desc'), ('limit', 3)
|
|
])
|
|
|
|
key_plays = ''
|
|
for play in p_query['plays']:
|
|
logger.info(f'this_play: {play}')
|
|
this_line = f'- {play["inning_half"].title()} {play["inning_num"]}: '
|
|
|
|
# Offensive Play
|
|
if play['wpa'] > 0:
|
|
logger.info('OFFENSE')
|
|
if play['runner'] is not None:
|
|
logger.info('RUNNER')
|
|
if play['on_third'] == play['runner']['id']:
|
|
s_base = 'HOME'
|
|
elif play['on_second'] == play['runner']['id']:
|
|
s_base = 'third'
|
|
else:
|
|
s_base = 'second'
|
|
this_line += f'{play["runner"]["name"]} ({play["runner"]["team"]["abbrev"]}) steals {s_base}'
|
|
else:
|
|
logger.info('BATTER')
|
|
if play['homerun'] == 1:
|
|
h_name = 'homers'
|
|
elif play['triple'] == 1:
|
|
h_name = 'triples'
|
|
elif play['double'] == 1:
|
|
h_name = 'doubles'
|
|
elif play['sac'] == 1:
|
|
h_name = 'sac flies'
|
|
else:
|
|
h_name = 'singles'
|
|
logger.info('RBI?')
|
|
if play['rbi'] > 0:
|
|
rbi_string = f' in {play["rbi"]} run{"s" if play["rbi"] > 1 else ""}'
|
|
else:
|
|
rbi_string = ''
|
|
logger.info('LINE?')
|
|
this_line += f'{play["batter"]["name"]} ({play["batter"]["team"]["abbrev"]}) {h_name}{rbi_string}'
|
|
# Defensive Play
|
|
else:
|
|
logger.info('DEFENSE')
|
|
if play['catcher'] is not None:
|
|
logger.info('CATCHER')
|
|
if play['on_third_final'] == 0:
|
|
s_base = 'HOME'
|
|
elif play['on_second_final'] == 0:
|
|
s_base = 'third'
|
|
else:
|
|
s_base = 'second'
|
|
this_line += f'{play["catcher"]["name"]} ({play["catcher"]["team"]["abbrev"]}) throws out the ' \
|
|
f'runner at {s_base}'
|
|
elif play['defender'] is not None:
|
|
logger.info('DEFENDER')
|
|
if play['outs'] == 3:
|
|
play_string = 'turns a TRIPLE PLAY'
|
|
elif play['outs'] == 2:
|
|
play_string = 'rolls a double play'
|
|
else:
|
|
play_string = f'makes a tough play at {play["check_pos"]}'
|
|
this_line += f'{play["defender"]["name"]} ({play["defender"]["team"]["abbrev"]}) {play_string}'
|
|
else:
|
|
logger.info('PITCHER')
|
|
if play['so'] == 1:
|
|
if play['starting_outs'] == 2:
|
|
out_th = 'for the 3rd out'
|
|
elif play['starting_outs'] == 1:
|
|
out_th = 'for the 2nd out'
|
|
else:
|
|
out_th = 'to leadoff the inning'
|
|
play_string = f'gets a K {out_th}'
|
|
elif play['on_base_code'] != '000' and play['starting_outs'] + play['outs'] > 2:
|
|
num_runners = play["on_base_code"].count("1")
|
|
play_string = f'strands {num_runners} runner{"s" if num_runners > 1 else ""}'
|
|
else:
|
|
if play['starting_outs'] == 2:
|
|
play_string = 'records the 3rd out'
|
|
elif play['starting_outs'] == 1:
|
|
play_string = 'records the 2nd out'
|
|
else:
|
|
play_string = 'retires the leadoff batter'
|
|
this_line += f'{play["pitcher"]["name"]} ({play["pitcher"]["team"]["abbrev"]}) {play_string}'
|
|
|
|
if play['is_go_ahead']:
|
|
this_line += ' to take the lead'
|
|
|
|
a_score = play['away_score']
|
|
h_score = play['home_score']
|
|
if play['inning_half'] == 'top':
|
|
a_score += play['rbi']
|
|
else:
|
|
h_score += play['rbi']
|
|
if a_score > h_score:
|
|
score_string = f'{away_team["abbrev"]} up {a_score}-{h_score}'
|
|
elif h_score > a_score:
|
|
score_string = f'{home_team["abbrev"]} up {h_score}-{a_score}'
|
|
else:
|
|
score_string = f'tied at {a_score}'
|
|
|
|
key_plays += f'{this_line}, {score_string}\n'
|
|
|
|
if len(key_plays) > 0:
|
|
embed.add_field(
|
|
name='Key Plays',
|
|
value=key_plays,
|
|
inline=False
|
|
)
|
|
|
|
|
|
# batting_string = ''
|
|
# count = 1
|
|
# if len(final_doubles) > 0:
|
|
# batting_string += '2B: '
|
|
#
|
|
# for x in final_doubles:
|
|
# player = await get_one_player(x[0])
|
|
# batting_string += f'{player["name"]}'
|
|
#
|
|
# if x[1] > 1:
|
|
# batting_string += f' {x[1]}'
|
|
#
|
|
# if count < len(final_doubles):
|
|
# batting_string += ', '
|
|
# else:
|
|
# batting_string += '\n'
|
|
# count += 1
|
|
#
|
|
# count = 1
|
|
# if len(final_triples) > 0:
|
|
# batting_string += '3B: '
|
|
#
|
|
# for x in final_triples:
|
|
# player = await get_one_player(x[0])
|
|
# batting_string += f'{player["name"]}'
|
|
#
|
|
# if x[1] > 1:
|
|
# batting_string += f' {x[1]}'
|
|
#
|
|
# if count < len(final_triples):
|
|
# batting_string += ', '
|
|
# else:
|
|
# batting_string += '\n'
|
|
# count += 1
|
|
#
|
|
# count = 1
|
|
# if len(final_homeruns) > 0:
|
|
# batting_string += 'HR: '
|
|
#
|
|
# for x in final_homeruns:
|
|
# player = await get_one_player(x[0])
|
|
# batting_string += f'{player["name"]}'
|
|
#
|
|
# if x[1] > 1:
|
|
# batting_string += f' {x[1]}'
|
|
#
|
|
# if count < len(final_homeruns):
|
|
# batting_string += ', '
|
|
# else:
|
|
# batting_string += '\n'
|
|
# count += 1
|
|
#
|
|
# if len(batting_string) > 0:
|
|
# embed.add_field(name='Batting', value=batting_string, inline=False)
|
|
#
|
|
# baserunning_string = ''
|
|
# count = 1
|
|
# if len(final_sbs) > 0:
|
|
# baserunning_string += 'SB: '
|
|
#
|
|
# for x in final_sbs:
|
|
# player = await get_one_player(x[0])
|
|
# baserunning_string += f'{player["name"]}'
|
|
#
|
|
# if x[1] > 1:
|
|
# baserunning_string += f' {x[1]}'
|
|
#
|
|
# if count < len(final_sbs):
|
|
# baserunning_string += ', '
|
|
# else:
|
|
# baserunning_string += '\n'
|
|
# count += 1
|
|
#
|
|
# count = 1
|
|
# if len(final_cscs) > 0:
|
|
# baserunning_string += 'CSc: '
|
|
#
|
|
# for x in final_cscs:
|
|
# player = await get_one_player(x[0])
|
|
# baserunning_string += f'{player["name"]}'
|
|
#
|
|
# if x[1] > 1:
|
|
# baserunning_string += f' {x[1]}'
|
|
#
|
|
# if count < len(final_cscs):
|
|
# baserunning_string += ', '
|
|
# else:
|
|
# baserunning_string += '\n'
|
|
# count += 1
|
|
#
|
|
# if len(baserunning_string) > 0:
|
|
# embed.add_field(name='Baserunning', value=baserunning_string, inline=False)
|
|
|
|
embed.add_field(
|
|
name='Scorecard',
|
|
value=f'[Website]({card_url}) / [Sheets]({sheet_url})',
|
|
inline=False
|
|
)
|
|
embed.set_footer(text='Please share the highlights!')
|
|
|
|
await send_to_channel(
|
|
self.bot,
|
|
'sba-network-news',
|
|
content=None,
|
|
embed=embed
|
|
)
|
|
|
|
update = await interaction.channel.send('I\'m tallying standings now...')
|
|
if await db_post(f'standings/s{current["season"]}/recalculate', timeout=8):
|
|
await update.delete()
|
|
await interaction.edit_original_response(content='You are all set!')
|
|
|
|
# try:
|
|
# setup_tab.update_values(
|
|
# crange=f'B7',
|
|
# values=setup_vals
|
|
# )
|
|
# await interaction.edit_original_response(content='You are all set!')
|
|
# except Exception as e:
|
|
# logger.error(f'could not freeze sheet for game {this_game["id"]}')
|
|
# await interaction.edit_original_response(
|
|
# content='You didn\'t give me edit perms so I couldn\'t lock the rosters in your sheet, '
|
|
# 'but everything else went through.'
|
|
# )
|
|
|
|
@app_commands.command(name='branding', description='Update your team branding')
|
|
@app_commands.rename(
|
|
team_image_url='team_logo_url',
|
|
mil_team_image_url='minor_league_logo_url',
|
|
)
|
|
@app_commands.describe(
|
|
color_hex='Color hex code to use for your team',
|
|
team_image_url='URL ending in .png or .jpg of your team logo',
|
|
mil_color_hex='Color hex code to use for your minor league team',
|
|
mil_team_image_url='URL ending in .png or .jpg of your minor league team logo',
|
|
dice_color_hex='Color hex code to use for your dice rolls',
|
|
)
|
|
@app_commands.checks.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def branding_slash_command(
|
|
self, interaction: discord.Interaction, color_hex: str = None, team_image_url: str = None,
|
|
mil_color_hex: str = None, mil_team_image_url: str = None, mil_team_name: str = None,
|
|
dice_color_hex: str = None):
|
|
await interaction.response.defer()
|
|
current = await db_get('current')
|
|
team = await get_team_by_owner(current['season'], interaction.user.id)
|
|
mil_team = await get_team_by_abbrev(f'{team["abbrev"]}MiL', current['season'])
|
|
team_role = get_team_role(interaction, team)
|
|
errors = []
|
|
show_mil = False
|
|
show_dice = False
|
|
|
|
if not team or not team_role:
|
|
await interaction.edit_original_response(
|
|
content=f'Do you have a team here? You don\'t look familiar. {await get_emoji(interaction, "realeyes")}'
|
|
)
|
|
return
|
|
|
|
if color_hex is not None:
|
|
color_int = int(color_hex, 16)
|
|
try:
|
|
await team_role.edit(colour=color_int)
|
|
except Exception as e:
|
|
logger.info(f'Error setting {team["sname"]} color to {color_hex}')
|
|
errors.append(f'- Error setting {team["sname"]} color to {color_hex}:\n{e}\n\n')
|
|
team['color'] = color_hex
|
|
await db_patch('teams', object_id=team['id'], params=[('color', color_hex)])
|
|
if team_image_url is not None:
|
|
if requests.get(team_image_url, timeout=3).status_code != 200:
|
|
errors.append(f'- I wasn\'t able to pull that image. Was it a public URL?\n\n')
|
|
else:
|
|
team['thumbnail'] = team_image_url
|
|
await db_patch('teams', object_id=team['id'], params=[('thumbnail', team_image_url)])
|
|
if mil_color_hex is not None:
|
|
try:
|
|
await db_patch('teams', object_id=mil_team['id'], params=[('color', mil_color_hex)])
|
|
show_mil = True
|
|
except Exception as e:
|
|
logger.info(f'Error setting {team["sname"]} color to {mil_color_hex}')
|
|
errors.append(f'- Error setting {team["sname"]} color to {mil_color_hex}:\n{e}\n\n')
|
|
if mil_team_image_url is not None:
|
|
if requests.get(mil_team_image_url, timeout=3).status_code != 200:
|
|
errors.append(f'- I wasn\'t able to pull that image. Was it a public URL?\n\n')
|
|
else:
|
|
await db_patch('teams', object_id=mil_team['id'], params=[('thumbnail', mil_team_image_url)])
|
|
show_mil = True
|
|
if dice_color_hex is not None:
|
|
try:
|
|
await db_patch('teams', object_id=team['id'], params=[('dice_color', dice_color_hex)])
|
|
show_dice = True
|
|
except Exception as e:
|
|
logger.info(f'Error setting {team["sname"]} color to {color_hex}')
|
|
errors.append(f'- Error setting {team["sname"]} color to {color_hex}:\n{e}\n\n')
|
|
|
|
team = await db_get('teams', object_id=team['id'])
|
|
major_embed = get_team_embed(f'{team["lname"]} Test', team=team)
|
|
major_embed.add_field(
|
|
name='Little Test Data',
|
|
value='Run the command again if you want to change anything!'
|
|
)
|
|
embeds = [major_embed]
|
|
|
|
if show_mil:
|
|
mil_team = await db_get('teams', object_id=mil_team['id'])
|
|
mil_embed = get_team_embed(f'{mil_team["lname"]} Test', team=mil_team)
|
|
mil_embed.add_field(
|
|
name='Little Test Data',
|
|
value='Run the command again if you want to change anything!'
|
|
)
|
|
embeds.append(mil_embed)
|
|
|
|
if show_dice:
|
|
logger.info(f'entering show_dice')
|
|
team['color'] = team['dice_color']
|
|
dice_embed = get_team_embed(f'{team["lname"]} Dice Test', team=team)
|
|
logger.info(f'got base embed: {dice_embed}')
|
|
dice_embed.add_field(
|
|
name='Little Test Data',
|
|
value='This is what we\'ve got for your dice rolls!'
|
|
)
|
|
logger.info(f'done with embed: {dice_embed}')
|
|
embeds.append(dice_embed)
|
|
|
|
await interaction.edit_original_response(content=None, embeds=embeds)
|
|
|
|
@commands.command(name='picks', aliases=['mypicks', 'draftpicks'], help='See your picks')
|
|
async def picks_command(self, ctx, *team_abbrev):
|
|
await ctx.send('Go away.')
|
|
return
|
|
|
|
@commands.command(name='vc', aliases=['voice', 'gameplay'], help='Get voice channel')
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME, 'Paper Dynasty Players')
|
|
async def voice_channel_command(self, ctx):
|
|
prompt = 'Would you like to get a gameplay channel?'
|
|
this_q = Question(self.bot, ctx.channel, prompt, qtype='yesno', timeout=15)
|
|
resp = await this_q.ask([ctx.author])
|
|
|
|
if not resp:
|
|
await ctx.send('Fine. I bet they didn\'t wanna talk to you anyway.')
|
|
return
|
|
else:
|
|
overwrites = {ctx.guild.default_role: discord.PermissionOverwrite(speak=True)}
|
|
channel_name = f'Gameplay {random_codename()}'
|
|
this_vc = await ctx.guild.create_voice_channel(
|
|
channel_name,
|
|
overwrites=overwrites,
|
|
category=discord.utils.get(ctx.guild.categories, name=f'Voice Channels')
|
|
)
|
|
logger.info(f'Just created voice channel: {channel_name} for {ctx.author}')
|
|
self.voice_channels.append(this_vc)
|
|
|
|
await ctx.send(f'Just created {this_vc} for you!')
|
|
|
|
while True:
|
|
await asyncio.sleep(900)
|
|
if len(this_vc.members) == 0:
|
|
self.voice_channels.remove(this_vc)
|
|
try:
|
|
await this_vc.delete()
|
|
except Exception as e:
|
|
logger.error(f'could not delete {this_vc}.')
|
|
break
|
|
|
|
@commands.command(name='private', help='Get private vc')
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def private_vc_command(self, ctx):
|
|
current = await db_get('current')
|
|
this_team = await get_team_by_owner(current['season'], ctx.author.id)
|
|
|
|
async def get_other_team():
|
|
prompt = f'Please enter the abbrev of the team you are playing.'
|
|
this_q = Question(self.bot, ctx.channel, prompt, qtype='text', timeout=15)
|
|
resp = await this_q.ask([ctx.author])
|
|
|
|
if not resp:
|
|
await ctx.send('You keep thinking about it and hit me up later if you figure it out.')
|
|
return None
|
|
else:
|
|
other_team = await get_team_by_abbrev(resp, current['season'])
|
|
if not other_team:
|
|
await ctx.send(f'What\'s a **{resp}**? If you could go ahead and run this command again, that\'d '
|
|
f'be great.')
|
|
return None
|
|
else:
|
|
return other_team
|
|
|
|
if not this_team:
|
|
await ctx.send('Hmm...I can\'t find your team. Are you from around here?')
|
|
return
|
|
|
|
g_query = await db_get('games', params=[
|
|
('season', current['season']), ('week', current['week']), ('team1_id', this_team['id'])
|
|
])
|
|
if g_query['count'] == 0:
|
|
other_team = await get_other_team()
|
|
if not other_team:
|
|
await ctx.send(f'Idk who you are playing this week.')
|
|
channel_name = f'{this_team["abbrev"]} vs {other_team["abbrev"]} Muted'
|
|
else:
|
|
this_game = g_query['games'][0]
|
|
if this_team == this_game['away_team']:
|
|
other_team = this_game['home_team']
|
|
else:
|
|
other_team = this_game['away_team']
|
|
channel_name = f'{this_game["away_team"]["sname"]} @ {this_game["home_team"]["sname"]} Muted'
|
|
|
|
prompt = f'Would you like to get a private voice channel for {this_team["abbrev"]} and {other_team["abbrev"]}?'
|
|
this_q = Question(self.bot, ctx.channel, prompt, qtype='yesno', timeout=15)
|
|
resp = await this_q.ask([ctx.author])
|
|
|
|
if not resp:
|
|
await ctx.send('Fine. I bet they didn\'t wanna talk to you anyway.')
|
|
return
|
|
|
|
logger.info(f'getting roles')
|
|
this_team_role = discord.utils.get(ctx.guild.roles, name=f'{this_team["lname"]}')
|
|
other_team_role = discord.utils.get(ctx.guild.roles, name=f'{other_team["lname"]}')
|
|
|
|
if None in [this_team_role, other_team_role]:
|
|
await ctx.send(f'Tell Cal that we\'re missing a team role to create this channel.')
|
|
return
|
|
|
|
logger.info(f'getting overwrites')
|
|
overwrites = {ctx.guild.default_role: discord.PermissionOverwrite(speak=False),
|
|
this_team_role: discord.PermissionOverwrite(speak=True),
|
|
other_team_role: discord.PermissionOverwrite(speak=True)}
|
|
logger.info(f'creating channel')
|
|
this_vc = await ctx.guild.create_voice_channel(
|
|
channel_name,
|
|
overwrites=overwrites,
|
|
category=discord.utils.get(ctx.guild.categories, name=f'Voice Channels')
|
|
)
|
|
self.voice_channels.append(this_vc)
|
|
|
|
await ctx.send(f'Just created {this_vc} for you!')
|
|
|
|
while True:
|
|
await asyncio.sleep(900)
|
|
if len(this_vc.members) == 0:
|
|
self.voice_channels.remove(this_vc)
|
|
try:
|
|
await this_vc.delete()
|
|
except Exception as e:
|
|
logger.error(f'could not delete {this_vc}.')
|
|
break
|
|
|
|
@commands.command(name='headshot', aliases=['hs'], help='Set headshot pic')
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def headshot_command(self, ctx, url, *, player_name):
|
|
if ctx.channel.name == 'season-6-chat':
|
|
await ctx.send('Not in season 6 chat, dumbass.')
|
|
return
|
|
|
|
current = await db_get('current')
|
|
this_team = await get_team_by_owner(current['season'], ctx.author.id)
|
|
|
|
if not this_team:
|
|
await ctx.send('Hmm...I can\'t find your team. Are you from around here?')
|
|
return
|
|
|
|
p_name = await fuzzy_player_search(
|
|
ctx, ctx.channel, self.bot, player_name, self.player_list.keys(), author=ctx.author
|
|
)
|
|
player = await get_player_by_name(current['season'], p_name)
|
|
if player is None:
|
|
await ctx.send(random_gif('it didn\'t work'))
|
|
return
|
|
|
|
player_embed = await get_player_embed(player, current)
|
|
player_embed.set_thumbnail(url=url)
|
|
prompt = 'Would you like to save this image?'
|
|
this_q = Question(self.bot, ctx.channel, prompt, 'yesno', 15, player_embed)
|
|
resp = await this_q.ask([ctx.author])
|
|
|
|
if not resp:
|
|
await ctx.send('That\'s okay. It wasn\'t a very good picture anyway.')
|
|
return
|
|
else:
|
|
player['headshot'] = url
|
|
await put_player(player)
|
|
await ctx.send(random_conf_word())
|
|
|
|
@commands.command(name='fancycard', aliases=['fc'], help='Set vanity card')
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def vanity_card_command(self, ctx, url, *, player_name):
|
|
if ctx.channel.name == 'season-6-chat':
|
|
await ctx.send('Not in season 6 chat, dumbass.')
|
|
return
|
|
|
|
current = await db_get('current')
|
|
this_team = await get_team_by_owner(current['season'], ctx.author.id)
|
|
|
|
if not this_team:
|
|
await ctx.send('Hmm...I can\'t find your team. Are you from around here?')
|
|
return
|
|
|
|
p_name = await fuzzy_player_search(
|
|
ctx, ctx.channel, self.bot, player_name, self.player_list.keys(), author=ctx.author
|
|
)
|
|
player = await get_player_by_name(current['season'], p_name)
|
|
if player is None:
|
|
await ctx.send(random_gif('it didn\'t work'))
|
|
return
|
|
|
|
player_embed = await get_player_embed(player, current)
|
|
player_embed.set_thumbnail(url=url)
|
|
prompt = 'Would you like to save this image?'
|
|
this_q = Question(self.bot, ctx.channel, prompt, 'yesno', 15, player_embed)
|
|
resp = await this_q.ask([ctx.author])
|
|
|
|
if not resp:
|
|
await ctx.send('That\'s okay. It wasn\'t a very good picture anyway.')
|
|
return
|
|
else:
|
|
player['vanity_card'] = url
|
|
await put_player(player)
|
|
await ctx.send(random_conf_word())
|
|
|
|
@commands.command(name='getfc', help='Get last season vanity card')
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def get_vanity_card_command(self, ctx, *, player_name):
|
|
if ctx.channel.name == 'season-5-chat':
|
|
await ctx.send('Not in season 5 chat, dumbass.')
|
|
return
|
|
|
|
current = await db_get('current')
|
|
this_team = await get_team_by_owner(current['season'], ctx.author.id)
|
|
|
|
if not this_team:
|
|
await ctx.send('Hmm...I can\'t find your team. Are you from around here?')
|
|
return
|
|
|
|
p_name = await fuzzy_player_search(
|
|
ctx, ctx.channel, self.bot, player_name, self.player_list.keys(), author=ctx.author
|
|
)
|
|
player = await get_player_by_name(current['season'], p_name)
|
|
|
|
p_query = await db_get('players', params=[('season', current['season'] - 1), ('name', p_name)])
|
|
if p_query['count'] == 0:
|
|
await ctx.send(f'I could not find **{p_name}** from Season {current["season"] - 1}')
|
|
return
|
|
|
|
player['vanity_card'] = p_query['players'][0]['vanity_card']
|
|
await put_player(player)
|
|
|
|
player_embed = await get_player_embed(player, current)
|
|
await ctx.send(content=None, embed=player_embed)
|
|
|
|
@app_commands.command(name='charts')
|
|
async def chart_command(self, interaction: discord.Interaction, chart_name: Literal[
|
|
'block-plate', 'defense-matters', 'fly-b', 'g1', 'g2', 'g3', 'groundball', 'hit-and-run',
|
|
'rest', 'rob-hr', 'sac-bunt', 'squeeze-bunt']):
|
|
gb_url = 'https://sombaseball.ddns.net/static/images/season04/ground-ball-chart'
|
|
all_charts = {
|
|
'rest': [f'{SBA_IMAGE_URL}/season05/charts/rest.png'],
|
|
'sac-bunt': [
|
|
f'{SBA_IMAGE_URL}/season05/charts/sac-bunt.png',
|
|
f'{SBA_IMAGE_URL}/season05/charts/sac-bunt-help.png'
|
|
],
|
|
'squeeze-bunt': [
|
|
f'{SBA_IMAGE_URL}/season05/charts/squeeze-bunt.png',
|
|
f'{SBA_IMAGE_URL}/season05/charts/squeeze-bunt-help.png'
|
|
],
|
|
'rob-hr': [f'{SBA_IMAGE_URL}/season05/charts/rob-hr.png'],
|
|
'defense-matters': [f'{SBA_IMAGE_URL}/season05/charts/defense-matters.png'],
|
|
'block-plate': [f'{SBA_IMAGE_URL}/season05/charts/block-plate.png'],
|
|
'hit-and-run': [
|
|
f'{SBA_IMAGE_URL}/season05/charts/hit-and-run.png',
|
|
f'{SBA_IMAGE_URL}/season05/charts/hit-and-run-pitcher.png'
|
|
],
|
|
'g1': [f'{gb_url}-g1.png', f'{gb_url}01.png', f'{gb_url}02.png'],
|
|
'g2': [f'{gb_url}-g2.png', f'{gb_url}01.png', f'{gb_url}02.png'],
|
|
'g3': [f'{gb_url}-g3.png', f'{gb_url}01.png', f'{gb_url}02.png'],
|
|
'groundball': [f'{gb_url}01.png', f'{gb_url}02.png'],
|
|
'fly-b': [f'https://i.postimg.cc/CMfZPwPC/flyball-b.png']
|
|
}
|
|
|
|
first = True
|
|
for link in all_charts[chart_name]:
|
|
if first:
|
|
await interaction.response.send_message(link)
|
|
first = False
|
|
else:
|
|
await interaction.followup.send(link)
|
|
|
|
@commands.command(name='pitcherbatting', aliases=['pbat', 'pitbat'], help='Show specific pitcher batting card')
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME, PD_PLAYERS_ROLE_NAME)
|
|
async def pitcher_batting_command(self, ctx: commands.Context, card_num: int = 1):
|
|
if card_num > 8:
|
|
await ctx.send(f'I only have pitcher batting cards 1 through 8. Why don\'t you try again.')
|
|
return
|
|
if card_num < 1:
|
|
await ctx.send(f'I only have pitcher batting cards 1 through 8. Why don\'t you try again.')
|
|
return
|
|
|
|
team = await get_team_by_owner(SBA_SEASON, ctx.author.id)
|
|
embed = get_team_embed(f'Pitcher Batting Card #{card_num}', team=team, thumbnail=False)
|
|
embed.set_image(url=f'{SBA_BASE_URL}/static/images/pitbat/card-{card_num}.png')
|
|
await ctx.send(content=None, embed=embed)
|
|
|
|
# @app_commands.command(name='keepers', description='Mod: Set team keepers')
|
|
# @app_commands.checks.has_any_role('Da Commish')
|
|
# async def set_keepers_slash(
|
|
# self, interaction: discord.Interaction, team_abbrev: str, keep1: str = None, keep2: str = None,
|
|
# keep3: str = None, keep4: str = None, keep5: str = None, keep6: str = None, keep7: str = None):
|
|
# await interaction.response.defer()
|
|
# current = await db_get('current')
|
|
# team = await get_team_by_abbrev(team_abbrev, current['season'])
|
|
#
|
|
# keepers = []
|
|
# keeper_string = ''
|
|
# keeper_swar = 0
|
|
#
|
|
# def get_pos_abbrev(position):
|
|
# if 'B' in position:
|
|
# return 'IF'
|
|
# if 'F' in position:
|
|
# return 'OF'
|
|
# if 'P' in position:
|
|
# return 'P'
|
|
# if position == 'C':
|
|
# return 'C'
|
|
# return 'DH'
|
|
#
|
|
# for x in [keep1, keep2, keep3, keep4, keep5, keep6, keep7]:
|
|
# if x:
|
|
# p_name = await fuzzy_player_search(
|
|
# interaction, interaction.channel, self.bot, x, self.player_list.keys(), author=interaction.user
|
|
# )
|
|
# this_p = await get_player_by_name(current['season'], p_name)
|
|
# keepers.append(this_p)
|
|
# keeper_string += f'{get_pos_abbrev(this_p["pos_1"])} - {this_p["name"]} ({this_p["wara"]:.2f})\n'
|
|
# keeper_swar += this_p['wara']
|
|
#
|
|
# await interaction.response.send_message(content=f'{team["sname"]} Keepers:\n{keeper_string}')
|
|
# all_players = await db_get('players', api_ver=3, params=[('team_abbrev', team['abbrev'])])
|
|
# logger.info(f'all_players: {all_players}')
|
|
#
|
|
# fa = await get_team_by_abbrev('FA', current['season'])
|
|
# for y in all_players['players']:
|
|
# if y not in keepers:
|
|
# y['team'] = fa
|
|
# await patch_player(y)
|
|
#
|
|
# await interaction.channel.send(
|
|
# f'Just yeeted **{len(all_players["players"]) - len(keepers)}** players into the sun!'
|
|
# )
|
|
#
|
|
# embed = get_team_embed(title=f'{team["lname"]} Keepers', team=team)
|
|
# embed.add_field(name=f'Keepers', value=keeper_string)
|
|
# embed.add_field(name='Total sWAR', value=f'{keeper_swar:.2f}')
|
|
#
|
|
# await send_to_channel(self.bot, 'sba-network-news', content=None, embed=embed)
|
|
|
|
group_publish = app_commands.Group(name='publish', description='Make a scorecard publicly accessible')
|
|
|
|
@group_publish.command(name='josef')
|
|
@app_commands.describe(sheet_url='The full URL of your publicly shared scorecard')
|
|
async def pub_josef_slash(self, interaction: discord.Interaction, sheet_url: str):
|
|
sheets = pygsheets.authorize(service_file='storage/major-domo-service-creds.json')
|
|
|
|
try:
|
|
if 'https://' in sheet_url:
|
|
scorecard = sheets.open_by_url(sheet_url).worksheet_by_title('Scorebug')
|
|
else:
|
|
scorecard = sheets.open_by_key(sheet_url).worksheet_by_title('Scorebug')
|
|
except Exception as e:
|
|
await interaction.response.send_message(
|
|
'Frick. I wasn\'t able to publish that card. Is that card ID correct?'
|
|
)
|
|
return
|
|
|
|
self.scorecards[f'{interaction.channel_id}'] = scorecard
|
|
await interaction.response.send_message(
|
|
f'Your scorecard has been published. Anyone may now run `/scorebug` in '
|
|
f'this channel to get the scorebug.')
|
|
|
|
@app_commands.command(name='scorebug', description='Pull the scorebug for the game in this channel')
|
|
@app_commands.describe(full_length='Include the full game summary, defaults to True')
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME, PD_PLAYERS_ROLE_NAME)
|
|
async def scorebug_slash(self, interaction: discord.Interaction, full_length: bool = True):
|
|
if not self.scorecards:
|
|
await interaction.response.send_message(
|
|
'Uhh...I don\'t see any games in this channel. You in the right place?'
|
|
)
|
|
return
|
|
|
|
this_scorecard = self.scorecards[f'{interaction.channel_id}']
|
|
if not this_scorecard:
|
|
await interaction.response.send_message(
|
|
'Uhh...I don\'t see any games in this channel. You in the right place?'
|
|
)
|
|
return
|
|
|
|
await interaction.response.send_message(f'I am checking sheets now...', ephemeral=True)
|
|
|
|
logger.info(f'scorebug_slash: full_length: {full_length}')
|
|
try:
|
|
game_embed = await self.game_scorebug(this_scorecard, full_length=full_length)
|
|
await interaction.edit_original_response(content=None, embed=game_embed)
|
|
except Exception as e:
|
|
logger.error(e)
|
|
await interaction.edit_original_response(
|
|
content='I was not able to generate a scorebug for this game'
|
|
)
|
|
|
|
@app_commands.command(name='injury', description='Make an injury check; rating = left of "p", games = right')
|
|
# @app_commands.guilds(discord.Object(id=os.environ.get('GUILD_ID')))
|
|
@app_commands.choices(games=[
|
|
Choice(name='70', value=70),
|
|
Choice(name='65', value=65),
|
|
Choice(name='60', value=60),
|
|
Choice(name='50', value=50),
|
|
Choice(name='40', value=40),
|
|
Choice(name='30', value=30),
|
|
Choice(name='20', value=20),
|
|
], rating=[
|
|
Choice(name='1', value=1),
|
|
Choice(name='2', value=2),
|
|
Choice(name='3', value=3),
|
|
Choice(name='4', value=4),
|
|
Choice(name='5', value=5),
|
|
Choice(name='6', value=6),
|
|
])
|
|
async def injury_roll_slash(self, interaction: discord.Interaction, rating: Choice[int], games: Choice[int]):
|
|
team = None
|
|
if interaction.guild_id != 613880856032968834:
|
|
await interaction.response.send_message(f'This must be run in the SBa server.')
|
|
return
|
|
await interaction.response.defer()
|
|
|
|
d_six_one = random.randint(1, 6)
|
|
d_six_two = random.randint(1, 6)
|
|
d_six_three = random.randint(1, 6)
|
|
injury_roll = d_six_one + d_six_two + d_six_three
|
|
|
|
inj_data = {
|
|
'one': {
|
|
'p70': ['OK', 'OK', 'OK', 'OK', 'OK', 'OK', 'REM', 'REM', 1, 1, 2, 2, 3, 3, 4, 4],
|
|
'p65': [2, 2, 'OK', 'REM', 1, 2, 3, 3, 4, 4, 4, 4, 5, 6, 8, 12],
|
|
'p60': ['OK', 'OK', 'REM', 1, 2, 3, 4, 4, 4, 5, 5, 6, 8, 12, 16, 16],
|
|
'p50': ['OK', 'REM', 1, 2, 3, 4, 4, 5, 5, 6, 8, 8, 12, 16, 16, 'OK'],
|
|
'p40': ['OK', 1, 2, 3, 4, 4, 5, 6, 6, 8, 8, 12, 16, 24, 'REM', 'OK'],
|
|
'p30': ['OK', 4, 1, 3, 4, 5, 6, 8, 8, 12, 16, 24, 4, 2, 'REM', 'OK'],
|
|
'p20': ['OK', 1, 2, 4, 5, 8, 8, 24, 16, 12, 12, 6, 4, 3, 'REM', 'OK']
|
|
},
|
|
'two': {
|
|
'p70': [4, 3, 2, 2, 1, 1, 'REM', 'OK', 'REM', 'OK', 2, 1, 2, 2, 3, 4],
|
|
'p65': [8, 5, 4, 2, 2, 'OK', 1, 'OK', 'REM', 1, 'REM', 2, 3, 4, 6, 12],
|
|
'p60': [1, 3, 4, 5, 2, 2, 'OK', 1, 3, 'REM', 4, 4, 6, 8, 12, 3],
|
|
'p50': [4, 'OK', 'OK', 'REM', 1, 2, 4, 3, 4, 5, 4, 6, 8, 12, 12, 'OK'],
|
|
'p40': ['OK', 'OK', 'REM', 1, 2, 3, 4, 4, 5, 4, 6, 8, 12, 16, 16, 'OK'],
|
|
'p30': ['OK', 'REM', 1, 2, 3, 4, 4, 5, 6, 5, 8, 12, 16, 24, 'REM', 'OK'],
|
|
'p20': ['OK', 1, 4, 4, 5, 5, 6, 6, 12, 8, 16, 24, 8, 3, 2, 'REM']
|
|
},
|
|
'three': {
|
|
'p70': [],
|
|
'p65': ['OK', 'OK', 'REM', 1, 3, 'OK', 'REM', 1, 2, 1, 2, 3, 4, 4, 5, 'REM'],
|
|
'p60': ['OK', 5, 'OK', 'REM', 1, 2, 2, 3, 4, 4, 1, 3, 5, 6, 8, 'REM'],
|
|
'p50': ['OK', 'OK', 'REM', 1, 2, 3, 4, 4, 5, 4, 4, 6, 8, 8, 12, 'REM'],
|
|
'p40': ['OK', 1, 1, 2, 3, 4, 4, 5, 6, 5, 6, 8, 8, 12, 4, 'REM'],
|
|
'p30': ['OK', 1, 2, 3, 4, 5, 4, 6, 5, 6, 8, 8, 12, 16, 1, 'REM'],
|
|
'p20': ['OK', 1, 2, 4, 4, 8, 8, 6, 5, 12, 6, 16, 24, 3, 4, 'REM']
|
|
},
|
|
'four': {
|
|
'p70': [],
|
|
'p65': [],
|
|
'p60': ['OK', 'OK', 'REM', 3, 3, 'OK', 'REM', 1, 2, 1, 4, 4, 5, 6, 8, 'REM'],
|
|
'p50': ['OK', 6, 4, 'OK', 'REM', 1, 2, 4, 4, 3, 5, 3, 6, 8, 12, 'REM'],
|
|
'p40': ['OK', 'OK', 'REM', 1, 2, 3, 4, 4, 5, 4, 4, 6, 8, 8, 12, 'REM'],
|
|
'p30': ['OK', 1, 1, 2, 3, 4, 4, 5, 6, 5, 6, 8, 8, 12, 4, 'REM'],
|
|
'p20': ['OK', 1, 2, 3, 4, 5, 4, 6, 5, 6, 12, 8, 8, 16, 1, 'REM']
|
|
},
|
|
'five': {
|
|
'p70': [],
|
|
'p65': [],
|
|
'p60': ['OK', 'REM', 'REM', 'REM', 3, 'OK', 1, 'REM', 2, 1, 'OK', 4, 5, 2, 6, 8],
|
|
'p50': ['OK', 'OK', 'REM', 1, 1, 'OK', 'REM', 3, 2, 4, 4, 5, 5, 6, 8, 12],
|
|
'p40': ['OK', 6, 6, 'OK', 1, 3, 2, 4, 4, 5, 'REM', 3, 8, 6, 12, 1],
|
|
'p30': ['OK', 'OK', 'REM', 4, 1, 2, 5, 4, 6, 3, 4, 8, 5, 6, 12, 'REM'],
|
|
'p20': ['OK', 'REM', 2, 3, 4, 4, 5, 4, 6, 5, 8, 6, 8, 1, 12, 'REM']
|
|
},
|
|
'six': {
|
|
'p70': [],
|
|
'p65': [],
|
|
'p60': [],
|
|
'p50': [],
|
|
'p40': ['OK', 6, 6, 'OK', 1, 3, 2, 4, 4, 5, 'REM', 3, 8, 6, 1, 12],
|
|
'p30': ['OK', 'OK', 'REM', 5, 1, 3, 6, 4, 5, 2, 4, 8, 3, 5, 12, 'REM'],
|
|
'p20': ['OK', 'REM', 4, 6, 2, 3, 6, 4, 8, 5, 5, 6, 3, 1, 12, 'REM']
|
|
}
|
|
}
|
|
p_ratings = ['one', 'two', 'three', 'four', 'five', 'six']
|
|
|
|
injury_string = f'```md\n# {injury_roll}\n' \
|
|
f'Details:[3d6 ({d_six_one} {d_six_two} {d_six_three})]\n```\n'
|
|
|
|
logger.info(f'injury rating: {rating.value}p{games.value}')
|
|
|
|
injury_list = inj_data[p_ratings[rating.value - 1]][f'p{games.value}']
|
|
injury_result = injury_list[injury_roll - 3]
|
|
logger.info(f'injury rating: {rating.value}p{games.value} / array: {injury_list}[{injury_roll - 2}] / result: {injury_result}')
|
|
|
|
if isinstance(injury_result, int):
|
|
try:
|
|
await interaction.edit_original_response(
|
|
content=random_gif(random_from_list(['salute', 'press f', 'pay respects', 'well shit']))
|
|
)
|
|
except Exception as e:
|
|
logger.info(f'failed to post funny gif')
|
|
injury_string += f'With a roll of {injury_roll}, the injury length is **{injury_result} ' \
|
|
f'game{"s" if injury_result > 1 else ""}**.'
|
|
elif injury_result == 'REM':
|
|
try:
|
|
await interaction.edit_original_response(
|
|
content=random_gif(random_from_list(['could be worse', 'not too bad']))
|
|
)
|
|
except Exception as e:
|
|
logger.info(f'failed to post funny gif')
|
|
injury_string += f'With a roll of {injury_roll}, the injury length is **REMAINDER OF GAME** for batters ' \
|
|
f'or **FATIGUED** for pitchers'
|
|
else:
|
|
try:
|
|
await interaction.edit_original_response(
|
|
content=random_gif(random_from_list(['it is fine', 'nothing to see here', 'i wasn\'t worried']))
|
|
)
|
|
except Exception as e:
|
|
logger.info(f'failed to post funny gif')
|
|
injury_string += f'With a roll of {injury_roll}, the player is **OKAY** - no injury!'
|
|
|
|
embed = await self.get_dice_embed(
|
|
interaction.channel.name,
|
|
f'Injury roll for {interaction.user.name}',
|
|
injury_string
|
|
)
|
|
embed.set_footer(text='For pitchers, add their current rest to the injury')
|
|
|
|
await interaction.channel.send(content=None, embed=embed)
|
|
|
|
# this_roll = {
|
|
# 'season': self.current['season'],
|
|
# 'week': self.current['week'],
|
|
# 'team_id': team["id"] if team else None,
|
|
# 'roller': interaction.user.id,
|
|
# 'threedsix': d_six_one + d_six_two + d_six_three
|
|
# }
|
|
# self.rolls.append(this_roll)
|
|
|
|
group_running_calcs = app_commands.Group(
|
|
name='running-calcs',
|
|
description='Let Domo do the math for your runner advancement'
|
|
)
|
|
|
|
@group_running_calcs.command(name='fly-b', description='Tag play from second base')
|
|
@app_commands.rename(
|
|
this_of='which-outfielder',
|
|
speed='runner-speed',
|
|
arm='outfielder-arm'
|
|
)
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME, PD_PLAYERS_ROLE_NAME)
|
|
async def running_calcs_flyb(
|
|
self, interaction: discord.Interaction, this_of: Literal['LF', 'CF', 'RF'], speed: int, arm: int):
|
|
await interaction.response.defer()
|
|
|
|
max_safe = speed + arm
|
|
min_out = 20 + arm
|
|
if this_of == 'RF':
|
|
max_safe += 2
|
|
min_out += 2
|
|
elif this_of == 'LF':
|
|
max_safe -= 2
|
|
min_out -= 2
|
|
|
|
if max_safe >= 20:
|
|
max_safe = 19
|
|
min_out = 21
|
|
|
|
safe_range = f'1'
|
|
if max_safe > 1:
|
|
safe_range += f' - {max_safe}'
|
|
|
|
out_range = 'None'
|
|
if min_out <= 20:
|
|
out_range = f'{min_out}'
|
|
if min_out < 20:
|
|
out_range += ' - 20'
|
|
|
|
if max_safe >= 20:
|
|
hold_range = '20'
|
|
elif (max_safe + 1) < min_out:
|
|
hold_range = f'{max_safe + 1}'
|
|
if (max_safe + 2) < min_out:
|
|
hold_range += f' - {min_out - 1}'
|
|
else:
|
|
hold_range = 'None'
|
|
|
|
tag_embed = get_team_embed('Flyball B Running')
|
|
tag_embed.add_field(name='Safe Range', value=safe_range)
|
|
tag_embed.add_field(name='Hold Range', value=hold_range)
|
|
tag_embed.add_field(name='Out Range', value=out_range)
|
|
|
|
await interaction.edit_original_response(content=None, embed=tag_embed)
|
|
|
|
def play_at_home(self, speed: int, arm: int):
|
|
max_safe = speed + arm
|
|
|
|
safe_range = f'1'
|
|
if max_safe >= 19:
|
|
safe_range += ' - 18'
|
|
catcher_range = '19 - 20'
|
|
out_range = 'None'
|
|
elif max_safe == 18:
|
|
safe_range += ' - 17'
|
|
catcher_range = '18 - 19'
|
|
out_range = '20'
|
|
elif max_safe > 2:
|
|
safe_range += f' - {max_safe - 1}'
|
|
catcher_range = f'{max_safe} - {max_safe + 1}'
|
|
out_range = f'{max_safe + 2} - 20'
|
|
elif max_safe == 2:
|
|
safe_range = '1'
|
|
catcher_range = f'2 - 3'
|
|
out_range = '4 - 20'
|
|
else:
|
|
safe_range = 'None'
|
|
catcher_range = f'1 - 2'
|
|
out_range = '3 - 20'
|
|
|
|
return {
|
|
'safe_range': safe_range,
|
|
'catcher_range': catcher_range,
|
|
'out_range': out_range
|
|
}
|
|
|
|
@group_running_calcs.command(name='fly-bq', description='Tag play from third base')
|
|
@app_commands.rename(
|
|
speed='runner-speed',
|
|
arm='outfielder-arm'
|
|
)
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME, PD_PLAYERS_ROLE_NAME)
|
|
async def running_calcs_flybq(
|
|
self, interaction: discord.Interaction, speed: int, arm: int):
|
|
await interaction.response.defer()
|
|
|
|
data = self.play_at_home(speed + 2, arm)
|
|
|
|
tag_embed = get_team_embed('Flyball B? Running')
|
|
tag_embed.add_field(name='Safe Range', value=data['safe_range'])
|
|
tag_embed.add_field(name='Block Plate Range', value=data['catcher_range'])
|
|
tag_embed.add_field(name='Out Range', value=data['out_range'])
|
|
|
|
await interaction.edit_original_response(content=None, embed=tag_embed)
|
|
|
|
@group_running_calcs.command(name='advance', description='Runner advancing on uncapped hit')
|
|
@app_commands.rename(
|
|
this_of='which-outfielder',
|
|
speed='runner-speed',
|
|
arm='outfielder-arm',
|
|
outs='starting-outs',
|
|
held='was-runner-held'
|
|
)
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME, PD_PLAYERS_ROLE_NAME)
|
|
async def running_calcs_advance(
|
|
self, interaction: discord.Interaction, this_of: Literal['LF', 'CF', 'RF'], speed: int, arm: int,
|
|
play_type: Literal['lead-runner', 'cutoff-play'],
|
|
to_base: Literal['Second Base', 'Third Base', 'Home Plate', 'Fifth Base'], outs: int, held: bool = False):
|
|
if to_base == 'Fifth Base':
|
|
await interaction.response.send_message(content=random_gif('why are you like this'))
|
|
return
|
|
|
|
await interaction.response.defer()
|
|
|
|
if to_base == 'Home Plate':
|
|
if outs == 2:
|
|
speed += 2
|
|
|
|
if not held:
|
|
speed += 1
|
|
elif held:
|
|
speed -= 1
|
|
|
|
data = self.play_at_home(speed, arm)
|
|
|
|
tag_embed = get_team_embed('Play at the Plate')
|
|
tag_embed.add_field(name='Safe Range', value=data['safe_range'])
|
|
tag_embed.add_field(name='Block Plate Range', value=data['catcher_range'])
|
|
tag_embed.add_field(name='Out Range', value=data['out_range'])
|
|
|
|
await interaction.edit_original_response(content=None, embed=tag_embed)
|
|
return
|
|
|
|
max_safe = speed + arm
|
|
if to_base == 'Third Base' and this_of == 'RF':
|
|
max_safe += 2
|
|
elif to_base == 'Third Base' and this_of == 'LF':
|
|
max_safe -= 2
|
|
|
|
if play_type == 'cutoff-play':
|
|
max_safe -= 5
|
|
elif play_type == 'lead-runner':
|
|
if outs == 2:
|
|
max_safe += 2
|
|
|
|
if not held:
|
|
max_safe += 1
|
|
elif held:
|
|
max_safe -= 1
|
|
|
|
if max_safe > 20:
|
|
max_safe = 19
|
|
elif max_safe < 1:
|
|
max_safe = 1
|
|
|
|
if max_safe == 20:
|
|
safe_range = '1 - 20'
|
|
out_range = 'None'
|
|
elif max_safe == 19:
|
|
safe_range = f'1 - 19'
|
|
out_range = '20'
|
|
elif max_safe == 1:
|
|
safe_range = '1'
|
|
out_range = '2 - 20'
|
|
else:
|
|
safe_range = f'1 - {max_safe}'
|
|
out_range = f'{max_safe + 1} - 20'
|
|
|
|
run_embed = get_team_embed(f'Play at {to_base}')
|
|
run_embed.add_field(name='Safe Range', value=safe_range)
|
|
run_embed.add_field(name='Out Range', value=out_range)
|
|
await interaction.edit_original_response(content=None, embed=run_embed)
|
|
|
|
|
|
@app_commands.command(name='sba-update-player', description='Crowd-sourcing player updates')
|
|
# @app_commands.guilds(discord.Object(id=os.environ.get('GUILD_ID')))
|
|
async def update_player_slash(
|
|
self, interaction: discord.Interaction, player_id: int, swar: Optional[float] = None,
|
|
injury_rating: Optional[str] = None, bbref_id: Optional[str] = None, strat_code: Optional[str] = None,
|
|
team_abbrev: Optional[str] = None):
|
|
if interaction.guild_id != 613880856032968834:
|
|
await interaction.response.send_message(f'This must be run in the SBa server.')
|
|
return
|
|
|
|
await interaction.response.defer()
|
|
|
|
current = await db_get('current')
|
|
new_season = 10
|
|
this_team = await get_team_by_owner(current['season'], interaction.user.id)
|
|
|
|
if not this_team:
|
|
await interaction.edit_original_response(content='Hmm...I can\'t find your team. Are you from around here?')
|
|
return
|
|
|
|
if interaction.user.id == 291738770313707521:
|
|
await interaction.edit_original_response(
|
|
content=random_gif(random.choices(['no', 'go away', 'please leave', 'why are you like this']))
|
|
)
|
|
return
|
|
|
|
this_player = await db_get('players', object_id=player_id)
|
|
if this_player is None:
|
|
await interaction.edit_original_response(
|
|
content=f'I do not know who Player ID **{player_id}** is.'
|
|
)
|
|
return
|
|
|
|
update_string = ''
|
|
if swar is not None:
|
|
update_string += f'sWAR: {this_player["wara"]} => {swar}\n'
|
|
this_player['wara'] = swar
|
|
if injury_rating is not None:
|
|
update_string += f'injury_rating: {this_player["injury_rating"]} => {injury_rating}\n'
|
|
this_player['injury_rating'] = injury_rating
|
|
if bbref_id is not None:
|
|
update_string += f'bbref_id: {this_player["bbref_id"]} => {bbref_id}\n'
|
|
this_player['bbref_id'] = bbref_id
|
|
if strat_code is not None:
|
|
update_string += f'strat_code: {this_player["strat_code"]} => {strat_code}\n'
|
|
this_player['strat_code'] = strat_code
|
|
if team_abbrev is not None:
|
|
new_team = await get_team_by_abbrev(team_abbrev, new_season)
|
|
if new_team is None:
|
|
await interaction.channel.send(
|
|
f'I could not find a team with abbrev **{team_abbrev}** for season {new_season}, ignoring team update'
|
|
)
|
|
return
|
|
update_string += f'team_abbrev: {this_player["team"]["abbrev"]} => {team_abbrev}\n'
|
|
this_player['team'] = new_team
|
|
|
|
if len(update_string) == 0:
|
|
await interaction.edit_original_response(
|
|
content='Hm. Well I guess it\'s the thought that counts. Maybe next time.'
|
|
)
|
|
return
|
|
|
|
p_embed = await get_player_embed(this_player, current, interaction, new_season)
|
|
p_embed.add_field(name='BBRef ID', value=bbref_id)
|
|
|
|
view = Confirm(responders=[interaction.user])
|
|
await interaction.edit_original_response(
|
|
content=f'Here are the updates - should I commit these?',
|
|
embed=p_embed,
|
|
view=view
|
|
)
|
|
await view.wait()
|
|
|
|
if view.value:
|
|
if await put_player(this_player) is not None:
|
|
await interaction.edit_original_response(
|
|
content=f'{this_player["name"]} has been updated',
|
|
embed=p_embed,
|
|
view=None
|
|
)
|
|
await send_to_channel(
|
|
self.bot,
|
|
'transaction-log',
|
|
f'{interaction.user.mention} updated {this_player["name"]}:\n{update_string}'
|
|
)
|
|
else:
|
|
await interaction.edit_original_response(
|
|
content=f'Hm. Well I guess it\'s the thought that counts. Maybe next time.',
|
|
embed=None,
|
|
view=None
|
|
)
|
|
|
|
|
|
async def setup(bot):
|
|
await bot.add_cog(Players(bot))
|