Added random_gif() Moved back from exception-handler cog to local error handling Updated !keepers to be season agnostic Added new !sync param to update and clear local guild Added error checking to !player command
1975 lines
92 KiB
Python
1975 lines
92 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, put_player, db_post
|
|
from discord.ext import commands, tasks
|
|
OFFSEASON_FLAG = True
|
|
logger = logging.getLogger('discord_app')
|
|
|
|
|
|
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):
|
|
logger.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)
|
|
logger.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']
|
|
|
|
logger.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']
|
|
|
|
logger.info(f'updating rosters')
|
|
for x in self.players:
|
|
logger.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:
|
|
logger.info(f'major league player')
|
|
# logger.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':
|
|
logger.info(f'minor league player')
|
|
mil_roster.remove(self.players[x]['player'])
|
|
# logger.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'Season-{self.current["season"]:03d}-Week-{self.effective_week:0>2}-{datetime.datetime.now().strftime("%d-%H:%M:%S")}'
|
|
moves = []
|
|
|
|
logger.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()
|
|
|
|
async def cog_command_error(self, ctx, error):
|
|
logger.error(msg=error, stack_info=True, exc_info=True)
|
|
await ctx.send(f'{error}\n\nRun !help <command_name> to see the command requirements')
|
|
|
|
async def slash_error(self, ctx, error):
|
|
logger.error(msg=error, stack_info=True, exc_info=True)
|
|
await ctx.send(f'{error[:1600]}')
|
|
|
|
@tasks.loop(minutes=1)
|
|
async def weekly_loop(self):
|
|
if OFFSEASON_FLAG:
|
|
return
|
|
|
|
current = await db_get('current')
|
|
now = datetime.datetime.now()
|
|
logger.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)
|
|
|
|
logger.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```'
|
|
logger.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 put_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:
|
|
logger.warning(f'No transactions to process for the freeze in week {current["week"]}')
|
|
return
|
|
|
|
moves = m_query['transactions']
|
|
logger.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"]]
|
|
)
|
|
logger.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]
|
|
logger.info(f'freeze / contested_players: {contested_players.keys()}')
|
|
|
|
# Determine winner for contested players, mark moveid cancelled for loser
|
|
def tiebreaker(val):
|
|
logger.info(f'tiebreaker: {val}')
|
|
return val[2]
|
|
|
|
for guy in contested_players:
|
|
contested_players[guy].sort(key=tiebreaker)
|
|
first = True
|
|
logger.info(f'Contested Player: {contested_players[guy]}\n\n')
|
|
for x in contested_players[guy]:
|
|
logger.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 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)
|
|
|
|
@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)
|
|
if team is None:
|
|
await ctx.send(f'Who are you? Why are you talking to me, you don\'t have a team.')
|
|
return
|
|
|
|
team_role = get_team_role(ctx, team)
|
|
if team_role is None:
|
|
await ctx.send(f'I could not find a team role for the {team["lname"]}')
|
|
return
|
|
|
|
poke_role = get_role(ctx, 'Pokétwo')
|
|
if poke_role is None:
|
|
await ctx.send(f'I could not find the poke role. This is an emergency.')
|
|
return
|
|
|
|
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),
|
|
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:
|
|
next_team = await get_team_by_abbrev(resp, current['season'])
|
|
if next_team is None:
|
|
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 as e:
|
|
logger.error(f'Could not find player *{resp}*')
|
|
else:
|
|
if player is None:
|
|
await trade.send(f'{await get_emoji(ctx, "squint")}')
|
|
await trade.send('Who even is that? Try 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:
|
|
dest_team = await get_team_by_abbrev(resp, current['season'])
|
|
if dest_team is None:
|
|
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 as e:
|
|
logger.error(f'Could not find player *{resp}*')
|
|
else:
|
|
if player is None:
|
|
await trade.send(f'{await get_emoji(ctx, "squint")}')
|
|
await trade.send('Who even is that? Try 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)
|
|
logger.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')
|
|
|
|
logger.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')
|
|
|
|
logger.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:
|
|
logger.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)
|
|
# logger.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')
|
|
#
|
|
# logger.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')
|
|
#
|
|
# logger.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:
|
|
# logger.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 as e:
|
|
logger.error(f'Could not find player *{resp}*')
|
|
else:
|
|
if player is None:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try 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 as e:
|
|
logger.error(f'Could not find player *{resp}*')
|
|
else:
|
|
if player is None:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try 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 as e:
|
|
logger.error(f'Could not find player *{resp}*')
|
|
else:
|
|
if player is None:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try 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)
|
|
logger.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')
|
|
|
|
logger.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')
|
|
|
|
logger.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 as e:
|
|
logger.error(f'Could not find player *{resp}*')
|
|
else:
|
|
if player is None:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try 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 as e:
|
|
logger.error(f'Could not find player *{resp}*')
|
|
else:
|
|
if player is None:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try 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 as e:
|
|
logger.error(f'Could not find player *{resp}*')
|
|
else:
|
|
if player is None:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try 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 as e:
|
|
logger.error(f'Could not find player *{resp}*')
|
|
else:
|
|
if player is None:
|
|
await dropadd.send(f'{await get_emoji(ctx, "squint")}')
|
|
await dropadd.send('Who even is that? Try 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 put_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']
|
|
logger.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']:
|
|
logger.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']:
|
|
# logger.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:
|
|
logger.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')
|
|
logger.info('beginning sleep')
|
|
await asyncio.sleep(3)
|
|
|
|
# try:
|
|
# await ctx.author.add_roles(bonked_role)
|
|
# except Exception as e:
|
|
# logger.error(f'unable to add {bonked_role} role to {ctx.author}: {e}')
|
|
try:
|
|
await ctx.author.remove_roles(player_role)
|
|
except Exception as e:
|
|
logger.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:
|
|
logger.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:
|
|
logger.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))
|