2105 lines
99 KiB
Python
2105 lines
99 KiB
Python
import re
|
|
import copy
|
|
|
|
from helpers import *
|
|
from db_calls import db_get, db_patch, get_team_by_owner, get_team_by_abbrev, get_player_by_name, patch_player, db_post
|
|
from discord.ext import commands, tasks
|
|
OFFSEASON_FLAG = False
|
|
|
|
|
|
class SBaTransaction:
|
|
def __init__(self, channel, current, move_type, this_week=False, first_team=None, team_role=None):
|
|
self.players = {} # Example: { <Player ID>: { "player": { Strat Player Dict }, "to": { Strat Team Dict } } }
|
|
self.teams = {} # Example: { <Team ID>: { "team": { Strat Team Dict }, "role": <Discord Role Object> } } }
|
|
self.picks = {} # Example: { <Pick ID>: { "pick": { Strat Pick Dict }, "to": { Strat Team Dict } } }
|
|
self.avoid_freeze = True
|
|
self.channel = channel
|
|
self.gms = []
|
|
self.current = current
|
|
self.effective_week = current['week'] + 1 if not this_week else current['week']
|
|
self.move_type = move_type
|
|
|
|
if first_team and team_role:
|
|
self.add_team(first_team, team_role)
|
|
if (first_team and not team_role) or (team_role and not first_team):
|
|
logging.error(f'Trade creation failed:\nteam: {first_team}\nteam_role: {team_role}')
|
|
raise ValueError('Trade creation failed')
|
|
|
|
def add_team(self, new_team, role):
|
|
if new_team['id'] not in self.teams.keys():
|
|
self.teams[new_team['id']] = {
|
|
'team': new_team,
|
|
'role': role
|
|
}
|
|
self.gms.append(new_team['gmid'])
|
|
if new_team['gmid2']:
|
|
self.gms.append(new_team['gmid2'])
|
|
|
|
return True
|
|
|
|
async def add_player(self, player, to_team):
|
|
if player['id'] not in self.players.keys():
|
|
self.players[player['id']] = {
|
|
'player': player,
|
|
'to': to_team
|
|
}
|
|
await self.send(f'Got it - throwing {player["name"]} onto a plane.')
|
|
else:
|
|
await self.send(f'{player["name"]} is already part of this transaction. They\'re heading to '
|
|
f'{self.players[player["id"]]["to"]["sname"]}. Try to keep up.')
|
|
|
|
async def add_pick(self, pick, to_team):
|
|
if pick['id'] not in self.picks.keys():
|
|
self.picks[pick['id']] = {
|
|
'pick': pick,
|
|
'to': to_team
|
|
}
|
|
await self.send(f'Okay, {pick["origowner"]["abbrev"]}\'s {pick["round"]} is on the table.')
|
|
else:
|
|
await self.send(f'{pick["origowner"]["abbrev"]}\'s {pick["round"]} is already part of the deal. It\'s '
|
|
f'going to {self.picks[pick["id"]]["to"]["abbrev"]}. Please try to keep up.')
|
|
|
|
def included_team(self, team):
|
|
team_abbrev = team['abbrev']
|
|
for team in self.teams.values():
|
|
if team_abbrev in [team['team']['abbrev'], f'{team["team"]["abbrev"]}IL', f'{team["team"]["abbrev"]}MiL']:
|
|
return True
|
|
|
|
return False
|
|
|
|
async def not_available(self, player, this_week=False):
|
|
transactions = await self.get_player_moves(player, this_week)
|
|
logging.info(f'Is {player["name"]} not available? - {len(transactions)}')
|
|
if len(transactions) > 0:
|
|
return True
|
|
return False
|
|
|
|
def get_gms(self, bot, team=None):
|
|
if team is None:
|
|
return [bot.get_user(x) for x in self.gms]
|
|
else:
|
|
these_gms = [bot.get_user(self.teams[team]['team']['gmid'])]
|
|
if self.teams[team]['team']['gmid2']:
|
|
these_gms.append(bot.get_user(self.teams[team]['team']['gmid2']))
|
|
return these_gms
|
|
|
|
async def send(self, content=None, embed=None):
|
|
return await self.channel.send(content=content, embed=embed)
|
|
|
|
async def show_moves(self, here=True):
|
|
embed = get_team_embed(f'Week {self.effective_week} Transaction', team=[*self.teams.values()][0]['team'])
|
|
teams = [self.teams[x]['team']['sname'] for x in self.teams]
|
|
embed.description = f'{", ".join(teams)}'
|
|
|
|
# Get player string
|
|
player_string = ''
|
|
for x in self.players:
|
|
player_string += f'**{self.players[x]["player"]["name"]}** ({self.players[x]["player"]["wara"]}) from ' \
|
|
f'{self.players[x]["player"]["team"]["abbrev"]} to {self.players[x]["to"]["abbrev"]}\n'
|
|
|
|
if len(player_string) == 0:
|
|
player_string = 'None...yet'
|
|
|
|
embed.add_field(name='Player Moves', value=player_string, inline=False)
|
|
|
|
# Get draft pick string
|
|
pick_string = ''
|
|
for x in self.picks:
|
|
pick_string += f'**{self.picks[x]["pick"]["origowner"]["abbrev"]} {self.picks[x]["pick"]["round"]}** to ' \
|
|
f'{self.picks[x]["to"]["abbrev"]}\n'
|
|
|
|
if len(pick_string) > 0:
|
|
embed.add_field(name='Pick Trades', value=pick_string, inline=False)
|
|
|
|
if here:
|
|
await self.send(content=None, embed=embed)
|
|
else:
|
|
return embed
|
|
|
|
async def timed_delete(self):
|
|
await self.channel.send('I will delete this channel in 5 minutes.')
|
|
await asyncio.sleep(300)
|
|
await self.channel.delete()
|
|
|
|
async def get_player_moves(self, player, this_week):
|
|
if this_week:
|
|
t_query = await db_get('transactions', params=[
|
|
('season', self.current['season']), ('week_start', self.current['week']),
|
|
('week_end', self.current['season']), ('player_id', player['id'])
|
|
])
|
|
return t_query['transactions']
|
|
else:
|
|
t_query = await db_get('transactions', params=[
|
|
('season', self.current['season']), ('week_start', self.effective_week),
|
|
('week_end', self.effective_week), ('player_id', player['id'])
|
|
])
|
|
return t_query['transactions']
|
|
|
|
async def check_major_league_errors(self, team):
|
|
wara = 0
|
|
mil_wara = 0
|
|
this_team = self.teams[team]['team']
|
|
# team_roster = await get_players(self.current['season'], this_team['abbrev'])
|
|
t_query = await db_get('players', params=[
|
|
('season', self.current['season']), ('team_id', this_team['id'])
|
|
])
|
|
team_roster = t_query['players']
|
|
|
|
ml_query = await db_get('teams', params=[
|
|
('season', self.current['season']), ('team_abbrev', f'{this_team["abbrev"]}MiL')
|
|
])
|
|
# mil_roster = await get_players(self.current['season'], f'{this_team["abbrev"]}MiL')
|
|
mil_team = await get_team_by_abbrev(f'{this_team["abbrev"]}MiL', season=this_team['season'])
|
|
m_query = await db_get('players', params=[
|
|
('season', self.current['season']), ('team_id', mil_team['id'])
|
|
])
|
|
mil_roster = m_query['players']
|
|
|
|
for player in team_roster:
|
|
wara += player['wara']
|
|
for player in mil_roster:
|
|
mil_wara += player['wara']
|
|
|
|
logging.info(f'checking future moves')
|
|
if self.effective_week > self.current['week']:
|
|
# set_moves = await get_transactions(
|
|
# self.current['season'], team_abbrev=this_team['abbrev'], week_start=self.effective_week,
|
|
# week_end=self.effective_week
|
|
# )
|
|
t_query = await db_get('transactions', params=[
|
|
('season', self.current['season']), ('week_start', self.effective_week),
|
|
('week_end', self.effective_week), ('team_abbrev', this_team['abbrev'])
|
|
])
|
|
set_moves = t_query['transactions']
|
|
# freeze_moves = await get_transactions(
|
|
# self.current['season'], team_abbrev=this_team['abbrev'], week_start=self.effective_week,
|
|
# week_end=self.effective_week, frozen=True
|
|
# )
|
|
t_query = await db_get('transactions', params=[
|
|
('season', self.current['season']), ('week_start', self.effective_week),
|
|
('week_end', self.effective_week), ('team_abbrev', this_team['abbrev']), ('frozen', True)
|
|
])
|
|
freeze_moves = t_query['transactions']
|
|
moves = set_moves + freeze_moves
|
|
|
|
for x in moves:
|
|
# If player is joining this team, add to roster and add WARa
|
|
if x['newteam'] == this_team:
|
|
team_roster.append(x['player'])
|
|
wara += x['player']['wara']
|
|
# If player is joining MiL team, add to roster and add WARa
|
|
elif x['newteam']['abbrev'] == f'{this_team["abbrev"]}MiL':
|
|
mil_roster.append(x['player'])
|
|
mil_wara += x['player']['wara']
|
|
|
|
# If player is leaving this team, remove from roster and subtract WARa
|
|
if x['oldteam'] == this_team:
|
|
team_roster.remove(x['player'])
|
|
wara -= x['player']['wara']
|
|
# If player is leaving MiL team, remove from roster and subtract WARa
|
|
elif x['oldteam']['abbrev'] == f'{this_team["abbrev"]}MiL':
|
|
mil_roster.remove(x['player'])
|
|
mil_wara -= x['player']['wara']
|
|
|
|
logging.info(f'updating rosters')
|
|
for x in self.players:
|
|
logging.info(f'x player: {x}')
|
|
# If player is joining this team, add to roster and add WARa
|
|
if self.players[x]['to'] == this_team:
|
|
team_roster.append(self.players[x]['player'])
|
|
wara += self.players[x]['player']['wara']
|
|
# If player is joining MiL team, add to roster and add WARa
|
|
elif self.players[x]['to']['abbrev'] == f'{this_team["abbrev"]}MiL':
|
|
mil_roster.append(self.players[x]['player'])
|
|
mil_wara += self.players[x]['player']['wara']
|
|
# If player is joining IL team, remove from roster and cut WARa
|
|
elif self.players[x]['to']['abbrev'] == f'{this_team["abbrev"]}IL':
|
|
wara -= self.players[x]['player']['wara']
|
|
|
|
# If player is leaving this team next week, remove from roster and subtract WARa
|
|
if self.players[x]['player']['team'] == this_team:
|
|
logging.info(f'major league player')
|
|
# logging.info(f'team roster: {team_roster}')
|
|
team_roster.remove(self.players[x]['player'])
|
|
# 06-13: COMMENTED OUT TO RESOLVE MID-WEEK IL REPLACEMENT BEING SENT BACK DOWN
|
|
# if self.effective_week != self.current['week']:
|
|
wara -= self.players[x]['player']['wara']
|
|
|
|
# If player is leaving MiL team next week, remove from roster and subtract WARa
|
|
if self.players[x]['player']['team']['abbrev'] == f'{this_team["abbrev"]}MiL':
|
|
logging.info(f'minor league player')
|
|
mil_roster.remove(self.players[x]['player'])
|
|
# logging.info(f'mil roster: {mil_roster}')
|
|
if self.effective_week != self.current['week']:
|
|
mil_wara -= self.players[x]['player']['wara']
|
|
|
|
return {'roster': team_roster, 'wara': wara, 'mil_roster': mil_roster, 'mil_wara': mil_wara}
|
|
|
|
# async def check_minor_league_errors(self, ml_team_id):
|
|
# wara = 0
|
|
# this_team = await get_one_team(ml_team_id + 2)
|
|
# team_roster = await get_players(self.current['season'], this_team['abbrev'])
|
|
#
|
|
# for player in team_roster:
|
|
# wara += team_roster[player]['wara']
|
|
#
|
|
# if self.effective_week > self.current['week']:
|
|
# set_moves = await get_transactions(
|
|
# self.current['season'], team_abbrev=this_team['abbrev'], week_start=self.effective_week,
|
|
# week_end=self.effective_week
|
|
# )
|
|
# freeze_moves = await get_transactions(
|
|
# self.current['season'], team_abbrev=this_team['abbrev'], week_start=self.effective_week,
|
|
# week_end=self.effective_week, frozen=True
|
|
# )
|
|
# moves = {**set_moves, **freeze_moves}
|
|
#
|
|
# for x in moves:
|
|
# # If player is joining this team, add to roster and add WARa
|
|
# if moves[x]['newteam'] == this_team:
|
|
# team_roster[moves[x]['player']['name']] = moves[x]['player']
|
|
# wara += moves[x]['player']['wara']
|
|
# # If player is leaving this team, remove from roster and subtract WARa
|
|
# else:
|
|
# # del team_roster[moves[x]['player']['name']]
|
|
# team_roster.pop(moves[x]['player']['name'], None)
|
|
# wara -= moves[x]['player']['wara']
|
|
#
|
|
# for x in self.players:
|
|
# # If player is joining this team, add to roster and add WARa
|
|
# if self.players[x]['to'] == this_team:
|
|
# team_roster[self.players[x]['player']['name']] = self.players[x]['player']
|
|
# wara += self.players[x]['player']['wara']
|
|
# # If player is leaving this team next week, remove from roster and subtract WARa
|
|
# elif self.players[x]['player']['team'] == this_team:
|
|
# team_roster.pop(self.players[x]['player']['name'], None)
|
|
# if self.effective_week != self.current['week']:
|
|
# wara -= self.players[x]['player']['wara']
|
|
#
|
|
# return {'roster': team_roster, 'wara': wara}
|
|
|
|
async def send_transaction(self):
|
|
team_id = list(self.teams.keys())[0]
|
|
moveid = f'Week-{self.effective_week:0>2}-{datetime.datetime.now().strftime("%d-%H:%M:%S")}'
|
|
moves = []
|
|
|
|
logging.warning(f'move_id: {moveid} / move_type: {self.move_type} / avoid_freeze: {self.avoid_freeze} / '
|
|
f'week: {self.current["week"]}')
|
|
if self.current['freeze'] and not self.avoid_freeze:
|
|
frozen = True
|
|
else:
|
|
frozen = False
|
|
|
|
for x in self.players:
|
|
moves.append({
|
|
'week': self.effective_week,
|
|
'player_id': self.players[x]['player']['id'],
|
|
'oldteam_id': self.players[x]['player']['team']['id'],
|
|
'newteam_id': self.players[x]['to']['id'],
|
|
'season': self.current['season'],
|
|
'moveid': moveid,
|
|
'frozen': frozen
|
|
})
|
|
|
|
await db_post('transactions', payload={'count': len(moves), 'moves': moves})
|
|
|
|
# TO BE UPDATED IF PICK DRAFTING RETURNS
|
|
# for x in self.picks:
|
|
# await patch_draftpick(self.picks[x]['pick']['id'], owner_id=self.picks[x]['to']['id'])
|
|
|
|
return moveid
|
|
|
|
def __str__(self):
|
|
trans_string = 'Players:\n'
|
|
for x in self.players:
|
|
trans_string += f'{self.players[x]}\n'
|
|
trans_string += '\nTeams:\n'
|
|
for x in self.teams:
|
|
trans_string += f'{self.teams[x]}\n'
|
|
trans_string += f'\nChannel: {self.channel}\n\nGMs:\n'
|
|
for x in self.gms:
|
|
trans_string += f'{x}\n'
|
|
|
|
return trans_string
|
|
|
|
|
|
class Transactions(commands.Cog):
|
|
def __init__(self, bot):
|
|
self.bot = bot
|
|
self.trade_season = False
|
|
|
|
self.weekly_loop.start()
|
|
|
|
@tasks.loop(minutes=1)
|
|
async def weekly_loop(self):
|
|
if OFFSEASON_FLAG:
|
|
return
|
|
|
|
current = await db_get('current')
|
|
now = datetime.datetime.now()
|
|
logging.debug(f'Datetime: {now} / weekday: {now.weekday()}')
|
|
|
|
# Begin Freeze
|
|
# if now.weekday() == 0 and now.hour == 5 and not current['freeze']: # Spring/Summer
|
|
if now.weekday() == 0 and now.hour == 0 and not current['freeze']: # Fall/Winter
|
|
current['week'] += 1
|
|
await db_patch('current', object_id=current['id'], params=[('week', current['week']), ('freeze', True)])
|
|
await self.run_transactions(current)
|
|
|
|
logging.debug(f'Building freeze string')
|
|
week_num = f'Week {current["week"]}'
|
|
stars = f'{"":*<32}'
|
|
freeze_message = f'```\n' \
|
|
f'{stars}\n'\
|
|
f'{week_num: >9} Freeze Period Begins\n' \
|
|
f'{stars}\n```'
|
|
logging.debug(f'Freeze string:\n\n{freeze_message}')
|
|
await send_to_channel(self.bot, 'transaction-log', freeze_message)
|
|
|
|
if current['week'] > 0 and current['week'] <= 18:
|
|
await self.post_weekly_info(current)
|
|
|
|
# End Freeze
|
|
# elif now.weekday() == 5 and now.hour == 5 and current['freeze']: # Spring/Summer
|
|
elif now.weekday() == 5 and now.hour == 0 and current['freeze']: # Fall/Winter
|
|
await db_patch('current', object_id=current['id'], params=[('freeze', False)])
|
|
|
|
week_num = f'Week {current["week"]}'
|
|
stars = f'{"":*<30}'
|
|
freeze_message = f'```\n' \
|
|
f'{stars}\n'\
|
|
f'{week_num: >9} Freeze Period Ends\n' \
|
|
f'{stars}\n```'
|
|
await self.process_freeze_moves(current)
|
|
await send_to_channel(self.bot, 'transaction-log', freeze_message)
|
|
self.trade_season = False
|
|
|
|
@weekly_loop.before_loop
|
|
async def before_notif_check(self):
|
|
await self.bot.wait_until_ready()
|
|
|
|
async def run_transactions(self, current):
|
|
m_query = await db_get('transactions', params=[
|
|
('season', current['season']), ('week_start', current['week']), ('week_end', current['week'])
|
|
])
|
|
if m_query['count'] == 0:
|
|
return
|
|
all_moves = m_query['transactions']
|
|
|
|
# for move in [*all_moves.values()]:
|
|
# try:
|
|
# if (move['newteam']['abbrev'][-3:] == 'MiL' and move['oldteam']['abbrev'] == 'FA') or \
|
|
# move['newteam']['abbrev'][-2:] == 'IL' or move['newteam']['abbrev'].lower() == 'fa':
|
|
# dem_week = current['week']
|
|
# else:
|
|
# dem_week = current['week'] + 1
|
|
#
|
|
# await patch_player(
|
|
# move['player']['id'],
|
|
# team_id=move['newteam']['id'],
|
|
# demotion_week=dem_week
|
|
# )
|
|
# except Exception as e:
|
|
# await send_to_channel(self.bot, 'commissioners-office', f'Error running move:\n{move["moveid"]}')
|
|
|
|
for x in all_moves:
|
|
if (x['newteam']['abbrev'][-3:] == 'MiL' and x['oldteam']['abbrev'] == 'FA') or \
|
|
x['newteam']['abbrev'][-2:] == 'IL' or x['newteam']['abbrev'] == 'FA':
|
|
dem_week = current['week']
|
|
else:
|
|
dem_week = current['week'] + 1
|
|
|
|
x['player']['team'] = x['newteam']
|
|
x['player']['demotion_week'] = dem_week
|
|
await patch_player(x['player'])
|
|
|
|
async def notify_cancel(self, trans_data):
|
|
team = trans_data[1]
|
|
guild = self.bot.get_guild(int(os.environ.get('GUILD_ID')))
|
|
|
|
cancel_text = f'Your transaction containing {trans_data[0]["name"]} has been cancelled because some douche ' \
|
|
f'with a worse team wanted him, too.'
|
|
gm_one = guild.get_member(team['gmid'])
|
|
await gm_one.send(cancel_text)
|
|
|
|
gm_two = None
|
|
if team['gmid2'] is not None:
|
|
gm_two = guild.get_member(team['gmid2'])
|
|
await gm_two.send(cancel_text)
|
|
|
|
async def process_freeze_moves(self, current):
|
|
# all_moves = await get_transactions(
|
|
# season=current['season'],
|
|
# week_start=current['week'],
|
|
# week_end=current['week'] + 1,
|
|
# frozen=True
|
|
# )
|
|
m_query = await db_get('transactions', params=[
|
|
('season', current['season']), ('week_start', current['week']), ('week_end', current['week'] + 1),
|
|
('frozen', True)
|
|
])
|
|
if m_query['count'] == 0:
|
|
logging.warning(f'No transactions to process for the freeze in week {current["week"]}')
|
|
return
|
|
|
|
moves = m_query['transactions']
|
|
logging.info(f'freeze / all_moves: {len(moves)}')
|
|
|
|
# {'player name': [[Player, TeamAdding, moveid], [Player, OtherTeamAdding, moveid]]}
|
|
added_players = {}
|
|
contested_players = {}
|
|
|
|
for move in moves:
|
|
if move['newteam']['abbrev'][-3:] == 'MiL':
|
|
new_team = await get_team_by_abbrev(move['newteam']['abbrev'][:-3], current['season'])
|
|
else:
|
|
new_team = move['newteam']
|
|
# team_record = await get_team_record(new_team, week_num=current["week"])
|
|
|
|
if new_team['abbrev'] == 'FA':
|
|
win_pct = 0
|
|
else:
|
|
r_query = await db_get('standings', params=[
|
|
('season', current['season']), ('team_id', new_team['id'])
|
|
])
|
|
win_pct = r_query['standings'][0]['wins'] / (
|
|
r_query['standings'][0]['wins'] + r_query['standings'][0]['losses'])
|
|
|
|
tiebreaker = win_pct + (random.randint(10000, 99999) * .00000001)
|
|
if move["player"]["name"] not in added_players.keys():
|
|
added_players[move["player"]["name"]] = [[move["player"], move["newteam"], tiebreaker, move["moveid"]]]
|
|
else:
|
|
added_players[move["player"]["name"]].append(
|
|
[move["player"], move["newteam"], tiebreaker, move["moveid"]]
|
|
)
|
|
logging.info(f'freeze / added_players: {added_players.keys()}')
|
|
|
|
# Check added_players for keys (player names) with more than one move in their list
|
|
for name in added_players:
|
|
if len(added_players[name]) > 1:
|
|
contested_players[name] = added_players[name]
|
|
logging.info(f'freeze / contested_players: {contested_players.keys()}')
|
|
|
|
# Determine winner for contested players, mark moveid cancelled for loser
|
|
def tiebreaker(val):
|
|
logging.info(f'tiebreaker: {val}')
|
|
return val[2]
|
|
|
|
for guy in contested_players:
|
|
contested_players[guy].sort(key=tiebreaker)
|
|
first = True
|
|
logging.info(f'Contested Player: {contested_players[guy]}\n\n')
|
|
for x in contested_players[guy]:
|
|
logging.info(f'First: {first} / x: {x}\n\n')
|
|
if not first:
|
|
await db_patch('transactions', object_id=x[3], params=[('frozen', False), ('cancelled', True)])
|
|
# await patch_transaction(move_id=x[3], cancelled=True, frozen=False)
|
|
await self.notify_cancel(x)
|
|
else:
|
|
first = False
|
|
|
|
# Post transactions that are not cancelled
|
|
# final_moves = await get_transactions(
|
|
# season=current['season'],
|
|
# week_start=current["week"],
|
|
# week_end=current["week"] + 1,
|
|
# frozen=True
|
|
# )
|
|
m_query = await db_get('transactions', params=[
|
|
('season', current['season']), ('week_start', current['week']), ('week_end', current['week'] + 1),
|
|
('frozen', True)
|
|
])
|
|
final_moves = m_query['transactions']
|
|
|
|
these_ids = []
|
|
for x in final_moves:
|
|
if x["moveid"] not in these_ids:
|
|
these_ids.append(x["moveid"])
|
|
|
|
# TODO: not sure I like this method of running moves
|
|
for move_id in these_ids:
|
|
# await patch_transaction(move_id, frozen=False)
|
|
await db_patch('transactions', object_id=move_id, params=[('frozen', False)])
|
|
await self.post_move_to_transaction_log(move_id)
|
|
|
|
# async def send_move_to_sheets(self, move_id):
|
|
# return
|
|
# current = await db_get('current')
|
|
# sheets = pygsheets.authorize(service_file='storage/major-domo-service-creds.json')
|
|
# trans_tab = sheets.open_by_key(SBA_ROSTER_KEY).worksheet_by_title('Transactions')
|
|
# all_vals = []
|
|
# all_moves = await get_transactions(
|
|
# season=current['season'],
|
|
# move_id=move_id
|
|
# )
|
|
#
|
|
# counter = 0
|
|
# for move in [*all_moves.values()]:
|
|
# all_vals.append([
|
|
# move['player']['name'],
|
|
# move['oldteam']['sname'],
|
|
# move['newteam']['sname'],
|
|
# move['week'],
|
|
# current['transcount'] + counter
|
|
# ])
|
|
# counter += 1
|
|
#
|
|
# try:
|
|
# trans_tab.update_values(
|
|
# crange=f'A{current["transcount"] + 3}',
|
|
# values=all_vals
|
|
# )
|
|
# await patch_current(transcount=current['transcount'] + counter)
|
|
# except Exception as e:
|
|
# await send_to_channel(self.bot, 'commissioners-office', f'Failed sending move {move_id} to sheets')
|
|
|
|
async def post_move_to_transaction_log(self, move_id):
|
|
current = await db_get('current')
|
|
# all_moves = await get_transactions(
|
|
# season=current['season'],
|
|
# move_id=move_id
|
|
# )
|
|
m_query = await db_get('transactions', params=[
|
|
('season', current['season']), ('move_id', move_id)
|
|
])
|
|
all_moves = m_query['transactions']
|
|
|
|
this_team = None
|
|
week_num = None
|
|
move_string = ''
|
|
|
|
for move in all_moves:
|
|
if this_team is None:
|
|
if move['newteam']['abbrev'] != 'FA' and 'IL' not in move['newteam']['abbrev']:
|
|
this_team = move['newteam']
|
|
else:
|
|
this_team = move['oldteam']
|
|
|
|
if move['oldteam']['abbrev'] != 'FA' and 'IL' not in move['oldteam']['abbrev']:
|
|
this_team = move['oldteam']
|
|
|
|
if week_num is None:
|
|
week_num = move['week']
|
|
|
|
move_string += f'**{move["player"]["name"]}** ({move["player"]["wara"]}) from ' \
|
|
f'{move["oldteam"]["abbrev"]} to {move["newteam"]["abbrev"]}\n'
|
|
|
|
embed = get_team_embed(f'Week {week_num} Transaction', this_team)
|
|
embed.description = this_team['sname']
|
|
embed.add_field(name='Player Moves', value=move_string)
|
|
|
|
await send_to_channel(self.bot, 'transaction-log', embed=embed)
|
|
|
|
async def post_weekly_info(self, current):
|
|
guild = self.bot.get_guild(int(os.environ.get('GUILD_ID')))
|
|
info_channel = discord.utils.get(guild.text_channels, name='weekly-info')
|
|
async for message in info_channel.history(limit=25):
|
|
await message.delete()
|
|
|
|
night_str = '\U0001F319 Night'
|
|
day_str = '\U0001F31E Day'
|
|
|
|
season_str = f'\U0001F3D6 **Summer**'
|
|
if current['week'] <= 5:
|
|
season_str = f'\U0001F33C **Spring**'
|
|
elif current['week'] > 14:
|
|
season_str = f'\U0001F342 **Fall**'
|
|
|
|
is_div_week = current['week'] in [1, 3, 6, 14, 16, 18]
|
|
|
|
weekly_str = f'**Season**: {season_str}\n' \
|
|
f'**Time of Day**: {night_str} / {night_str if is_div_week else day_str} / ' \
|
|
f'{night_str} / {day_str}'
|
|
|
|
await info_channel.send(
|
|
content=f'Each team has manage permissions in their home ballpark. They may pin messages and rename the '
|
|
f'channel.\n\n**Make sure your ballpark starts with your team abbreviation.**'
|
|
)
|
|
await info_channel.send(weekly_str)
|
|
|
|
# async def send_stats_to_sheets(self, channel='commissioners-office', which='all'):
|
|
# current = await db_get('current')
|
|
# b_stats = None
|
|
# p_stats = None
|
|
#
|
|
# if which == 'all' or which == 'batting':
|
|
# await send_to_channel(self.bot, channel, 'Collecting batting stats...')
|
|
# b_stats = await get_battingstat(current['season'], timeout=90)
|
|
#
|
|
# if which == 'all' or which == 'pitching':
|
|
# await send_to_channel(self.bot, channel, 'Collecting pitching stats...')
|
|
# p_stats = await get_pitchingstat(current['season'], timeout=90)
|
|
#
|
|
# sheets = pygsheets.authorize(service_file='storage/major-domo-service-creds.json')
|
|
# if b_stats:
|
|
# await send_to_channel(self.bot, channel, f'Preparing batting stats ({len(b_stats)} lines found)...')
|
|
# batting_stats = []
|
|
#
|
|
# for x in [*b_stats.values()]:
|
|
# batting_stats.append([
|
|
# x['player']['name'], x['team']['abbrev'], x['pos'], x['pa'], x['ab'], x['run'], x['hit'], x['rbi'],
|
|
# x['double'], x['triple'], x['hr'], x['bb'], x['so'], x['hbp'], x['sac'], x['ibb'], x['gidp'],
|
|
# x['sb'], x['cs'], x['xch'], x['xhit'], x['error'], x['pb'], x['sbc'], x['csc'], x['week'],
|
|
# x['game'], f'{x["week"]}.{x["game"]}'
|
|
# ])
|
|
# await patch_current(bstatcount=len(batting_stats))
|
|
# await send_to_channel(self.bot, channel, f'Sending {len(batting_stats)} batting lines...')
|
|
# sheets.open_by_key(SBA_STATS_KEY).worksheet_by_title('Batting Data').update_values(
|
|
# crange='A2',
|
|
# values=batting_stats
|
|
# )
|
|
# await send_to_channel(self.bot, channel, f'Batting stats have been sent')
|
|
# elif which == 'all' or which == 'batting':
|
|
# await send_to_channel(self.bot, channel, 'No batting stats found')
|
|
#
|
|
# if p_stats:
|
|
# await send_to_channel(self.bot, channel, f'Preparing pitching stats ({len(p_stats)} lines found)...')
|
|
# pitching_stats = []
|
|
#
|
|
# for x in [*p_stats.values()]:
|
|
# pitching_stats.append([
|
|
# x['player']['name'], x['team']['abbrev'], x['ip'], x['hit'], x['run'], x['erun'], x['so'], x['bb'],
|
|
# x['hbp'], x['wp'], x['balk'], x['hr'], 1 if x['gs'] else 0, 1 if x['win'] else 0,
|
|
# 1 if x['loss'] else 0, 1 if x['hold'] else 0, 1 if x['sv'] else 0, 1 if x['bsv'] else 0, x['week'],
|
|
# x['game'], f'{x["week"]}.{x["game"]}'
|
|
# ])
|
|
# await patch_current(pstatcount=len(pitching_stats))
|
|
# await send_to_channel(self.bot, channel, f'Sending {len(pitching_stats)} pitching lines...')
|
|
# sheets.open_by_key(SBA_STATS_KEY).worksheet_by_title('Pitching Data').update_values(
|
|
# crange='A2',
|
|
# values=pitching_stats
|
|
# )
|
|
# await send_to_channel(self.bot, channel, f'Pitching stats have been sent')
|
|
# elif which == 'all' or which == 'pitching':
|
|
# await send_to_channel(self.bot, channel, 'No pitching stats found')
|
|
|
|
# async def update_roster_sheet(self, season):
|
|
# logging.info(f'calling the db')
|
|
# # csv_data = db_get('players', api_ver=3, params=[('season', 6), ('csv', True)], as_csv=True)
|
|
# # csv = DataFrame(csv_data).to_csv(header=False, index=False)
|
|
# # csv = pandas.read_csv(csv_data)
|
|
#
|
|
# ap = await db_get('players', api_ver=3, timeout=8, params=[('season', season)])
|
|
# player_data = [
|
|
# ['name', 'sWAR', 'image', 'vanity_card', 'team_abbrev', 'inj_rat', 'pos_1', 'pos_2', 'pos_3', 'pos_4',
|
|
# 'pos_5', 'pos_6', 'pos_7', 'pos_8', 'last_game', 'last_game2', 'il_return', 'dem_week', 'strat_code',
|
|
# 'bbref_id']
|
|
# ]
|
|
# for x in ap:
|
|
# player_data.append([
|
|
# ap[x]['name'], ap[x]['wara'], ap[x]['image'], ap[x]['vanity_card'], ap[x]['team']['abbrev'],
|
|
# ap[x]['injury_rating'], ap[x]['pos_1'], ap[x]['pos_2'], ap[x]['pos_3'], ap[x]['pos_4'], ap[x]['pos_5'],
|
|
# ap[x]['pos_6'], ap[x]['pos_7'], ap[x]['pos_8'], ap[x]['last_game'], ap[x]['last_game2'],
|
|
# ap[x]['il_return'], ap[x]['demotion_week'], ap[x]['strat_code'], ap[x]['bbref_id']
|
|
# ])
|
|
# # logging.info(f'\n\nCSV:\n{player_data}\n')
|
|
# # auth sheets
|
|
# logging.info(f'authorizing sheets')
|
|
# sheets = pygsheets.authorize(service_file='storage/major-domo-service-creds.json', retries=1)
|
|
# # get sheet
|
|
# logging.info(f'getting sheet')
|
|
# master_sheet = sheets.open_by_key(SBA_ROSTER_KEY)
|
|
# # get worksheet
|
|
# logging.info(f'getting worksheet')
|
|
# roster_sheet = master_sheet.worksheet_by_title('API Import')
|
|
#
|
|
# logging.info(f'updating values')
|
|
# roster_sheet.update_values(
|
|
# crange='A1',
|
|
# values=player_data
|
|
# )
|
|
|
|
@staticmethod
|
|
def on_team_il(team, player):
|
|
player_team_abbrev = player['team']['abbrev']
|
|
sil_abbrev = f'{team["abbrev"]}IL'
|
|
mil_abbrev = f'{team["abbrev"]}MiL'
|
|
|
|
if player_team_abbrev in [sil_abbrev, mil_abbrev]:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
@commands.command(name='run_transactions')
|
|
@commands.is_owner()
|
|
async def run_transactions_helper_command(self, ctx):
|
|
current = await db_get('current')
|
|
await self.run_transactions(current)
|
|
await ctx.send(new_rand_conf_gif())
|
|
|
|
@commands.command(name='process_freeze')
|
|
@commands.is_owner()
|
|
async def process_freeze_helper_command(self, ctx):
|
|
current = await db_get('current')
|
|
await self.process_freeze_moves(current)
|
|
await ctx.send(random_conf_gif())
|
|
|
|
@commands.command(name='post-weekly')
|
|
@commands.is_owner()
|
|
async def post_weekly_info_command(self, ctx):
|
|
await self.post_weekly_info(await db_get('current'))
|
|
|
|
@commands.command(
|
|
name='trade', aliases=['tradeplz', 'pleasetrade', 'tradeplease', 'plztrade'], help='Trade players')
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def trade_command(self, ctx):
|
|
current = await db_get('current')
|
|
|
|
if current['week'] > current['trade_deadline']:
|
|
await ctx.send(await get_emoji(ctx, 'oof', False))
|
|
await ctx.send(f'The trade deadline is **week {current["trade_deadline"]}**. Since it is currently **week '
|
|
f'{current["week"]}** I am just going to stop you right there.')
|
|
return
|
|
if current['week'] < -2:
|
|
await ctx.send(await get_emoji(ctx, 'oof', False))
|
|
await ctx.send(f'Patience, grasshopper. Trades open soon.')
|
|
return
|
|
|
|
team = await get_team_by_owner(current['season'], ctx.author.id)
|
|
team_role = get_team_role(ctx, team)
|
|
player_cog = self.bot.get_cog('Players')
|
|
poke_role = get_role(ctx, 'Pokétwo')
|
|
|
|
# Create trade channel
|
|
overwrites = {ctx.guild.default_role: discord.PermissionOverwrite(read_messages=False),
|
|
team_role: discord.PermissionOverwrite(read_messages=True),
|
|
ctx.guild.me: discord.PermissionOverwrite(read_messages=True),
|
|
poke_role: discord.PermissionOverwrite(read_messages=True, send_messages=False)}
|
|
|
|
try:
|
|
t_channel = await ctx.guild.create_text_channel(
|
|
f'{team["abbrev"]}-trade',
|
|
overwrites=overwrites,
|
|
category=discord.utils.get(ctx.guild.categories, name=f'Transactions')
|
|
)
|
|
# t_channel = await create_channel(
|
|
# ctx,
|
|
# channel_name=f'{team["abbrev"]}-trade',
|
|
# category_name=f'Transactions',
|
|
# everyone_read=False,
|
|
# read_send_roles=team_role
|
|
# )
|
|
except Exception as e:
|
|
await ctx.send(f'{e}\n\n'
|
|
f'Discord is having issues creating private channels right now. Please try again later.')
|
|
return
|
|
|
|
# Create trade and post to channel
|
|
trade = SBaTransaction(t_channel, current, 'trade', first_team=team, team_role=team_role)
|
|
await trade.send(f'Let\'s start here, {team_role.mention}.')
|
|
await ctx.send(f'Take my hand... {trade.channel.mention}')
|
|
intro = await trade.send(
|
|
'First, we will add each team involved in the trade. Then I will have you enter each of the players '
|
|
'involved with the trade and where they are going.\n\nOnce that is done, each of the teams involved '
|
|
'will need to confirm the trade.'
|
|
)
|
|
await intro.pin()
|
|
|
|
# Add teams loop
|
|
while True:
|
|
prompt = 'Are you adding a team to this deal? (Yes/No)'
|
|
this_q = Question(self.bot, trade.channel, prompt, 'yesno', 30)
|
|
resp = await this_q.ask(trade.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await trade.send('RIP this move. Maybe next time.')
|
|
await trade.timed_delete()
|
|
return
|
|
elif not resp:
|
|
break
|
|
else:
|
|
this_q.prompt = 'Please enter the team\'s abbreviation.'
|
|
this_q.qtype = 'text'
|
|
resp = await this_q.ask(trade.get_gms(self.bot))
|
|
|
|
if not resp:
|
|
await trade.send('RIP this move. Maybe next time.')
|
|
await trade.timed_delete()
|
|
return
|
|
else:
|
|
try:
|
|
next_team = await get_team_by_abbrev(resp, current['season'])
|
|
except ValueError:
|
|
await trade.send('Who the fuck even is that? Try again.')
|
|
else:
|
|
next_team_role = get_team_role(ctx, next_team)
|
|
overwrites[next_team_role] = discord.PermissionOverwrite(read_messages=True)
|
|
await trade.channel.edit(overwrites=overwrites)
|
|
trade.add_team(next_team, next_team_role)
|
|
await trade.send(f'Welcome to the trade, {next_team_role.mention}!')
|
|
|
|
# Get player trades
|
|
while True:
|
|
prompt = f'Are you trading a player between teams?'
|
|
this_q = Question(self.bot, trade.channel, prompt, 'yesno', 300)
|
|
resp = await this_q.ask(trade.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await trade.send('RIP this move. Maybe next time.')
|
|
await trade.timed_delete()
|
|
return
|
|
elif not resp:
|
|
break
|
|
else:
|
|
this_q.prompt = 'Which player is being traded?'
|
|
this_q.qtype = 'text'
|
|
resp = await this_q.ask(trade.get_gms(self.bot))
|
|
|
|
if not resp:
|
|
pass
|
|
else:
|
|
try:
|
|
player = await get_player_by_name(
|
|
current['season'],
|
|
await fuzzy_player_search(ctx, trade.channel, self.bot, resp, player_cog.player_list.keys())
|
|
)
|
|
except ValueError:
|
|
await trade.send(f'{await get_emoji(ctx, "squint")}')
|
|
await trade.send('Who even is that? Try again.')
|
|
except requests.ReadTimeout:
|
|
await trade.send(
|
|
f'I\'m dumb and couldn\'t read from the database fast enough. '
|
|
f'{await get_emoji(ctx, "dead")} Let\'s try that again.'
|
|
)
|
|
else:
|
|
# Check that player is on one of the teams
|
|
# Check that the player hasn't been dropped (IL is okay)
|
|
if not trade.included_team(player['team']):
|
|
await trade.send(f'You know that {player["name"]} is on {player["team"]["abbrev"]}, right? '
|
|
f'They\'re not part of this trade so...nah.')
|
|
elif await trade.not_available(player):
|
|
await trade.send(f'Ope. {player["name"]} is already one the move next week.')
|
|
else:
|
|
this_q.prompt = 'Where are they going? Please enter the destination team\'s abbreviation.'
|
|
resp = await this_q.ask(trade.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await trade.send('RIP this move. Maybe next time.')
|
|
await trade.timed_delete()
|
|
else:
|
|
try:
|
|
dest_team = await get_team_by_abbrev(resp, current['season'])
|
|
except ValueError:
|
|
await trade.send(f'{await get_emoji(ctx, "facepalm")} They aren\'t even part of '
|
|
f'this trade. Come on.')
|
|
else:
|
|
if player['team'] == dest_team:
|
|
await trade.send(f'{await get_emoji(ctx, "lolwhat")} {player["name"]} '
|
|
f'is already on {dest_team["abbrev"]}.')
|
|
elif not trade.included_team(dest_team):
|
|
await trade.send(f'{await get_emoji(ctx, "lolwhat")} {dest_team["abbrev"]} '
|
|
f'isn\'t even part of this trade.')
|
|
else:
|
|
await trade.add_player(player, dest_team)
|
|
|
|
await trade.show_moves()
|
|
|
|
# Get pick trades
|
|
# while True and current['pick_trade_end'] >= current['week'] >= current['pick_trade_start']:
|
|
# prompt = f'Are you trading any draft picks?'
|
|
# this_q = Question(self.bot, trade.channel, prompt, 'yesno', 300)
|
|
# resp = await this_q.ask(trade.get_gms(self.bot))
|
|
# effective_season = current['season'] if OFFSEASON_FLAG else current['season'] + 1
|
|
# team_season = current['season']
|
|
#
|
|
# if resp is None:
|
|
# await trade.send('RIP this move. Maybe next time.')
|
|
# await trade.timed_delete()
|
|
# return
|
|
# elif not resp:
|
|
# break
|
|
# else:
|
|
# # Get first pick
|
|
# this_q.prompt = 'Enter the pick\'s original owner and round number like this: TIT 17'
|
|
# this_q.qtype = 'text'
|
|
# resp = await this_q.ask(trade.get_gms(self.bot))
|
|
#
|
|
# if not resp:
|
|
# await trade.send('RIP this move. Maybe next time.')
|
|
# await trade.timed_delete()
|
|
# return
|
|
# else:
|
|
# team_abbrev = resp.split(' ')[0]
|
|
# round_num = resp.split(' ')[1]
|
|
# try:
|
|
# first_pick = await get_one_draftpick_search(
|
|
# effective_season,
|
|
# orig_owner_abbrev=team_abbrev,
|
|
# round_num=round_num,
|
|
# team_season=team_season
|
|
# )
|
|
# except Exception as e:
|
|
# await trade.send(f'Uh oh, I couldn\'t find **{team_abbrev} {round_num}**. Check the team and '
|
|
# f'round number, please.')
|
|
# else:
|
|
# this_q.prompt = 'Now enter the return pick\'s original owner and round number like this: TIT 17'
|
|
# resp = await this_q.ask(trade.get_gms(self.bot))
|
|
#
|
|
# if not resp:
|
|
# await trade.send('RIP this move. Maybe next time.')
|
|
# await trade.timed_delete()
|
|
# return
|
|
# else:
|
|
# team_abbrev = resp.split(' ')[0]
|
|
# round_num = resp.split(' ')[1]
|
|
# try:
|
|
# second_pick = await get_one_draftpick_search(
|
|
# effective_season,
|
|
# orig_owner_abbrev=team_abbrev,
|
|
# round_num=round_num,
|
|
# team_season=team_season
|
|
# )
|
|
# except Exception as e:
|
|
# await trade.send(
|
|
# f'Uh oh, I couldn\'t find **{team_abbrev} {round_num}**. Check the team and '
|
|
# f'round number, please.')
|
|
# else:
|
|
# team_getting_first_pick = second_pick['owner']
|
|
# team_getting_second_pick = first_pick['owner']
|
|
#
|
|
# if not trade.included_team(first_pick['owner']):
|
|
# await trade.send(
|
|
# f'Imma let you finish, but **{first_pick["owner"]["abbrev"]}** currently holds '
|
|
# f'{first_pick["origowner"]["abbrev"]} {first_pick["round"]} and are not part '
|
|
# f'of this deal so let\'s try this again.'
|
|
# )
|
|
# else:
|
|
# if not trade.included_team(second_pick['owner']):
|
|
# await trade.send(
|
|
# f'Imma let you finish, but **{second_pick["owner"]["abbrev"]}** currently '
|
|
# f'holds {second_pick["origowner"]["abbrev"]} {second_pick["round"]} and '
|
|
# f'are not part of this deal so let\'s try this again.'
|
|
# )
|
|
# else:
|
|
# await trade.add_pick(first_pick, team_getting_first_pick)
|
|
# await trade.add_pick(second_pick, team_getting_second_pick)
|
|
#
|
|
# await trade.show_moves()
|
|
|
|
# FA drops per team
|
|
|
|
if current['week'] > 0:
|
|
for team in trade.teams:
|
|
while True:
|
|
this_q.prompt = f'{trade.teams[team]["role"].mention}\nAre you making an FA drop?'
|
|
this_q.qtype = 'yesno'
|
|
resp = await this_q.ask(trade.get_gms(self.bot, team))
|
|
|
|
if resp is None:
|
|
await trade.send('RIP this move. Maybe next time.')
|
|
await trade.timed_delete()
|
|
return
|
|
elif not resp:
|
|
break
|
|
else:
|
|
this_q.prompt = 'Who are you dropping?'
|
|
this_q.qtype = 'text'
|
|
resp = await this_q.ask(trade.get_gms(self.bot, team))
|
|
|
|
if resp is None:
|
|
await trade.send('RIP this move. Maybe next time.')
|
|
await trade.timed_delete()
|
|
return
|
|
else:
|
|
try:
|
|
player = await get_player_by_name(
|
|
current['season'],
|
|
await fuzzy_player_search(ctx, trade.channel, self.bot, resp,
|
|
player_cog.player_list.keys())
|
|
)
|
|
except ValueError:
|
|
await trade.send(f'{await get_emoji(ctx, "squint")}')
|
|
await trade.send('Who even is that? Try again.')
|
|
except requests.ReadTimeout:
|
|
await trade.send(
|
|
f'I\'m dumb and couldn\'t read from the database fast enough. '
|
|
f'{await get_emoji(ctx, "dead")} Let\'s try that again.'
|
|
)
|
|
else:
|
|
if not trade.included_team(player['team']):
|
|
await t_channel.send(f'It looks like {player.name} is on {player.team.abbrev} '
|
|
f'so I can\'t let you do that.')
|
|
# elif player['demotion_week'] > current['week']:
|
|
# await trade.send(f'Oof. {player["name"]} cannot be dropped until week '
|
|
# f'{player["demotion_week"]}.')
|
|
else:
|
|
dest_team = await get_team_by_abbrev('FA', current['season'])
|
|
await trade.add_player(player, dest_team)
|
|
|
|
await trade.show_moves()
|
|
|
|
# Check for empty move
|
|
if len(trade.players) + len(trade.picks) == 0:
|
|
await trade.send(f'This has been fun. Come again and maybe do something next time.')
|
|
await trade.timed_delete()
|
|
return
|
|
|
|
# Check legality for all teams
|
|
errors = []
|
|
roster_errors = []
|
|
for team in trade.teams:
|
|
data = await trade.check_major_league_errors(team)
|
|
logging.warning(f'Done checking data - checking sWAR now ({data["wara"]}')
|
|
|
|
if data['wara'] > 32.001 and not OFFSEASON_FLAG:
|
|
errors.append(f'- {trade.teams[team]["team"]["abbrev"]} would have {data["wara"]:.2f} WARa')
|
|
|
|
logging.warning(f'Now checking roster {len(data["roster"])}')
|
|
if len(data['roster']) > 26 and not OFFSEASON_FLAG:
|
|
errors.append(f'- {trade.teams[team]["team"]["abbrev"]} would have {len(data["roster"])} players')
|
|
|
|
logging.warning(f'Any errors? {errors}')
|
|
if (data['wara'] > 32.001 or len(data['roster']) > 26) and not OFFSEASON_FLAG:
|
|
roster_string = ''
|
|
for x in data['roster']:
|
|
roster_string += f'{x["wara"]: >5} - {x["name"]}\n'
|
|
roster_errors.append(f'- This is the roster I have for {trade.teams[team]["team"]["abbrev"]}:\n'
|
|
f'```\n{roster_string}```')
|
|
|
|
if len(errors) + len(roster_errors) > 0:
|
|
error_message = '\n'.join(errors)
|
|
await trade.send(f'Yikes. I\'m gonna put the kibosh on this trade. Below is why:\n\n{error_message}')
|
|
if len(roster_errors) > 0:
|
|
for x in roster_errors:
|
|
await trade.send(x)
|
|
await trade.timed_delete()
|
|
return
|
|
|
|
# Ask for each team's explict confirmation
|
|
for team in trade.teams:
|
|
this_q.prompt = f'{trade.teams[team]["role"].mention}\nDo you accept this trade?'
|
|
this_q.qtype = 'yesno'
|
|
resp = await this_q.ask(trade.get_gms(self.bot, team))
|
|
|
|
if not resp:
|
|
await trade.send('RIP this move. Maybe next time.')
|
|
await trade.timed_delete()
|
|
return
|
|
else:
|
|
await trade.show_moves()
|
|
|
|
# Run moves
|
|
trans_id = await trade.send_transaction()
|
|
|
|
await send_to_channel(self.bot, 'transaction-log', embed=await trade.show_moves(here=False))
|
|
|
|
await trade.send(f'All done! Your transaction id is: {trans_id}')
|
|
try:
|
|
choas = get_role(ctx, 'CHOAS ALERT')
|
|
await send_to_channel(self.bot, f'season-{current["season"]}-chat', f'{choas.mention}')
|
|
except Exception as e:
|
|
logging.error(f'Couldn\'t ping chaos for a trade')
|
|
await trade.timed_delete()
|
|
|
|
# @commands.command(name='picktrade', help='Trade draft picks', hidden=True)
|
|
# @commands.is_owner()
|
|
# async def pick_trade_command(self, ctx):
|
|
# current = await db_get('current')
|
|
#
|
|
# if current['week'] < -2:
|
|
# await ctx.send(await get_emoji(ctx, 'oof', False))
|
|
# await ctx.send(f'Patience, grasshopper. Trades open up Monday.')
|
|
# return
|
|
# if not OFFSEASON_FLAG:
|
|
# await ctx.send(await get_emoji(ctx, 'oof', False))
|
|
# await ctx.send(f'You\'ll have to wait, hoss. No pick trades until the offseason.')
|
|
# return
|
|
#
|
|
# team = await get_team_by_owner(current['season'], ctx.author.id)
|
|
# team_role = get_team_role(ctx, team)
|
|
# player_cog = self.bot.get_cog('Players')
|
|
#
|
|
# # Create trade channel
|
|
# overwrites = {ctx.guild.default_role: discord.PermissionOverwrite(read_messages=False),
|
|
# team_role: discord.PermissionOverwrite(read_messages=True),
|
|
# ctx.guild.me: discord.PermissionOverwrite(read_messages=True)}
|
|
#
|
|
# try:
|
|
# # t_channel = await ctx.guild.create_text_channel(
|
|
# # f'{team["abbrev"]}-trade',
|
|
# # overwrites=overwrites,
|
|
# # category=discord.utils.get(ctx.guild.categories, name=f'Transactions')
|
|
# # )
|
|
# t_channel = await create_channel(
|
|
# ctx,
|
|
# channel_name=f'{team["abbrev"]}-trade',
|
|
# category_name=f'Transactions',
|
|
# everyone_read=False,
|
|
# read_send_roles=team_role
|
|
# )
|
|
# except Exception as e:
|
|
# await ctx.send(f'{e}\n\n'
|
|
# f'Discord is having issues creating private channels right now. Please try again later.')
|
|
# return
|
|
#
|
|
# # Create trade and post to channel
|
|
# trade = SBaTransaction(t_channel, current, 'trade', first_team=team, team_role=team_role)
|
|
# await trade.send(f'Let\'s start here, {team_role.mention}.')
|
|
# await ctx.send(f'Take my hand... {trade.channel.mention}')
|
|
# intro = await trade.send(
|
|
# 'Alrighty, let\'s collect the pick trades. Once they are all entered, each of the teams involved '
|
|
# 'will need to confirm the trade.'
|
|
# )
|
|
# await intro.pin()
|
|
#
|
|
# # Add teams loop
|
|
# while True:
|
|
# prompt = 'Are you adding a team to this deal? (Yes/No)'
|
|
# this_q = Question(self.bot, trade.channel, prompt, 'yesno', 30)
|
|
# resp = await this_q.ask(trade.get_gms(self.bot))
|
|
#
|
|
# if resp is None:
|
|
# await trade.send('RIP this move. Maybe next time.')
|
|
# await trade.timed_delete()
|
|
# return
|
|
# elif not resp:
|
|
# break
|
|
# else:
|
|
# this_q.prompt = 'Please enter the team\'s abbreviation.'
|
|
# this_q.qtype = 'text'
|
|
# resp = await this_q.ask(trade.get_gms(self.bot))
|
|
#
|
|
# if not resp:
|
|
# await trade.send('RIP this move. Maybe next time.')
|
|
# await trade.timed_delete()
|
|
# return
|
|
# else:
|
|
# try:
|
|
# next_team = await get_team_by_abbrev(resp, current['season'])
|
|
# except ValueError:
|
|
# await trade.send('Who the fuck even is that? Try again.')
|
|
# else:
|
|
# next_team_role = get_team_role(ctx, next_team)
|
|
# overwrites[next_team_role] = discord.PermissionOverwrite(read_messages=True)
|
|
# await trade.channel.edit(overwrites=overwrites)
|
|
# trade.add_team(next_team, next_team_role)
|
|
# await trade.send(f'Welcome to the trade, {next_team_role.mention}!')
|
|
#
|
|
# # Get pick trades
|
|
# while True:
|
|
# prompt = f'Are you trading any draft picks?'
|
|
# this_q = Question(self.bot, trade.channel, prompt, 'yesno', 300)
|
|
# resp = await this_q.ask(trade.get_gms(self.bot))
|
|
# effective_season = current['season'] if OFFSEASON_FLAG else current['season'] + 1
|
|
# team_season = current['season']
|
|
#
|
|
# if resp is None:
|
|
# await trade.send('RIP this move. Maybe next time.')
|
|
# await trade.timed_delete()
|
|
# return
|
|
# elif not resp:
|
|
# break
|
|
# else:
|
|
# # Get first pick
|
|
# this_q.prompt = 'Enter the overall pick number being traded.'
|
|
# this_q.qtype = 'int'
|
|
# resp = await this_q.ask(trade.get_gms(self.bot))
|
|
#
|
|
# if not resp:
|
|
# await trade.send('RIP this move. Maybe next time.')
|
|
# await trade.timed_delete()
|
|
# return
|
|
# else:
|
|
# try:
|
|
# first_pick = await get_one_draftpick_byoverall(
|
|
# effective_season,
|
|
# overall=resp
|
|
# )
|
|
# except Exception as e:
|
|
# await trade.send(f'Frick, I couldn\'t find pick #{resp}.')
|
|
# else:
|
|
# this_q.prompt = 'Now enter the return pick\'s overall pick number.'
|
|
# resp = await this_q.ask(trade.get_gms(self.bot))
|
|
#
|
|
# if not resp:
|
|
# await trade.send('RIP this move. Maybe next time.')
|
|
# await trade.timed_delete()
|
|
# return
|
|
# else:
|
|
# try:
|
|
# second_pick = await get_one_draftpick_byoverall(
|
|
# effective_season,
|
|
# overall=resp
|
|
# )
|
|
# except Exception as e:
|
|
# await trade.send(f'Frick, I couldn\'t find pick #{resp}.')
|
|
# else:
|
|
# team_getting_first_pick = second_pick['owner']
|
|
# team_getting_second_pick = first_pick['owner']
|
|
#
|
|
# if not trade.included_team(first_pick['owner']):
|
|
# await trade.send(
|
|
# f'Ope. **{first_pick["owner"]["abbrev"]}** currently holds '
|
|
# f'{first_pick["origowner"]["abbrev"]} {first_pick["round"]} and are not part '
|
|
# f'of this deal so let\'s try this again.'
|
|
# )
|
|
# else:
|
|
# if not trade.included_team(second_pick['owner']):
|
|
# await trade.send(
|
|
# f'Imma let you finish, but **{second_pick["owner"]["abbrev"]}** currently '
|
|
# f'holds {second_pick["origowner"]["abbrev"]} {second_pick["round"]} and '
|
|
# f'are not part of this deal so let\'s try this again.'
|
|
# )
|
|
# else:
|
|
# await trade.add_pick(first_pick, team_getting_first_pick)
|
|
# await trade.add_pick(second_pick, team_getting_second_pick)
|
|
#
|
|
# await trade.show_moves()
|
|
#
|
|
# # Check for empty move
|
|
# if len(trade.players) + len(trade.picks) == 0:
|
|
# await trade.send(f'This has been fun. Come again and maybe do something next time.')
|
|
# await trade.timed_delete()
|
|
# return
|
|
#
|
|
# # Check legality for all teams
|
|
# errors = []
|
|
# for team in trade.teams:
|
|
# data = await trade.check_major_league_errors(team)
|
|
# logging.warning(f'Done checking data - checking WARa now ({data["wara"]}')
|
|
#
|
|
# if data['wara'] > 32.001:
|
|
# errors.append(f'- {trade.teams[team]["team"]["abbrev"]} would have {data["wara"]:.2f} WARa')
|
|
#
|
|
# logging.warning(f'Now checking roster {len(data["roster"])}')
|
|
# if len(data['roster']) > 26:
|
|
# errors.append(f'- {trade.teams[team]["team"]["abbrev"]} would have {len(data["roster"])} players')
|
|
#
|
|
# logging.warning(f'Any errors? {errors}')
|
|
# if data['wara'] > 32.001 or len(data['roster']) > 26:
|
|
# roster_string = ''
|
|
# for x in data['roster']:
|
|
# roster_string += f'{data["roster"][x]["wara"]: >5} - {data["roster"][x]["name"]}\n'
|
|
# errors.append(f'- This is the roster I have for {trade.teams[team]["team"]["abbrev"]}:\n'
|
|
# f'```\n{roster_string}```')
|
|
#
|
|
# if len(errors) > 0:
|
|
# error_message = '\n'.join(errors)
|
|
# await trade.send(f'Yikes. I\'m gonna put the kibosh on this trade. Below is why:\n\n{error_message}')
|
|
# await trade.timed_delete()
|
|
# return
|
|
#
|
|
# # Ask for each team's explict confirmation
|
|
# for team in trade.teams:
|
|
# this_q.prompt = f'{trade.teams[team]["role"].mention}\nDo you accept this trade?'
|
|
# this_q.qtype = 'yesno'
|
|
# resp = await this_q.ask(trade.get_gms(self.bot, team))
|
|
#
|
|
# if not resp:
|
|
# await trade.send('RIP this move. Maybe next time.')
|
|
# await trade.timed_delete()
|
|
# return
|
|
# else:
|
|
# await trade.show_moves()
|
|
#
|
|
# # Run moves
|
|
# trans_id = await trade.send_transaction()
|
|
#
|
|
# await send_to_channel(self.bot, 'sba-network-news', embed=await trade.show_moves(here=False))
|
|
# await self.send_move_to_sheets(trans_id)
|
|
#
|
|
# await trade.send(f'All done! Your transaction id is: {trans_id}')
|
|
# try:
|
|
# choas = get_role(ctx, 'CHOAS ALERT')
|
|
# await send_to_channel(self.bot, f'season-{current["season"]}-chat', f'{choas.mention}')
|
|
# except Exception as e:
|
|
# logging.error('I was not able to ping CHOAS ALERT')
|
|
# await trade.timed_delete()
|
|
|
|
@commands.command(name='dropadd', aliases=['drop', 'add', 'adddrop', 'longil'], help='FA/MiL moves')
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def drop_add_command(self, ctx):
|
|
current = await db_get('current')
|
|
team = await get_team_by_owner(current['season'], ctx.author.id)
|
|
# team_schedule = await get_schedule(
|
|
# current['season'],
|
|
# team_abbrev1=team["abbrev"],
|
|
# week_start=current['week'] + 1,
|
|
# week_end=current['week'] + 1,
|
|
# )
|
|
s_query = await db_get('games', params=[
|
|
('season', current['season']), ('team1_id', team['id']), ('week', current['week'] + 1)
|
|
])
|
|
team_role = get_team_role(ctx, team)
|
|
player_cog = self.bot.get_cog('Players')
|
|
poke_role = get_role(ctx, 'Pokétwo')
|
|
|
|
if s_query['count'] == 0 and not OFFSEASON_FLAG and current['week'] != 18:
|
|
await ctx.send('It looks like your season is over so transactions are locked.')
|
|
return
|
|
|
|
# Create transaction channel
|
|
overwrites = {ctx.guild.default_role: discord.PermissionOverwrite(read_messages=False),
|
|
team_role: discord.PermissionOverwrite(read_messages=True),
|
|
ctx.guild.me: discord.PermissionOverwrite(read_messages=True),
|
|
poke_role: discord.PermissionOverwrite(read_messages=True, send_messages=False)}
|
|
|
|
try:
|
|
t_channel = await ctx.guild.create_text_channel(
|
|
f'{team["abbrev"]}-transaction',
|
|
overwrites=overwrites,
|
|
category=discord.utils.get(ctx.guild.categories, name=f'Transactions')
|
|
)
|
|
except Exception as e:
|
|
await ctx.send(f'{e}\n\n'
|
|
f'Discord is having issues creating private channels right now. Please try again later.')
|
|
return
|
|
|
|
dropadd = SBaTransaction(t_channel, current, 'dropadd', first_team=team, team_role=team_role)
|
|
|
|
await dropadd.send(f'Let\'s start here, {team_role.mention}')
|
|
await ctx.send(f'Take my hand... {dropadd.channel.mention}')
|
|
await dropadd.send(f'This transaction is for __next week__. It will go into effect for '
|
|
f'week {current["week"] + 1}.')
|
|
|
|
# Get MiL moves
|
|
while True and not OFFSEASON_FLAG:
|
|
prompt = f'Are you adding someone to the Minor League roster?'
|
|
this_q = Question(self.bot, dropadd.channel, prompt, 'yesno', 300)
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
elif not resp:
|
|
break
|
|
else:
|
|
this_q.prompt = 'Who are you sending to the MiL?'
|
|
this_q.qtype = 'text'
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
else:
|
|
try:
|
|
player = await get_player_by_name(
|
|
current['season'],
|
|
await fuzzy_player_search(ctx, dropadd.channel, self.bot, resp,
|
|
player_cog.player_list.keys())
|
|
)
|
|
except ValueError:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try again.')
|
|
except requests.ReadTimeout:
|
|
await dropadd.send(
|
|
f'I\'m dumb and couldn\'t read from the database fast enough. '
|
|
f'{await get_emoji(ctx, "dead")} Let\'s try that again.'
|
|
)
|
|
else:
|
|
fa_team = await get_team_by_abbrev('FA', current['season'])
|
|
dest_team = await get_team_by_abbrev(f'{team["abbrev"]}MiL', current['season'])
|
|
if not dropadd.included_team(player['team']) and player['team'] != fa_team:
|
|
await t_channel.send(f'It looks like {player["name"]} is on {player["team"]["abbrev"]} '
|
|
f'so I can\'t let you do that.')
|
|
elif await dropadd.not_available(player):
|
|
await dropadd.send(f'Uh oh, looks like {player["name"]} is already on the move next week.')
|
|
elif player['demotion_week'] > current['week']:
|
|
await dropadd.send(f'Oof. {player["name"]} cannot be dropped until week '
|
|
f'{player["demotion_week"]}.')
|
|
else:
|
|
if player['team'] == fa_team:
|
|
dropadd.avoid_freeze = False
|
|
await dropadd.add_player(player, dest_team)
|
|
|
|
await dropadd.show_moves()
|
|
|
|
# Get Major League Adds
|
|
while True and not OFFSEASON_FLAG:
|
|
prompt = f'Are you adding any players to the Major League roster?'
|
|
this_q = Question(self.bot, dropadd.channel, prompt, 'yesno', 300)
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
elif not resp:
|
|
break
|
|
else:
|
|
this_q.prompt = 'Who are you adding?'
|
|
this_q.qtype = 'text'
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
else:
|
|
try:
|
|
player = await get_player_by_name(
|
|
current['season'],
|
|
await fuzzy_player_search(ctx, dropadd.channel, self.bot, resp,
|
|
player_cog.player_list.keys())
|
|
)
|
|
except ValueError:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try again.')
|
|
except requests.ReadTimeout:
|
|
await dropadd.send(
|
|
f'I\'m dumb and couldn\'t read from the database fast enough. '
|
|
f'{await get_emoji(ctx, "dead")} Let\'s try that again.'
|
|
)
|
|
else:
|
|
if OFFSEASON_FLAG:
|
|
if not self.on_team_il(team, player):
|
|
await t_channel.send(f'It looks like {player["name"]} is on {player["team"]["abbrev"]} '
|
|
f'so I can\'t let you do that.')
|
|
else:
|
|
await dropadd.add_player(player, team)
|
|
else:
|
|
fa_team = await get_team_by_abbrev('FA', current['season'])
|
|
if player['team'] != fa_team and not self.on_team_il(team, player):
|
|
await t_channel.send(f'It looks like {player["name"]} is on {player["team"]["abbrev"]} '
|
|
f'so I can\'t let you do that.')
|
|
elif await dropadd.not_available(player):
|
|
await dropadd.send(f'Uh oh, looks like {player["name"]} is already on the move '
|
|
f'next week.')
|
|
elif player['demotion_week'] > current['week']:
|
|
await dropadd.send(f'Oof. {player["name"]} cannot be dropped until week '
|
|
f'{player["demotion_week"]}.')
|
|
else:
|
|
if player['team'] == fa_team:
|
|
dropadd.avoid_freeze = False
|
|
await dropadd.add_player(player, team)
|
|
|
|
await dropadd.show_moves()
|
|
|
|
# Get FA Drops
|
|
while True:
|
|
prompt = f'Are you dropping anyone to FA?'
|
|
this_q = Question(self.bot, dropadd.channel, prompt, 'yesno', 300)
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
elif not resp:
|
|
break
|
|
else:
|
|
this_q.prompt = 'Who are you dropping to FA?'
|
|
this_q.qtype = 'text'
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
else:
|
|
try:
|
|
player = await get_player_by_name(
|
|
current['season'],
|
|
await fuzzy_player_search(ctx, dropadd.channel, self.bot, resp,
|
|
player_cog.player_list.keys())
|
|
)
|
|
except ValueError:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try again.')
|
|
except requests.ReadTimeout:
|
|
await dropadd.send(
|
|
f'I\'m dumb and couldn\'t read from the database fast enough. '
|
|
f'{await get_emoji(ctx, "dead")} Let\'s try that again.'
|
|
)
|
|
else:
|
|
if not dropadd.included_team(player['team']):
|
|
await t_channel.send(f'It looks like {player["name"]} is on {player["team"]["abbrev"]} '
|
|
f'so I can\'t let you do that.')
|
|
elif await dropadd.not_available(player):
|
|
await dropadd.send(f'Uh oh, looks like {player["name"]} is already on the move next week.')
|
|
elif player['demotion_week'] > current['week']:
|
|
await dropadd.send(f'Oof. {player["name"]} cannot be dropped until week '
|
|
f'{player["demotion_week"]}.')
|
|
else:
|
|
dest_team = await get_team_by_abbrev('FA', current['season'])
|
|
await dropadd.add_player(player, dest_team)
|
|
|
|
await dropadd.show_moves()
|
|
|
|
# Check for empty move
|
|
if len(dropadd.players) == 0:
|
|
await dropadd.send(f'This has been fun. Come again and maybe do something next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
|
|
# Check legality
|
|
errors = []
|
|
roster_errors = []
|
|
for team in dropadd.teams:
|
|
data = await dropadd.check_major_league_errors(team)
|
|
logging.warning(f'Done checking data - checking WARa now ({data["wara"]})')
|
|
|
|
if data['wara'] > 32.001 and not OFFSEASON_FLAG:
|
|
errors.append(f'- {dropadd.teams[team]["team"]["abbrev"]} would have {data["wara"]:.2f} sWAR')
|
|
|
|
logging.warning(f'Now checking roster {len(data["roster"])}')
|
|
if len(data['roster']) > 26 and not OFFSEASON_FLAG:
|
|
errors.append(f'- {dropadd.teams[team]["team"]["abbrev"]} would have {len(data["roster"])} players')
|
|
|
|
logging.warning(f'Any errors? {errors}')
|
|
if (data['wara'] > 32.001 or len(data['roster']) > 26) and not OFFSEASON_FLAG:
|
|
roster_string = ''
|
|
for x in data['roster']:
|
|
roster_string += f'{x["wara"]: >5} - {x["name"]}\n'
|
|
errors.append(f'- This is the roster I have for {dropadd.teams[team]["team"]["abbrev"]}:\n'
|
|
f'```\n{roster_string}```')
|
|
|
|
if len(data['mil_roster']) > 9:
|
|
errors.append(
|
|
f'- {dropadd.teams[team]["team"]["abbrev"]}MiL would have {len(data["mil_roster"])} players'
|
|
)
|
|
|
|
if len(errors) + len(roster_errors) > 0:
|
|
error_message = '\n'.join(errors)
|
|
await dropadd.send(f'Yikes. I\'m gonna put the kibosh on this move. Below is why:\n\n{error_message}')
|
|
if len(roster_errors) > 0:
|
|
for x in roster_errors:
|
|
await dropadd.send(x)
|
|
await dropadd.timed_delete()
|
|
return
|
|
|
|
# Ask for confirmation
|
|
for team in dropadd.teams:
|
|
this_q.prompt = f'{dropadd.teams[team]["role"].mention}\nWould you like me to run this move?'
|
|
this_q.qtype = 'yesno'
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot, team))
|
|
|
|
if not resp:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
else:
|
|
await dropadd.show_moves()
|
|
|
|
# Run moves
|
|
trans_id = await dropadd.send_transaction()
|
|
|
|
if not current['freeze'] or dropadd.avoid_freeze:
|
|
await send_to_channel(self.bot, 'transaction-log', embed=await dropadd.show_moves(here=False))
|
|
|
|
await dropadd.send(f'All done! Your transaction id is: {trans_id}')
|
|
await dropadd.timed_delete()
|
|
|
|
@commands.command(name='ilmove', help='IL move')
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def il_move_command(self, ctx):
|
|
current = await db_get('current')
|
|
|
|
if OFFSEASON_FLAG:
|
|
await ctx.send(await get_emoji(ctx, 'oof', False))
|
|
await ctx.send(f'I\'m not supposed to let anybody make IL moves during the offseason. You can still '
|
|
f'trade and drop players to FA, though!')
|
|
return
|
|
|
|
team = await get_team_by_owner(current['season'], ctx.author.id)
|
|
# team = await get_team_by_abbrev('VA', current['season'])
|
|
s_query = await db_get('games', params=[
|
|
('season', current['season']), ('team1_id', team['id']), ('week', current['week'])
|
|
])
|
|
if s_query['count'] == 0 and current['week'] != 18:
|
|
await ctx.send('It looks like your season is over so transactions are locked.')
|
|
return
|
|
|
|
team_role = get_team_role(ctx, team)
|
|
player_cog = self.bot.get_cog('Players')
|
|
poke_role = get_role(ctx, 'Pokétwo')
|
|
|
|
overwrites = {ctx.guild.default_role: discord.PermissionOverwrite(read_messages=False),
|
|
team_role: discord.PermissionOverwrite(read_messages=True),
|
|
ctx.guild.me: discord.PermissionOverwrite(read_messages=True),
|
|
poke_role: discord.PermissionOverwrite(read_messages=True, send_messages=False)}
|
|
|
|
try:
|
|
t_channel = await ctx.guild.create_text_channel(
|
|
f'{team["abbrev"]}-transaction',
|
|
overwrites=overwrites,
|
|
category=discord.utils.get(ctx.guild.categories, name=f'Transactions')
|
|
)
|
|
except Exception as e:
|
|
await ctx.send(f'{e}\n\n'
|
|
f'Discord is having issues creating private channels right now. Please try again later.')
|
|
return
|
|
|
|
dropadd = SBaTransaction(t_channel, current, 'dropadd', this_week=True, first_team=team, team_role=team_role)
|
|
|
|
await dropadd.send(f'Let\'s start here, {team_role.mention}')
|
|
await ctx.send(f'Take my hand... {dropadd.channel.mention}')
|
|
await dropadd.send(f'This transaction is for __this week__. It will go into effect for week {current["week"]}.')
|
|
|
|
# Get IL moves
|
|
while True:
|
|
prompt = f'Are you sending someone to the IL?'
|
|
this_q = Question(self.bot, dropadd.channel, prompt, 'yesno', 300)
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
elif not resp:
|
|
break
|
|
else:
|
|
this_q.prompt = 'Who are you sending to the IL?'
|
|
this_q.qtype = 'text'
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
else:
|
|
try:
|
|
player = await get_player_by_name(
|
|
current['season'],
|
|
await fuzzy_player_search(ctx, dropadd.channel, self.bot, resp,
|
|
player_cog.player_list.keys())
|
|
)
|
|
except ValueError:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try again.')
|
|
except requests.ReadTimeout:
|
|
await dropadd.send(
|
|
f'I\'m dumb and couldn\'t read from the database fast enough. '
|
|
f'{await get_emoji(ctx, "dead")} Let\'s try that again.'
|
|
)
|
|
else:
|
|
if not dropadd.included_team(player['team']):
|
|
await t_channel.send(f'It looks like {player["name"]} is on {player["team"]["abbrev"]} '
|
|
f'so I can\'t let you do that.')
|
|
else:
|
|
dest_team = await get_team_by_abbrev(f'{team["abbrev"]}IL', current['season'])
|
|
await dropadd.add_player(player, dest_team)
|
|
|
|
await dropadd.show_moves()
|
|
|
|
# Get Major League Adds
|
|
while True and not OFFSEASON_FLAG:
|
|
prompt = f'Are you adding someone to the Major League team?'
|
|
this_q = Question(self.bot, dropadd.channel, prompt, 'yesno', 300)
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
elif not resp:
|
|
break
|
|
else:
|
|
this_q.prompt = 'Who are you adding?'
|
|
this_q.qtype = 'text'
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
else:
|
|
try:
|
|
player = await get_player_by_name(
|
|
current['season'],
|
|
await fuzzy_player_search(ctx, dropadd.channel, self.bot, resp,
|
|
player_cog.player_list.keys())
|
|
)
|
|
except ValueError:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try again.')
|
|
except requests.ReadTimeout:
|
|
await dropadd.send(
|
|
f'I\'m dumb and couldn\'t read from the database fast enough. '
|
|
f'{await get_emoji(ctx, "dead")} Let\'s try that again.'
|
|
)
|
|
else:
|
|
if not self.on_team_il(team, player):
|
|
await t_channel.send(f'It looks like {player["name"]} is on {player["team"]["abbrev"]} '
|
|
f'- you can only call up your MiL players mid-week.')
|
|
else:
|
|
await dropadd.add_player(player, team)
|
|
|
|
await dropadd.show_moves()
|
|
|
|
# Get MiL moves
|
|
while True and not OFFSEASON_FLAG:
|
|
prompt = f'Are you adding someone to the Minor League team?'
|
|
this_q = Question(self.bot, dropadd.channel, prompt, 'yesno', 300)
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
elif not resp:
|
|
break
|
|
else:
|
|
this_q.prompt = 'Who are you sending to the MiL?'
|
|
this_q.qtype = 'text'
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
else:
|
|
try:
|
|
player = await get_player_by_name(
|
|
current['season'],
|
|
await fuzzy_player_search(ctx, dropadd.channel, self.bot, resp,
|
|
player_cog.player_list.keys())
|
|
)
|
|
except ValueError:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try again.')
|
|
except requests.ReadTimeout:
|
|
await dropadd.send(
|
|
f'I\'m dumb and couldn\'t read from the database fast enough. '
|
|
f'{await get_emoji(ctx, "dead")} Let\'s try that again.'
|
|
)
|
|
else:
|
|
if not dropadd.included_team(player['team']):
|
|
await t_channel.send(f'It looks like {player["name"]} is on {player["team"]["abbrev"]} '
|
|
f'so I can\'t let you do that.')
|
|
# elif player['demotion_week'] > current['week']:
|
|
# await dropadd.send(f'Oof. {player["name"]} cannot be dropped until week '
|
|
# f'{player["demotion_week"]}.')
|
|
else:
|
|
dest_team = await get_team_by_abbrev(f'{team["abbrev"]}MiL', current['season'])
|
|
await dropadd.add_player(player, dest_team)
|
|
|
|
await dropadd.show_moves()
|
|
|
|
# Get FA Drops
|
|
while True:
|
|
prompt = f'Are you dropping anyone to FA?'
|
|
this_q = Question(self.bot, dropadd.channel, prompt, 'yesno', 300)
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
elif not resp:
|
|
break
|
|
else:
|
|
this_q.prompt = 'Who are you dropping to FA?'
|
|
this_q.qtype = 'text'
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot))
|
|
|
|
if resp is None:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
else:
|
|
try:
|
|
player = await get_player_by_name(
|
|
current['season'],
|
|
await fuzzy_player_search(ctx, dropadd.channel, self.bot, resp,
|
|
player_cog.player_list.keys())
|
|
)
|
|
except ValueError:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try again.')
|
|
except requests.ReadTimeout:
|
|
await dropadd.send(
|
|
f'I\'m dumb and couldn\'t read from the database fast enough. '
|
|
f'{await get_emoji(ctx, "dead")} Let\'s try that again.'
|
|
)
|
|
else:
|
|
if not dropadd.included_team(player['team']):
|
|
await t_channel.send(f'It looks like {player["name"]} is on {player["team"]["abbrev"]} '
|
|
f'so I can\'t let you do that.')
|
|
# elif player['demotion_week'] > current['week']:
|
|
# await dropadd.send(f'Oof. {player["name"]} cannot be dropped until week '
|
|
# f'{player["demotion_week"]}.')
|
|
else:
|
|
dest_team = await get_team_by_abbrev('FA', current['season'])
|
|
await dropadd.add_player(player, dest_team)
|
|
|
|
await dropadd.show_moves()
|
|
|
|
# Check for empty move
|
|
if len(dropadd.players) == 0:
|
|
await dropadd.send(f'This has been fun. Come again and maybe do something next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
|
|
# Check legality
|
|
errors = []
|
|
roster_errors = []
|
|
for team in dropadd.teams:
|
|
data = await dropadd.check_major_league_errors(team)
|
|
|
|
if data['wara'] > 32.001 and not OFFSEASON_FLAG:
|
|
errors.append(f'- {dropadd.teams[team]["team"]["abbrev"]} would have {data["wara"]:.2f} WARa')
|
|
|
|
if len(data['roster']) > 26 and not OFFSEASON_FLAG:
|
|
errors.append(f'- {dropadd.teams[team]["team"]["abbrev"]} would have {len(data["roster"])} players')
|
|
|
|
if (data['wara'] > 32.001 or len(data['roster']) > 26) and not OFFSEASON_FLAG:
|
|
roster_string = ''
|
|
for x in data['roster']:
|
|
roster_string += f'{x["wara"]: >5} - {x["name"]}\n'
|
|
errors.append(f'- This is the roster I have for {dropadd.teams[team]["team"]["abbrev"]}:\n'
|
|
f'```\n{roster_string}```')
|
|
|
|
if len(errors) + len(roster_errors) > 0:
|
|
error_message = '\n'.join(errors)
|
|
await dropadd.send(f'Yikes. I\'m gonna put the kibosh on this move. Below is why:\n\n{error_message}')
|
|
if len(roster_errors) > 0:
|
|
for x in roster_errors:
|
|
await dropadd.send(x)
|
|
await dropadd.timed_delete()
|
|
return
|
|
|
|
# Ask for confirmation
|
|
for team in dropadd.teams:
|
|
this_q.prompt = f'{dropadd.teams[team]["role"].mention}\nWould you like me to run this move?'
|
|
this_q.qtype = 'yesno'
|
|
resp = await this_q.ask(dropadd.get_gms(self.bot, team))
|
|
|
|
if not resp:
|
|
await dropadd.send('RIP this move. Maybe next time.')
|
|
await dropadd.timed_delete()
|
|
return
|
|
else:
|
|
await dropadd.show_moves()
|
|
|
|
# Post moves
|
|
trans_id = await dropadd.send_transaction()
|
|
|
|
if dropadd.avoid_freeze:
|
|
# Run moves
|
|
for player_move in [*dropadd.players.values()]:
|
|
this_guy = copy.deepcopy(player_move['player'])
|
|
this_guy['team'] = player_move['to']
|
|
this_guy['demotion_week'] = current['week']
|
|
await patch_player(this_guy)
|
|
|
|
await send_to_channel(self.bot, 'transaction-log', embed=await dropadd.show_moves(here=False))
|
|
|
|
await dropadd.send(f'All done! Your transaction id is: {trans_id}')
|
|
await dropadd.timed_delete()
|
|
|
|
@commands.command(name='mymoves', help='Show upcoming moves')
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def my_moves_command(self, ctx):
|
|
current = await db_get('current')
|
|
team = await get_team_by_owner(current['season'], ctx.author.id)
|
|
# set_moves = await get_transactions(
|
|
# current['season'],
|
|
# team_abbrev=team['abbrev'],
|
|
# week_start=current['week']+1,
|
|
# week_end=current['week']+1
|
|
# )
|
|
t_query = await db_get('transactions', params=[
|
|
('season', current['season']), ('week_start', current['week']),
|
|
('week_end', current['season']), ('team_abbrev', team['abbrev'])
|
|
])
|
|
set_moves = t_query['transactions']
|
|
# frozen_moves = await get_transactions(
|
|
# current['season'],
|
|
# team_abbrev=team['abbrev'],
|
|
# week_start=current['week']+1,
|
|
# week_end=current['week']+1,
|
|
# frozen=True
|
|
# )
|
|
t_query = await db_get('transactions', params=[
|
|
('season', current['season']), ('week_start', current['week']),
|
|
('week_end', current['season']), ('team_abbrev', team['abbrev']), ('frozen', True)
|
|
])
|
|
frozen_moves = t_query['transactions']
|
|
logging.info(f'Num Moves: {len(set_moves)}')
|
|
|
|
embed = get_team_embed(f'{team["lname"]} Guaranteed Transactions', team=team)
|
|
embed.description = f'Week {current["week"] + 1} Moves'
|
|
guaranteed = {}
|
|
frozen = {}
|
|
|
|
for x in set_moves:
|
|
if x["moveid"] not in guaranteed.keys():
|
|
guaranteed[x["moveid"]] = []
|
|
|
|
guaranteed[x["moveid"]].append(
|
|
f'**{x["player"]["name"]}** ({x["player"]["wara"]}) from '
|
|
f'{x["oldteam"]["abbrev"]} to {x["newteam"]["abbrev"]}\n'
|
|
)
|
|
|
|
for x in frozen_moves:
|
|
if x["moveid"] not in frozen.keys():
|
|
frozen[x["moveid"]] = []
|
|
|
|
frozen[x["moveid"]].append(
|
|
f'**{x["player"]["name"]}** ({x["player"]["wara"]}) from '
|
|
f'{x["oldteam"]["abbrev"]} to {x["newteam"]["abbrev"]}\n'
|
|
)
|
|
|
|
if len(guaranteed) > 0:
|
|
for move_id in guaranteed:
|
|
move_string = ''.join(guaranteed[move_id])
|
|
embed.add_field(name=f'Trans ID: {move_id}', value=move_string)
|
|
|
|
if len(frozen) > 0:
|
|
for move_id in frozen:
|
|
move_string = ''.join(frozen[move_id])
|
|
embed.add_field(name=f'Trans ID: {move_id}', value=move_string)
|
|
|
|
await ctx.author.send(content='Hey, boo. Here are your upcoming transactions:', embed=embed)
|
|
|
|
@commands.command(name='legal', help='Check roster legality')
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def legal_command(self, ctx, team_abbrev: str):
|
|
current = await db_get('current')
|
|
if team_abbrev:
|
|
this_team = await get_team_by_abbrev(team_abbrev, current['season'])
|
|
else:
|
|
this_team = await get_team_by_owner(current['season'], ctx.author.id)
|
|
|
|
# this_week_team = await get_team_roster(this_team, 'current')
|
|
# next_week_team = await get_team_roster(this_team, 'next')
|
|
this_week_team = await db_get(f'teams/{this_team["id"]}/roster/current')
|
|
next_week_team = await db_get(f'teams/{this_team["id"]}/roster/next')
|
|
|
|
count = 0
|
|
all_players = []
|
|
|
|
for roster in [this_week_team, next_week_team]:
|
|
embed = get_team_embed(f'{this_team["lname"]} Roster Check', team=this_team)
|
|
if count == 0:
|
|
embed.description = f'Week {current["week"]}'
|
|
else:
|
|
embed.description = f'Week {current["week"] + 1}'
|
|
|
|
errors = []
|
|
|
|
sil_wara = roster['shortil']['WARa']
|
|
total_wara = roster['active']['WARa']
|
|
wara_string = f'{total_wara:.2f}'
|
|
if sil_wara > 0:
|
|
wara_string += f' ({sil_wara:.2f} IL)'
|
|
|
|
embed.add_field(name='sWAR', value=wara_string)
|
|
if total_wara > 32.001:
|
|
errors.append(f'- sWAR currently {total_wara:.2f} (cap 32.0)')
|
|
|
|
player_count = len(roster["active"]["players"])
|
|
embed.add_field(name='Player Count', value=f'{player_count}')
|
|
if player_count != 26:
|
|
errors.append(f'- Currently have {player_count} players (need 26)')
|
|
|
|
pos_string = f'```\nC 1B 2B 3B SS\n' \
|
|
f'{roster["active"]["C"]} {roster["active"]["1B"]} {roster["active"]["2B"]} ' \
|
|
f'{roster["active"]["3B"]} {roster["active"]["SS"]}\n\n' \
|
|
f'LF CF RF SP RP\n' \
|
|
f'{roster["active"]["LF"]} {roster["active"]["CF"]} {roster["active"]["RF"]} ' \
|
|
f'{roster["active"]["SP"]} {roster["active"]["RP"]}\n```'
|
|
embed.add_field(name='Position Checks', value=pos_string, inline=False)
|
|
for pos in roster['active']:
|
|
if pos in ['C', '1B', '2B', '3B', 'SS', 'LF', 'CF', 'RF']:
|
|
logging.info(f'Pos: {pos} / {roster["active"][pos]}')
|
|
if roster["active"][pos] < 2:
|
|
errors.append(f'- Only have {roster["active"][pos]} {pos} (need 2)')
|
|
# elif pos in ['SP', 'RP']:
|
|
# logging.info(f'Pos: {pos} / {roster["active"][pos]}')
|
|
# if roster["active"][pos] < 5:
|
|
# errors.append(f'- Only have {roster["active"][pos]} {pos} (need 5)')
|
|
|
|
if len(errors) > 0:
|
|
embed.add_field(name='Legality: ILLEGAL ❌', value="\n".join(errors), inline=False)
|
|
else:
|
|
embed.add_field(name='Legality: LEGAL 👍️', value='All good!', inline=False)
|
|
|
|
await ctx.send(content=None, embed=embed)
|
|
count += 1
|
|
|
|
@commands.command(name='tomil', help='Post-draft demotions')
|
|
@commands.has_any_role(SBA_PLAYERS_ROLE_NAME)
|
|
async def to_mil_command(self, ctx, *player_list):
|
|
current = await db_get('current')
|
|
team = await get_team_by_owner(current['season'], owner_id=ctx.author.id)
|
|
il_team = await get_team_by_abbrev(f'{team["abbrev"]}MiL', current['season'])
|
|
|
|
if current['week'] != 0:
|
|
logging.info('entering the thot check')
|
|
await react_and_reply(ctx, '👀', 'https://c.tenor.com/FCAj8xDvEHwAAAAC/be-gone-thot.gif')
|
|
player_role = get_role(ctx, SBA_PLAYERS_ROLE_NAME)
|
|
bonked_role = get_role(ctx, 'BAINSHED')
|
|
logging.info('beginning sleep')
|
|
await asyncio.sleep(3)
|
|
|
|
# try:
|
|
# await ctx.author.add_roles(bonked_role)
|
|
# except Exception as e:
|
|
# logging.error(f'unable to add {bonked_role} role to {ctx.author}: {e}')
|
|
try:
|
|
await ctx.author.remove_roles(player_role)
|
|
except Exception as e:
|
|
logging.error(f'unable to remove {player_role} role from {ctx.author}: {e}')
|
|
|
|
return
|
|
|
|
player_list = ' '.join(player_list)
|
|
player_names = re.split(',', player_list)
|
|
output_string = ''
|
|
errors = []
|
|
moves = []
|
|
|
|
for x in player_names:
|
|
player_cog = self.bot.get_cog('Players')
|
|
|
|
try:
|
|
player_name = await fuzzy_player_search(ctx, ctx.channel, self.bot, x, player_cog.player_list.keys())
|
|
player = await get_player_by_name(current['season'], player_name)
|
|
except Exception as e:
|
|
logging.error(f'Could not demote {x} for {team["abbrev"]}: {e}')
|
|
errors.append(x)
|
|
else:
|
|
if player['team']['id'] != team['id']:
|
|
await ctx.send(f'Omg stop trying to make {player["name"]} happen. It\'s not going to happen.')
|
|
else:
|
|
output_string += f'**{player["name"]}** ({player["wara"]}) to MiL\n'
|
|
if player['team']['id'] == team['id']:
|
|
moves.append({
|
|
'week': 1,
|
|
'player_id': player['id'],
|
|
'oldteam_id': team['id'],
|
|
'newteam_id': il_team['id'],
|
|
'season': current['season'],
|
|
'moveid': f'draft-tomil-{team["abbrev"]}'
|
|
})
|
|
|
|
if len(moves) == 0:
|
|
await react_and_reply(ctx, '🖕', 'Thanks for that. So much fun.')
|
|
return
|
|
|
|
await db_post('transactions', payload={'count': len(moves), 'moves': moves})
|
|
embed = get_team_embed(f'Pre-Season Demotions', team)
|
|
embed.add_field(name='Demotions', value=output_string, inline=False)
|
|
await send_to_channel(self.bot, 'transaction-log', content=None, embed=embed)
|
|
|
|
if len(moves) > 0:
|
|
await react_and_reply(ctx, '✅', random_conf_gif())
|
|
if len(errors) > 0:
|
|
await react_and_reply(ctx, '❌', f'I wasn\'t able to find {", ".join(errors)}')
|
|
|
|
@commands.command(name='calisamazing', help='Make up for your idiocy')
|
|
async def cal_is_amazing_command(self, ctx):
|
|
current = await db_get('current')
|
|
team = await get_team_by_owner(current['season'], owner_id=ctx.author.id)
|
|
|
|
if not team:
|
|
await ctx.send(random_conf_gif())
|
|
|
|
player_role = get_role(ctx, SBA_PLAYERS_ROLE_NAME)
|
|
try:
|
|
await ctx.author.add_roles(player_role)
|
|
except Exception as e:
|
|
logging.error(f'unable to add {player_role} role to {ctx.author}: {e}')
|
|
await react_and_reply(
|
|
ctx, '😩',
|
|
f'{e}\n\nLooks like you didn\'t apologize hard enough. I can\'t role you back up.')
|
|
await react_and_reply(ctx, '💖', 'You are too kind.')
|
|
|
|
|
|
async def setup(bot):
|
|
await bot.add_cog(Transactions(bot))
|