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

2078 lines
98 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 = True
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')
m_query = await db_get('players', params=[
('season', self.current['season']), ('team_id', f'{this_team["abbrev"]}MiL')
])
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:
# 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:
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':
mil_roster.remove(self.players[x]['player'])
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):
try:
guild = self.bot.get_guild(int(os.environ.get('GUILD_ID')))
if not guild:
logging.error(f'Could not pull guild; exiting loop')
return
except Exception as e:
logging.error(f'Could not run weekly_loop: {e}')
return
current = await db_get('current')
now = datetime.datetime.now()
logging.info(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 == 6 and not current['freeze']: # Fall/Winter
current['week'] += 1
if OFFSEASON_FLAG:
pass
# if not self.trade_season:
# await db_patch('current', object_id=current['id'], params=[('week', current['week'])])
# await self.run_transactions(current)
# stars = f'{"":*<26}'
# freeze_message = f'```\n' \
# f'{stars}\n' \
# f' IT\'S TRADE SZN BITCHES\n' \
# f'{stars}\n```'
# logging.info(f'Freeze string:\n\n{freeze_message}')
# await send_to_channel(self.bot, 'sba-network-news', freeze_message)
# self.trade_season = True
else:
await db_patch('current', object_id=current['id'], params=[('week', current['week']), ('freeze', True)])
await self.run_transactions(current)
logging.info(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.info(f'Freeze string:\n\n{freeze_message}')
await send_to_channel(self.bot, 'transaction-log', freeze_message)
# End Freeze
# elif now.weekday() == 5 and now.hour == 5 and current['freeze']: # Spring/Summer
elif now.weekday() == 5 and now.hour == 6 and current['freeze']: # Fall/Winter
if not OFFSEASON_FLAG:
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
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"])
r_query = await db_get('standings', params=[
('season', current['season']), ('team_abbrev', new_team['abbrev'])
])
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 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='trade', 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 WARa now ({data["wara"]}')
if data['wara'] > 38.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'] > 38.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'] > 38.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'] > 38.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('schedules', params=[
('season', current['season']), ('team_abbrev', team['abbrev']), ('week_start', current['week'] + 1),
('week_end', 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'] != 22:
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'] > 38.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'] > 38.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)
s_query = await db_get('schedules', params=[
('season', current['season']), ('team_abbrev', team['abbrev']), ('week_start', current['week'] + 1),
('week_end', current['week'] + 1)
])
if s_query['count'] == 0 and current['week'] != 22:
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'] > 38.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'] > 38.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[frozen_moves[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)
await ctx.author.send('See everything you expected?')
@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='WARa', value=wara_string)
if total_wara > 38.001:
errors.append(f'- WARa currently {total_wara:.2f} (cap 38.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))