major-domo-legacy/cogs/players.py
2023-07-24 23:40:50 -05:00

2229 lines
102 KiB
Python

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, patch_player, get_player_by_name, db_post
from typing import Literal
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.build_master_player_list.start()
# 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:
logging.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
@tasks.loop(count=1)
async def build_master_player_list(self):
guild = self.bot.get_guild(int(os.environ.get('GUILD_ID')))
if not guild:
logging.error(f'build_master_player_list - could not pull guild / retrying in 15 seconds')
await asyncio.sleep(15)
guild = self.bot.get_guild(int(os.environ.get('GUILD_ID')))
logging.info(f'build_master_player_list - guild: {guild}')
logging.info(f'build_master_player_list - getting current')
current = await db_get('current')
logging.info(f'build_master_player_list - getting all_players')
p_query = await db_get('players', timeout=8, params=[('season', current['season'])])
logging.info(f'build_master_player_list - building player_list')
self.player_list = {x['name'].lower(): x['id'] for x in p_query['players']}
logging.info(f'player list count: {len(self.player_list)}')
logging.debug(f'player list: {self.player_list}')
@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 = {}
all_injuries = await db_get('players', params=[
('season', current['season']), ('is_injured', True)
])
for x in all_injuries:
player = all_injuries[x]
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 {player["il_return"][1:3]}' not in inj_week.keys():
inj_week[f'Week {player["il_return"][1:3]}'] = [player]
else:
inj_week[f'Week {player["il_return"][1:3]}'].append(player)
inj_by_team = dict(sorted(inj_team.items()))
inj_by_week = dict(sorted(inj_week.items()))
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:
team_string = ''
for player in inj_by_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:
week_string = ''
for player in inj_by_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"] < 0:
gb = stan["div_gb"] if stan["div_gb"] >= 0.0 else f'+{stan["div_gb"] * -1}'
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'+{stan["wc_gb"] * -1}'
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: >5} {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'])
])
game_count = 0
for x in s_query['schedules']:
game_count += x['gamecount']
return {'games_played': r_query['count'], 'game_count': game_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 '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':
# logging.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('standings', params=[
('season', current['season']), ('team_abbrev', team['abbrev'])
])
if s_query['count'] > 0:
team_standings = s_query['standings'][0]
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:
logging.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'])
logging.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://sombaseball.ddns.net/teams?abbrev={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)
logging.info(f'player_search: {player_search}')
logging.info(f'player_search.group(): {player_search.group()} / group(1): {player_search.group(1)} '
f'/ group(2): {player_search.group(2)}')
# No season is included
if not player_search.group(1):
p_name = await fuzzy_player_search(ctx, ctx.channel, self.bot, name, self.player_list.keys())
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:
async with ctx.typing():
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
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']]
)
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.')
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: int):
await ctx.send(f'That mother fucker Cal hasn\'t updated this command for the new API.')
await ctx.send(random_gif('this idiot'))
return
current = await db_get('current')
if week:
schedule_week = week[0]
elif current['week'] < 1:
schedule_week = 1
else:
schedule_week = current['week']
this_week_raw = await get_schedule(
current['season'],
week_start=schedule_week,
week_end=schedule_week
)
next_week_raw = await get_schedule(
current['season'],
week_start=schedule_week + 1,
week_end=schedule_week + 1
)
results_this_week = await get_results(
current['season'],
week=schedule_week
)
this_week = dict(sorted(this_week_raw.items(), key=lambda item: item[1]["id"]))
next_week = dict(sorted(next_week_raw.items(), key=lambda item: item[1]["id"]))
game_count = 0
for x in this_week:
game_count += this_week[x]['gamecount']
embed = get_team_embed(f'Season {current["season"]} | Week {schedule_week} | '
f'{len(results_this_week)}/{game_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 this_week:
away_wins = 0
away_losses = 0
weekly_results = await get_results(current['season'], week=schedule_week,
away_abbrev=this_week[x]['awayteam']['abbrev'])
for y in weekly_results:
if weekly_results[y]['awayteam'] == this_week[x]['awayteam'] and \
weekly_results[y]['hometeam'] == this_week[x]['hometeam']:
if weekly_results[y]['awayscore'] > weekly_results[y]['homescore']:
away_wins += 1
else:
away_losses += 1
this_line = f'`({away_wins}) {this_week[x]["awayteam"]["abbrev"]: >4}` ' \
f'{await team_emoji(ctx, this_week[x]["awayteam"])} @ ' \
f'{await team_emoji(ctx, this_week[x]["hometeam"])} ' \
f'`{this_week[x]["hometeam"]["abbrev"]: <4} ({away_losses})`\n'
if count > 8:
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 next_week:
this_line = f'`{next_week[x]["awayteam"]["abbrev"]: >4}` ' \
f'{await team_emoji(ctx, next_week[x]["awayteam"])} @ ' \
f'{await team_emoji(ctx, next_week[x]["hometeam"])} ' \
f'`{next_week[x]["hometeam"]["abbrev"]: <4}`\n'
if count > 8:
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']), ('league_abbrev', 'al'), ('division_abbrev', 'e')
])
div_one = d1_query['standings']
d2_query = await db_get('standings', params=[
('season', current['season']), ('league_abbrev', 'al'), ('division_abbrev', 'w')
])
div_two = d2_query['standings']
d3_query = await db_get('standings', params=[
('season', current['season']), ('league_abbrev', 'nl'), ('division_abbrev', 'e')
])
div_three = d3_query['standings']
d4_query = await db_get('standings', params=[
('season', current['season']), ('league_abbrev', 'nl'), ('division_abbrev', 'w')
])
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'**AL East**', value=div_one_standings, inline=False)
embed.add_field(name=f'**AL West**', value=div_two_standings, inline=False)
embed.add_field(name=f'**NL East**', value=div_three_standings, inline=False)
embed.add_field(name=f'**NL West**', 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', 'al')
])
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)
logging.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:
logging.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
logging.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.guilds(discord.Object(id=os.environ.get('GUILD_ID')))
@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):
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
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 patch_player(player):
await db_patch('current', object_id=current['id'], params=[('injury_count', current['injury_count'] + 1)])
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 log_injury(
# current, {'player': player, 'type': 'new', 'current_game': this_game, 'injury_length': inj_games}
# )
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]
if not player['il_return']:
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']
await interaction.edit_original_response(
content=f'{player["name"]}\'s return was set for {player["il_return"]}.'
)
view = Confirm(responders=[interaction.user])
await interaction.edit_original_response(
content='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 patch_player(player):
await db_patch(
'current', object_id=current['id'], params=[('injury_count', current['injury_count'] + 1)]
)
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 log_injury(
# current, {'player': player, 'type': 'clear', 'current_game': None, 'injury_length': None}
# )
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(
'***S C O R E C A R D S***\n'
'**OG Card**:\n<https://docs.google.com/spreadsheets/d/1t6bfTFpHODRINIC2RF9lDt1XpHsnzeU0rYvSnpgWch'
'I/edit?usp=sharing>\n'
'**S6 PCD**:\n<https://docs.google.com/spreadsheets/d/1XeBbQjao6R4Z5HYJAbftFjfWQU9Jq2swKtYsg483TI0'
'/edit#gid=970312780>\n'
'**Foxx\'s**:\n<https://docs.google.com/spreadsheets/d/1NODWy7XeYcEBfQW_EmiwnthGTfn_JX5FDy6Hwjmf0f'
'k/edit?usp=sharing>\n'
'**Josef\'s**:\n<https://docs.google.com/spreadsheets/d/1g_ixDp9ZFuSyc5cNTQegsEwhpr_5yxpiIHhOvgchH'
'9k/edit?usp=sharing>\n\n'
'***R E F E R E N C E S***\n'
'**Rules Reference**:\n<https://docs.google.com/document/d/1wu63XSgfQE2wadiegWaaDda11QvqkN0liRurKm0'
'vcTs/edit?usp=sharing>\n'
'**League Guidelines**:\n<https://docs.google.com/document/d/1VVoGCDD3vaqy7NyZBKJ2BV8BvmiZJTie11hrh'
'pt_joI/edit?usp=sharing>\n'
'**Scouting Reference**:\n<https://docs.google.com/spreadsheets/d/1HErEweHt-cpf-a8X6pXMO13n0-aiVppF'
'g1jISNr5DpE/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...')
# logging.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).worksheet_by_title('Results')
# except Exception as e:
# logging.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
# try:
# away_bats = scorecard.get_values('A3', 'AK19')
# home_bats = scorecard.get_values('A33', 'AK49')
# away_arms = scorecard.get_values('A22', 'V30')
# home_arms = scorecard.get_values('A52', 'V59')
# away_team = await get_one_team(away_arms[0][1])
# home_team = await get_one_team(home_arms[0][1])
# week_num = away_bats[0][35]
# game_num = home_bats[0][36]
# except Exception as e:
# logging.error(f'Failed to read scorecard {sheet_url}: {e}')
# await interaction.edit_original_response(content=f'Oof, I got you an error:\n\n{e}.')
# return
#
# # Confirm teams and matchup
# this_matchup = await get_schedule(
# current['season'], away_abbrev=away_team['abbrev'], home_abbrev=home_team['abbrev'], week_start=week_num,
# week_end=week_num
# )
# if len(this_matchup) != 1:
# await interaction.edit_original_response(
# content=f'Hmm...it doesn\'t look like {away_team["abbrev"]} played {home_team["abbrev"]} in '
# f'week {week_num}.'
# )
# return
#
# # Confirm stats for game don't already exist
# old_home_bat = await get_battingstat(
# season=current['season'], team_abbrev=home_team['abbrev'], week_start=week_num,
# week_end=week_num, game_num=game_num)
# old_away_bat = await get_battingstat(
# season=current['season'], team_abbrev=away_team['abbrev'], week_start=week_num,
# week_end=week_num, game_num=game_num)
# old_home_arm = await get_pitchingstat(
# season=current['season'], team_abbrev=home_team['abbrev'], week_start=week_num,
# week_end=week_num, game_num=game_num)
# old_away_arm = await get_pitchingstat(
# season=current['season'], team_abbrev=away_team['abbrev'], week_start=week_num,
# week_end=week_num, game_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
#
# if len(old_home_bat) + len(old_away_bat) + len(old_home_arm) + len(old_away_arm) > 0:
# view = Confirm(responders=[interaction.user])
# question = await interaction.channel.send(
# f'I already see stats for {away_team["abbrev"]} @ {home_team["abbrev"]} week {week_num} game '
# f'{game_num}. Would you like me to remove those and update with this card?',
# view=view
# )
# await view.wait()
#
# if view.value:
# logging.info(f'sba-submit - view.value')
# this_game = {
# 'season': current['season'],
# 'week': week_num,
# 'game_num': game_num,
# 'away_team_id': away_team['id'],
# 'home_team_id': home_team['id']
# }
#
# await question.edit(
# content='What a pain in my balls. Let\'s start by deleting the batting stats...',
# view=None
# )
# if await delete_battingstats(this_game):
# await question.edit(content='Batting stats are gone - now the pitching stats...')
#
# if await delete_pitchingstats(this_game):
# await question.edit(
# content='Pitching stats are gone - now to recalculate everybody\'s season batting lines...'
# )
#
# if await recalc_batting_seasons(current['season'], away_team['id']):
# if await recalc_batting_seasons(current['season'], home_team['id']):
# await question.edit(
# content='Batting lines are done - now to recalculate pitching lines...'
# )
#
# if await recalc_pitching_seasons(current['season'], away_team['id']):
# if await recalc_pitching_seasons(current['season'], home_team['id']):
# await question.edit(
# content='Pitching lines are done - now to recalculate fielding lines...'
# )
#
# if await recalc_fielding_seasons(current['season'], away_team['id']):
# if await recalc_fielding_seasons(current['season'], home_team['id']):
# await question.edit(
# content=f'All done. Don\'t suck next time '
# f'{await get_emoji(interaction.guild, "lakemonsters")}'
# )
#
# week_games = await get_results(
# current['season'], away_abbrev=away_team['abbrev'], home_abbrev=home_team['abbrev'], week=week_num
# )
# this_game = None
# for x in week_games:
# if week_games[x]['game'] == game_num:
# this_game = week_games[x]
# break
# if this_game:
# await db_delete('results', object_id=this_game['id'])
#
# else:
# logging.info(f'sba-submit - view.value "else"')
# await interaction.channel.send('Alright, we\'ll call it a day here.')
# return
#
# logging.info(f'sba-submit - reading scorecard')
# # Read scorecard
# errors = []
# b_counts = {'sbc': 0, 'csc': 0, 'sb': 0, 'cs': 0, 'so': 0, 'bb': 0, 'run': 0, 'rbi': 0, 'xba': 0, 'xbt': 0,
# 'raa': 0, 'rto': 0}
# p_counts = {'gs': 0, 'win': 0, 'loss': 0, 'so': 0, 'bb': 0, 'run': 0, 'erun': 0, 'ir': 0, 'irs': 0}
# positions = ['C', '1B', '2B', '3B', 'SS', 'LF', 'CF', 'RF', 'DH', 'PH', 'PR', 'P']
# pit_nums = [f'{x}' for x in range(20)]
#
# bat_stats = ['player', 'team', 'pos', 'pa', 'ab', 'run', 'hit', 'rbi', 'double', 'triple', 'hr', 'bb', 'so',
# 'hbp', 'sac', 'ibb', 'gidp', 'sb', 'cs', 'bphr', 'bpfo', 'bp1b', 'bplo', 'xba', 'xbt', 'xch',
# 'xhit', 'error', 'pb', 'sbc', 'csc', 'roba', 'robs', 'raa', 'rto', 'week', 'game']
# pit_stats = ['player', 'team', 'ip', 'hit', 'run', 'erun', 'so', 'bb', 'hbp', 'wp', 'balk', 'hr', 'ir', 'irs',
# 'gs', 'win', 'loss', 'hold', 'sv', 'bsv', 'week', 'game']
#
# new_bat_stats = []
# new_pit_stats = []
# final_box_away = {'r': 0, 'h': 0, 'e': 0, 'ip': 0}
# final_box_home = {'r': 0, 'h': 0, 'e': 0, 'ip': 0}
# final_wp = None
# final_lp = None
# final_holds = []
# final_sv = None
# final_bsv = []
# final_doubles = []
# final_triples = []
# final_homeruns = []
# final_sbs = []
# final_cscs = []
#
# # Read batting stats
# for group in [away_bats, home_bats]:
# for line in group:
# if line[0]:
# # Dictionary to hold data to be passed to db for BatStat model
# this_batter = {'season': current['season']}
#
# # Keeping count so we can add stat name and data from sheet into this_batter dict
# for count in range(len(bat_stats)):
# if line[count] != '' and line[count] != '#REF' and line[count] != 0:
# this_batter[bat_stats[count]] = line[count]
#
# # Add this_batter to collection new_bat_stats
# try:
# this_batter['player_id'] = self.player_list[line[0].lower()]
# this_batter['team_id'] = away_team['id'] if line[1].lower() == away_team['abbrev'].lower() \
# else home_team['id']
# # Check for pitcher int in position
# if this_batter['pos'] in pit_nums:
# this_batter['pos'] = 'P'
# this_bat_stat = BatStat.parse_obj(this_batter)
# new_bat_stats.append(this_bat_stat.dict())
#
# # Get stats for news-ticker
# if this_batter['team_id'] == away_team['id']:
# final_box_away['r'] += this_bat_stat.run
# final_box_away['h'] += this_bat_stat.hit
# final_box_away['e'] += this_bat_stat.error
# else:
# final_box_home['r'] += this_bat_stat.run
# final_box_home['h'] += this_bat_stat.hit
# final_box_home['e'] += this_bat_stat.error
#
# if this_bat_stat.double:
# final_doubles.append((this_batter['player_id'], this_bat_stat.double))
# if this_bat_stat.triple:
# final_triples.append((this_batter['player_id'], this_bat_stat.triple))
# if this_bat_stat.hr:
# final_homeruns.append((this_batter['player_id'], this_bat_stat.hr))
# if this_bat_stat.sb:
# final_sbs.append((this_batter['player_id'], this_bat_stat.sb))
# if this_bat_stat.csc:
# final_cscs.append((this_batter['player_id'], this_bat_stat.csc))
#
# except Exception as e:
# errors.append(f'{line[0]}: {e}')
#
# # Read pitching stats
# for group in [away_arms, home_arms]:
# for line in group:
# if line[0]:
# # Dictionary to hold data for PitStat model
# this_pitcher = {'season': current['season']}
#
# # Keeping count so we can add stat name and data from sheet into this_pitcher dict
# for count in range(len(pit_stats)):
# if line[count] != '' and line[count] != '#REF' and line[count] != 0:
# this_pitcher[pit_stats[count]] = line[count]
#
# # Add this_pitcher to collection new_pit_stats
# try:
# this_pitcher['player_id'] = self.player_list[line[0].lower()]
# this_pitcher['team_id'] = away_team['id'] if line[1].lower() == away_team['abbrev'].lower() \
# else home_team['id']
# this_pit_stat = PitStat.parse_obj(this_pitcher)
#
# # Update IP to an even third
# first_digit = f'{this_pit_stat.ip % 1}'[2]
# if first_digit == '0':
# this_pit_stat.ip = math.floor(this_pit_stat.ip)
# elif first_digit in ['1', '3']:
# this_pit_stat.ip = math.floor(this_pit_stat.ip) + (1/3)
# else:
# this_pit_stat.ip = math.floor(this_pit_stat.ip) + (2/3)
#
# new_pit_stats.append(this_pit_stat.dict())
#
# # Get stats for news-ticker
# if this_pit_stat.win:
# final_wp = this_pit_stat.player_id
# if this_pit_stat.loss:
# final_lp = this_pit_stat.player_id
# if this_pit_stat.sv:
# final_sv = this_pit_stat.player_id
# if this_pit_stat.bsv:
# final_bsv.append(this_pit_stat.player_id)
# if this_pit_stat.hold:
# final_holds.append(this_pit_stat.player_id)
# if this_pitcher['team_id'] == away_team['id']:
# final_box_away['ip'] += this_pit_stat.ip
# else:
# final_box_home['ip'] += this_pit_stat.ip
# except Exception as e:
# errors.append(f'{line[0]}: {e}')
#
# # Error checks
# await interaction.edit_original_response(
# content='Just finished reading the scorecard. Now to look for all of your mistakes...'
# )
# for line in new_bat_stats:
# b_counts['sbc'] += line['sbc']
# b_counts['csc'] += line['csc']
# b_counts['sb'] += line['sb']
# b_counts['cs'] += line['cs']
# b_counts['so'] += line['so']
# b_counts['bb'] += line['bb'] + line['ibb']
# b_counts['run'] += line['run']
# b_counts['rbi'] += line['rbi']
# b_counts['xba'] += line['xba']
# b_counts['xbt'] += line['xbt']
# b_counts['raa'] += line['raa']
# b_counts['rto'] += line['rto']
# if line['pos'] not in positions:
# errors.append(f'{line["pos"]} not a valid position')
# for line in new_pit_stats:
# logging.info(f'line: {line}')
# p_counts['gs'] += line['gs']
# p_counts['win'] += line['win']
# p_counts['loss'] += line['loss']
# p_counts['bb'] += line['bb']
# p_counts['so'] += line['so']
# p_counts['run'] += line['run']
# p_counts['erun'] += line['erun']
# p_counts['ir'] += line['ir']
# p_counts['irs'] += line['irs']
#
# if b_counts['sbc'] > b_counts['sb'] + b_counts['cs']:
# errors.append(f'There are {b_counts["sbc"]} stolen base attempts (SBa), but {b_counts["sb"]} SB and '
# f'{b_counts["cs"]} CS.')
# if b_counts['csc'] > b_counts['cs']:
# errors.append(f'There are {b_counts["sbc"]} catcher caught stealings (CSc), but '
# f'{b_counts["cs"]} baserunner CS.')
# if b_counts['so'] != p_counts['so']:
# errors.append(f'There are {b_counts["so"]} batter strikeouts, but {p_counts["so"]} pitcher strikeouts.')
# if b_counts['bb'] != p_counts['bb']:
# errors.append(f'There are {b_counts["bb"]} batter walks, but {p_counts["bb"]} pitcher.')
# if b_counts['run'] != p_counts['run']:
# errors.append(f'There are {b_counts["run"]} batter runs, but {p_counts["run"]} pitcher runs.')
# if b_counts['rbi'] > b_counts['run']:
# errors.append(f'There are {b_counts["rbi"]} runs batted in, but {b_counts["run"]} runs scored.')
# if b_counts['rto'] > b_counts['raa']:
# errors.append(f'There are {b_counts["rto"]} runners thrown out, but {b_counts["raa"]} runner '
# f'advance attempts.')
# if b_counts['xbt'] > b_counts['xba']:
# errors.append(f'There are {b_counts["xbt"]} extra bases taken, but {b_counts["xba"]} extra '
# f'base attempts.')
# if p_counts['erun'] > p_counts['run']:
# errors.append(f'There are {p_counts["erun"]} earned runs and {p_counts["run"]} total runs. ')
# if p_counts['gs'] != 2:
# errors.append(f'There should be 2 GS, but I see {p_counts["gs"]} of them.')
# if p_counts['win'] != 1:
# errors.append(f'There should be 1 W, but I see {p_counts["win"]} of them.')
# if p_counts['loss'] != 1:
# errors.append(f'There should be 1 L, but I see {p_counts["loss"]} of them.')
# if p_counts['irs'] > p_counts['ir']:
# errors.append(f'There are {p_counts["irs"]} inherited runners scored and {p_counts["ir"]} '
# f'inherited runners.')
#
# # Post errors, if any, or post stats to db
# if len(errors) > 0:
# error_message = '\n- '.join(errors)
# 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- {error_message}'
# )
# logging.error(f'Scorecard errors: {error_message}')
# return
# else:
# bat_conf = await post_battingstats(new_bat_stats)
# pit_conf = await post_pitchingstats(new_pit_stats)
#
# if bat_conf and pit_conf:
# await interaction.edit_original_response(
# content=f'You did it! I just logged the stats for **wk{week_num}g{game_num}**'
# )
#
# # Update last games for pitchers
# for x in new_pit_stats:
# this_pitcher = await get_one_player(x["player_id"])
# game_string = f'{float(x["ip"]):.2}IP w{x["week"]}g{x["game"]}'
# await patch_player(this_pitcher['id'], last_game=game_string, last_game2=this_pitcher['last_game'])
# else:
# await interaction.edit_original_response(
# content='So the stats looked okay, but I had an accident when I tried to post them. They '
# 'did not go through.'
# )
#
# # Post scorecard to weekly archive
# card_url = f'<{SBA_BASE_URL}/scorecards/?season={current["season"]}&week={week_num}&game={game_num}' \
# f'&away_abbrev={away_team["abbrev"]}&home_abbrev={home_team["abbrev"]}>'
# # try:
# # archive_channel = get_channel(interaction, name=f'week-{week_num}-archive')
# # logging.info(f'archive_channel: {archive_channel}')
# # if not archive_channel:
# # archive_channel = await create_channel(
# # interaction,
# # channel_name=f'week-{week_num}-archive',
# # category_name=f'Season {current["season"]} Archives',
# # read_send_roles=[get_role(interaction, 'Gameplay Bots')]
# # )
# #
# # await archive_channel.send(
# # f'Game {game_num}: **{away_team["sname"]}** {await team_emoji(interaction, away_team)} '
# # f'{final_box_away["r"]} @ {final_box_home["r"]} '
# # f'{await team_emoji(interaction, home_team)} **{home_team["sname"]}**\n{card_url}')
# # except Exception as e:
# # await interaction.edit_original_response(
# # content='Ope. I wasn\'t able to post this to the archive channel.'
# # )
#
# # Post box score to news-ticker
#
# extras = ''
# if final_box_home['ip'] > 9:
# extras = f' F/{math.floor(final_box_home["ip"])}'
# embed = get_team_embed(
# f'{away_team["sname"]} {final_box_away["r"]} @ '
# f'{final_box_home["r"]} {home_team["sname"]}{extras}',
# team=away_team if final_box_away['r'] > final_box_home['r'] 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} | {final_box_away["r"]: >2} | {final_box_away["h"]: >2} | '
# f'{final_box_away["e"]: >2} |\n'
# f'{home_team["abbrev"]: <4} | {final_box_home["r"]: >2} | {final_box_home["h"]: >2} | '
# f'{final_box_home["e"]: >2} |\n'
# f'```',
# inline=False
# )
#
# wp = await get_one_player(final_wp)
# lp = await get_one_player(final_lp)
# if final_sv:
# sv = await get_one_player(final_sv)
# else:
# sv = None
# holds = []
# bsvs = []
# for x in final_holds:
# holds.append(await get_one_player(x))
# for x in final_bsv:
# bsvs.append(await get_one_player(x))
#
# 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 += ', '
# elif len(holds) > 0:
# hold_string += '\n'
# count += 1
# pitching_string += hold_string
#
# if sv:
# pitching_string += f'SV: {sv["name"]}'
#
# embed.add_field(name='Pitching', value=pitching_string, 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})'
# )
# embed.set_footer(text='Please share the highlights!')
#
# await send_to_channel(
# self.bot,
# 'sba-network-news',
# content=None,
# embed=embed
# )
#
# result = {
# 'week': week_num,
# 'game': game_num,
# 'away_team_id': away_team['id'],
# 'home_team_id': home_team['id'],
# 'away_score': final_box_away["r"],
# 'home_score': final_box_home["r"],
# 'season': current['season'],
# 'scorecard_url': sheet_url
# }
# if await db_post('results', payload={'results': [result]}):
# update = await interaction.channel.send('I\'m tallying standings now...')
# if await db_post(f'standings/s{current["season"]}/recalculate'):
# await update.delete()
@app_commands.command(name='branding', description='Update your team branding')
@app_commands.guilds(discord.Object(id=os.environ.get('GUILD_ID')))
@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, 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.response.send_message(
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:
logging.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=0.5).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', color_hex)])
show_mil = True
except Exception as e:
logging.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')
if mil_team_image_url is not None:
if requests.get(mil_team_image_url, timeout=0.5).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:
logging.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:
logging.info(f'entering show_dice')
team['color'] = team['dice_color']
dice_embed = get_team_embed(f'{team["lname"]} Dice Test', team=team)
logging.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!'
)
logging.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')
)
logging.info(f'Just created voice channel: {channel_name} for {ctx.author}')
await ctx.send(f'Just created {this_vc} for you!')
while True:
await asyncio.sleep(900)
if len(this_vc.members) == 0:
await this_vc.delete()
logging.info(f'Just deleted voice channel: {channel_name}')
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
s_query = await db_get('schedules', params=[
('season', current['season']), ('team_abbrev', this_team['abbrev']), ('week_start', current['week']),
('week_end', current['week']), ('short_output', False)
])
if s_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_matchup = s_query['schedules'][0]
if this_team == this_matchup['awayteam']:
other_team = this_matchup['hometeam']
else:
other_team = this_matchup['awayteam']
channel_name = f'{this_matchup["awayteam"]["sname"]} @ {this_matchup["hometeam"]["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 resp is None:
await ctx.send('Fine. I bet they didn\'t wanna talk to you anyway.')
return
elif not resp:
channel_name = f'{this_team["abbrev"]} vs {other_team["abbrev"]}'
logging.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
logging.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)}
logging.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')
)
await ctx.send(f'Just created {this_vc} for you!')
while True:
await asyncio.sleep(900)
if len(this_vc.members) == 0:
await this_vc.delete()
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 patch_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 patch_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 patch_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[
'rest', 'sac-bunt', 'squeeze-bunt', 'rob-hr', 'defense-matters', 'block-plate', 'hit-and-run',
'g1', 'g2', 'g3', 'groundball']):
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']
}
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'])])
logging.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('ASCII')
else:
scorecard = sheets.open_by_key(sheet_url).worksheet_by_title('ASCII')
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')
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME, PD_PLAYERS_ROLE_NAME)
async def scorebug_slash(self, interaction: discord.Interaction):
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)
score_text = this_scorecard.get_value('A1')
await interaction.edit_original_response(content=score_text)
@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='86', value=86),
Choice(name='80', value=80),
Choice(name='70', value=70),
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
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': {
'p86': ['OK', 'OK', 'OK', 'OK', 'OK', 'OK', 'REM', 'REM', 1, 1, 2, 2, 3, 3, 4, 5],
'p80': [2, 2, 'OK', 'REM', 1, 2, 3, 3, 4, 4, 5, 5, 6, 8, 12, 16],
'p70': ['OK', 'OK', 'REM', 1, 2, 3, 4, 5, 5, 6, 6, 8, 12, 16, 20, 20],
'p60': ['OK', 'REM', 1, 2, 3, 4, 5, 6, 6, 8, 12, 12, 16, 20, 20, 'OK'],
'p50': ['OK', 1, 2, 3, 4, 5, 6, 8, 8, 12, 12, 16, 20, 30, 'REM', 'OK'],
'p40': ['OK', 5, 1, 3, 5, 6, 8, 12, 12, 16, 20, 30, 4, 2, 'REM', 'OK'],
'p30': ['OK', 1, 2, 5, 6, 8, 12, 16, 20, 30, 12, 8, 4, 3, 'REM', 'OK'],
'p20': ['OK', 1, 2, 5, 6, 12, 12, 30, 20, 16, 16, 8, 4, 3, 'REM', 'OK']
},
'two': {
'p86': [4, 3, 2, 2, 1, 1, 'REM', 'OK', 'REM', 'OK', 2, 1, 2, 2, 3, 5],
'p80': [12, 6, 4, 2, 2, 'OK', 1, 'OK', 'REM', 1, 'REM', 2, 3, 5, 8, 16],
'p70': [1, 3, 4, 6, 2, 2, 'OK', 1, 3, 'REM', 4, 5, 8, 12, 16, 3],
'p60': [5, 'OK', 'OK', 'REM', 1, 2, 5, 3, 4, 6, 4, 8, 12, 16, 16, 'OK'],
'p50': ['OK', 'OK', 'REM', 1, 2, 3, 4, 5, 6, 5, 8, 12, 16, 20, 20, 'OK'],
'p40': ['OK', 'REM', 1, 2, 3, 4, 5, 6, 8, 6, 12, 16, 20, 30, 'REM', 'OK'],
'p30': ['OK', 1, 2, 4, 5, 6, 8, 6, 12, 16, 8, 20, 30, 3, 5, 'REM'],
'p20': ['OK', 1, 4, 5, 6, 6, 8, 8, 16, 12, 20, 30, 12, 3, 2, 'REM']
},
'three': {
'p86': [],
'p80': ['OK', 'OK', 'REM', 1, 3, 'OK', 'REM', 1, 2, 1, 2, 3, 4, 5, 6, 'REM'],
'p70': ['OK', 6, 'OK', 'REM', 1, 2, 2, 3, 4, 5, 1, 3, 6, 8, 12, 'REM'],
'p60': ['OK', 'OK', 'REM', 1, 2, 3, 4, 5, 6, 4, 5, 8, 12, 12, 16, 'REM'],
'p50': ['OK', 1, 1, 2, 3, 4, 5, 6, 8, 6, 8, 12, 12, 16, 5, 'REM'],
'p40': ['OK', 1, 2, 3, 4, 6, 5, 8, 6, 8, 12, 12, 16, 20, 1, 'REM'],
'p30': ['OK', 2, 3, 4, 5, 8, 6, 8, 12, 12, 16, 6, 20, 30, 1, 'REM'],
'p20': ['OK', 1, 2, 4, 5, 12, 12, 8, 6, 16, 8, 20, 30, 3, 5, 'REM']
},
'four': {
'p86': [],
'p80': [],
'p70': ['OK', 'OK', 'REM', 3, 3, 'OK', 'REM', 1, 2, 1, 4, 5, 6, 8, 12, 'REM'],
'p60': ['OK', 8, 4, 'OK', 'REM', 1, 2, 4, 5, 3, 6, 3, 8, 12, 16, 'REM'],
'p50': ['OK', 'OK', 'REM', 1, 2, 3, 4, 5, 6, 4, 5, 8, 12, 12, 16, 'REM'],
'p40': ['OK', 1, 1, 2, 3, 4, 5, 6, 8, 6, 8, 12, 12, 16, 5, 'REM'],
'p30': ['OK', 'REM', 2, 3, 4, 5, 6, 6, 8, 8, 16, 12, 12, 1, 20, 'REM'],
'p20': ['OK', 1, 2, 3, 4, 6, 5, 8, 6, 8, 16, 12, 12, 20, 1, 'REM']
},
'five': {
'p86': [],
'p80': [],
'p70': [],
'p60': ['OK', 'OK', 'REM', 1, 1, 'OK', 'REM', 3, 2, 4, 5, 6, 8, 6, 12, 16],
'p50': ['OK', 8, 8, 'OK', 1, 3, 2, 4, 5, 6, 'REM', 3, 12, 8, 16, 1],
'p40': ['OK', 'OK', 'REM', 5, 1, 2, 6, 4, 8, 3, 5, 12, 6, 8, 16, 'REM'],
'p30': ['OK', 'REM', 2, 3, 5, 4, 6, 5, 8, 6, 12, 8, 3, 1, 16, 'REM'],
'p20': ['OK', 'REM', 2, 3, 5, 4, 6, 5, 8, 6, 12, 8, 12, 1, 16, 'REM']
},
'six': {
'p86': [],
'p80': [],
'p70': [],
'p60': [],
'p50': ['OK', 8, 3, 'OK', 1, 3, 2, 4, 5, 6, 'REM', 8, 12, 3, 16, 1],
'p40': ['OK', 'OK', 'REM', 5, 1, 3, 8, 4, 6, 2, 5, 12, 3, 4, 16, 'REM'],
'p30': ['OK', 'REM', 4, 5, 2, 3, 6, 4, 8, 5, 12, 6, 3, 1, 16, 'REM'],
'p20': ['OK', 'REM', 2, 3, 5, 4, 6, 5, 8, 6, 12, 8, 12, 1, 16, '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'
logging.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]
logging.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']))
)
except Exception as e:
logging.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:
logging.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:
logging.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)
async def setup(bot):
await bot.add_cog(Players(bot))