paper-dynasty-discord/helpers.py
Cal Corum 3debfd6e82 Catchup commit
Includes discord_ui refactor, testing overhaul, addition of
2025-07-22 09:22:19 -05:00

1698 lines
62 KiB
Python

import asyncio
import datetime
import logging
import math
import os
import random
import traceback
import discord
import pygsheets
import requests
from discord.ext import commands
from api_calls import *
from bs4 import BeautifulSoup
from difflib import get_close_matches
from dataclasses import dataclass
from typing import Optional, Literal
from exceptions import log_exception
from in_game.gameplay_models import Team
from constants import *
from discord_ui import *
from random_content import *
from utils import *
from search_utils import *
from discord_utils import *
async def get_player_photo(player):
search_term = player['bbref_id'] if player['bbref_id'] else player['p_name']
req_url = f'https://www.thesportsdb.com/api/v1/json/1/searchplayers.php?p={search_term}'
try:
resp = requests.get(req_url, timeout=.5)
except Exception as e:
return None
if resp.status_code == 200 and resp.json()['player']:
if resp.json()['player'][0]['strSport'] == 'Baseball':
await db_patch('players', object_id=player['player_id'],
params=[('headshot', resp.json()['player'][0]['strThumb'])])
return resp.json()['player'][0]['strThumb']
return None
async def get_player_headshot(player):
search_term = player['bbref_id'] if player['bbref_id'] else player['p_name']
req_url = f'https://www.baseball-reference.com/search/search.fcgi?search={search_term}'
try:
resp = requests.get(req_url, timeout=2).text
soup = BeautifulSoup(resp, 'html.parser')
for item in soup.find_all('img'):
if 'headshot' in item['src']:
await db_patch('players', object_id=player['player_id'], params=[('headshot', item['src'])])
return item['src']
except:
pass
return await get_player_photo(player)
"""
NEW FOR SEASON 4
"""
async def get_team_by_owner(owner_id: int):
team = await db_get('teams', params=[('gm_id', owner_id)])
if not team['count']:
return None
return team['teams'][0]
async def team_role(ctx, team: Team):
return await get_or_create_role(ctx, f'{team.abbrev} - {team.lname}')
def get_all_pos(player):
all_pos = []
for x in range(1, 8):
if player[f'pos_{x}']:
all_pos.append(player[f'pos_{x}'])
return all_pos
async def share_channel(channel, user, read_only=False):
await channel.set_permissions(user, read_messages=True, send_messages=not read_only)
async def get_card_embeds(card, include_stats=False) -> list:
embed = discord.Embed(
title=f'{card["player"]["p_name"]}',
color=int(card['player']['rarity']['color'], 16)
)
# embed.description = card['team']['lname']
embed.description = f'{card["player"]["cardset"]["name"]} / {card["player"]["mlbclub"]}'
embed.set_author(name=card['team']['lname'], url=IMAGES['logo'], icon_url=card['team']['logo'])
embed.set_footer(text=f'Paper Dynasty Season {card["team"]["season"]}', icon_url=IMAGES['logo'])
if include_stats:
b_query = await db_get(
'plays/batting', params=[('player_id', card['player']['player_id']), ('season', PD_SEASON)])
p_query = await db_get(
'plays/pitching', params=[('player_id', card['player']['player_id']), ('season', PD_SEASON)])
embed.add_field(name='Player ID', value=f'{card["player"]["player_id"]}')
embed.add_field(name='Rarity', value=f'{card["player"]["rarity"]["name"]}')
embed.add_field(name='Cost', value=f'{card["player"]["cost"]}')
pos_string = ", ".join(get_all_pos(card['player']))
embed.add_field(name='Positions', value=pos_string)
# all_dex = card['player']['paperdex']
all_dex = await db_get('paperdex', params=[("player_id", card["player"]["player_id"]), ('flat', True)])
count = all_dex['count']
if card['team']['lname'] != 'Paper Dynasty':
bool_list = [True for elem in all_dex['paperdex'] if elem['team'] == card['team'].get('id', None)]
if any(bool_list):
if count == 1:
coll_string = f'Only you'
else:
coll_string = f'You and {count - 1} other{"s" if count - 1 != 1 else ""}'
elif count:
coll_string = f'{count} other team{"s" if count != 1 else ""}'
else:
coll_string = f'0 teams'
embed.add_field(name='Collected By', value=coll_string)
else:
embed.add_field(name='Collected By', value=f'{count} team{"s" if count != 1 else ""}')
# TODO: check for dupes with the included paperdex data
# if card['team']['lname'] != 'Paper Dynasty':
# team_dex = await db_get('cards', params=[("player_id", card["player"]["player_id"]), ('team_id', card['team']['id'])])
# count = 1 if not team_dex['count'] else team_dex['count']
# embed.add_field(name='# Dupes', value=f'{count - 1} dupe{"s" if count - 1 != 1 else ""}')
# embed.add_field(name='Team', value=f'{card["player"]["mlbclub"]}')
if card['player']['franchise'] != 'Pokemon':
player_pages = f'[BBRef](https://www.baseball-reference.com/players/{card["player"]["bbref_id"][0]}/{card["player"]["bbref_id"]}.shtml)'
else:
player_pages = f'[Pkmn]({PKMN_REF_URL}{card["player"]["bbref_id"]})'
embed.add_field(name='Player Page', value=f'{player_pages}')
embed.set_image(url=card["player"]["image"])
headshot = card['player']['headshot'] if card['player']['headshot'] else await get_player_headshot(card['player'])
if headshot:
embed.set_thumbnail(url=headshot)
else:
embed.set_thumbnail(url=IMAGES['logo'])
if card['player']['franchise'] == 'Pokemon':
if card['player']['fangr_id'] is not None:
try:
evo_mon = await db_get('players', object_id=card['player']['fangr_id'], none_okay=True)
if evo_mon is not None:
embed.add_field(
name='Evolves Into',
value=f'{evo_mon["p_name"]}'
)
except Exception as e:
logging.error('could not pull evolution: {e}', exc_info=True, stack_info=True)
if '420420' not in card['player']['strat_code']:
try:
evo_mon = await db_get('players', object_id=card['player']['strat_code'], none_okay=True)
if evo_mon is not None:
embed.add_field(
name='Evolves From',
value=f'{evo_mon["p_name"]}'
)
except Exception as e:
logging.error('could not pull evolution: {e}', exc_info=True, stack_info=True)
if include_stats:
if b_query['count'] > 0:
b = b_query['stats'][0]
re24 = f'{b["re24"]:.2f}'
batting_string = f'```\n' \
f' AVG OBP SLG\n' \
f' {b["avg"]:.3f} {b["obp"]:.3f} {b["slg"]:.3f}\n``````\n' \
f' OPS wOBA RE24\n' \
f' {b["ops"]:.3f} {b["woba"]:.3f} {re24: ^5}\n``````\n' \
f' PA H RBI 2B 3B HR SB\n' \
f'{b["pa"]: >3} {b["hit"]: ^3} {b["rbi"]: ^3} {b["double"]: >2} {b["triple"]: >2} ' \
f'{b["hr"]: >2} {b["sb"]: >2}```\n'
embed.add_field(name='Batting Stats', value=batting_string, inline=False)
if p_query['count'] > 0:
p = p_query['stats'][0]
ip_whole = math.floor(p['outs'] / 3)
ip_denom = p['outs'] % 3
ips = ip_whole + (ip_denom * 0.1)
kpbb = f'{p["k/bb"]:.1f}'
era = f'{p["era"]:.2f}'
whip = f'{p["whip"]:.2f}'
re24 = f'{p["re24"]:.2f}'
pitching_string = f'```\n' \
f' W-L SV ERA WHIP\n' \
f'{p["win"]: >2}-{p["loss"]: <2} {p["save"]: >2} {era: >5} {whip: >4}\n``````\n' \
f' IP SO K/BB RE24\n' \
f'{ips: >5} {p["so"]: ^3} {kpbb: ^4} {re24: ^5}\n```'
embed.add_field(name='Pitching Stats', value=pitching_string, inline=False)
if not card['player']['image2']:
return [embed]
card_two = discord.Embed(color=int(card['player']['rarity']['color'], 16))
card_two.set_footer(text=f'Paper Dynasty Season {card["team"]["season"]}', icon_url=IMAGES['logo'])
card_two.set_image(url=card['player']['image2'])
return [embed, card_two]
def image_embed(image_url: str, title: str = None, color: str = None, desc: str = None, author_name: str = None,
author_icon: str = None):
embed_color = int(SBA_COLOR, 16)
if color is not None:
embed_color = int(color, 16)
embed = discord.Embed(color=embed_color)
if title is not None:
embed.title = title
if desc is not None:
embed.description = desc
if author_name is not None:
icon = author_icon if author_icon is not None else IMAGES['logo']
embed.set_author(name=author_name, icon_url=icon)
embed.set_footer(text=f'Paper Dynasty Season {PD_SEASON}', icon_url=IMAGES['logo'])
embed.set_image(url=image_url)
return embed
def is_shiny(card):
if card['player']['rarity']['value'] >= 5:
return True
return False
async def display_cards(
cards: list, team: dict, channel, user, bot=None, pack_cover: str = None, cust_message: str = None,
add_roster: bool = True, pack_name: str = None) -> bool:
cards.sort(key=lambda x: x['player']['rarity']['value'])
card_embeds = [await get_card_embeds(x) for x in cards]
page_num = 0 if pack_cover is None else -1
seen_shiny = False
view = Pagination([user], timeout=10)
l_emoji = await get_emoji(channel.guild, 'arrow_left')
r_emoji = await get_emoji(channel.guild, 'arrow_right')
view.left_button.disabled = True
view.left_button.label = f'{l_emoji}Prev: -/{len(card_embeds)}'
view.cancel_button.label = f'Close Pack'
view.right_button.label = f'Next: {page_num + 2}/{len(card_embeds)}{r_emoji}'
if len(cards) == 1:
view.right_button.disabled = True
if pack_cover:
msg = await channel.send(
content=None,
embed=image_embed(pack_cover, title=f'{team["lname"]}', desc=pack_name),
view=view
)
else:
msg = await channel.send(content=None, embeds=card_embeds[page_num], view=view)
if cust_message:
follow_up = await channel.send(cust_message)
else:
follow_up = await channel.send(f'{user.mention} you\'ve got {len(cards)} cards here')
while True:
await view.wait()
if view.value:
if view.value == 'cancel':
await msg.edit(view=None)
if add_roster:
await follow_up.edit(content=f'Refresh your cards here: {get_roster_sheet(team)}')
return True
if view.value == 'left':
page_num -= 1 if page_num > 0 else 0
if view.value == 'right':
page_num += 1 if page_num <= len(card_embeds) else len(card_embeds)
else:
if page_num == len(card_embeds) - 1:
await msg.edit(view=None)
if add_roster:
await follow_up.edit(content=f'Refresh your cards here: {get_roster_sheet(team)}')
return True
else:
page_num += 1
view.value = None
if is_shiny(cards[page_num]) and not seen_shiny:
seen_shiny = True
view = Pagination([user], timeout=300)
view.cancel_button.style = discord.ButtonStyle.success
view.cancel_button.label = 'Flip!'
view.left_button.label = '-'
view.right_button.label = '-'
view.left_button.disabled = True
view.right_button.disabled = True
await msg.edit(
embed=image_embed(
IMAGES['mvp'][cards[page_num]["player"]["franchise"]],
color='56f1fa',
author_name=team['lname'],
author_icon=team['logo']
),
view=view)
tmp_msg = await channel.send(content=f'<@&1163537676885033010> we\'ve got an MVP!')
await follow_up.edit(content=f'<@&1163537676885033010> we\'ve got an MVP!')
await tmp_msg.delete()
await view.wait()
view = Pagination([user], timeout=10)
view.right_button.label = f'Next: {page_num + 2}/{len(card_embeds)}{r_emoji}'
view.cancel_button.label = f'Close Pack'
view.left_button.label = f'{l_emoji}Prev: {page_num}/{len(card_embeds)}'
if page_num == 0:
view.left_button.label = f'{l_emoji}Prev: -/{len(card_embeds)}'
view.left_button.disabled = True
elif page_num == len(card_embeds) - 1:
view.timeout = 600.0
view.right_button.label = f'Next: -/{len(card_embeds)}{r_emoji}'
view.right_button.disabled = True
await msg.edit(content=None, embeds=card_embeds[page_num], view=view)
async def embed_pagination(
all_embeds: list, channel, user: discord.Member, custom_message: str = None,
timeout: int = 10, start_page: int = 0):
if start_page > len(all_embeds) - 1 or start_page < 0:
page_num = 0
else:
page_num = start_page
view = Pagination([user], timeout=timeout)
l_emoji = ''
r_emoji = ''
view.right_button.label = f'Next: {page_num + 2}/{len(all_embeds)}{r_emoji}'
view.cancel_button.label = f'Cancel'
view.left_button.label = f'{l_emoji}Prev: {page_num}/{len(all_embeds)}'
if page_num == 0:
view.left_button.label = f'{l_emoji}Prev: -/{len(all_embeds)}'
view.left_button.disabled = True
elif page_num == len(all_embeds) - 1:
view.right_button.label = f'Next: -/{len(all_embeds)}{r_emoji}'
view.right_button.disabled = True
msg = await channel.send(content=custom_message, embed=all_embeds[page_num], view=view)
while True:
await view.wait()
if view.value:
if view.value == 'cancel':
await msg.edit(view=None)
return True
if view.value == 'left':
page_num -= 1 if page_num > 0 else 0
if view.value == 'right':
page_num += 1 if page_num <= len(all_embeds) else len(all_embeds)
else:
if page_num == len(all_embeds) - 1:
await msg.edit(view=None)
return True
else:
page_num += 1
view.value = None
view = Pagination([user], timeout=timeout)
view.right_button.label = f'Next: {page_num + 2}/{len(all_embeds)}{r_emoji}'
view.cancel_button.label = f'Cancel'
view.left_button.label = f'{l_emoji}Prev: {page_num}/{len(all_embeds)}'
if page_num == 0:
view.left_button.label = f'{l_emoji}Prev: -/{len(all_embeds)}'
view.left_button.disabled = True
elif page_num == len(all_embeds) - 1:
view.timeout = 600.0
view.right_button.label = f'Next: -/{len(all_embeds)}{r_emoji}'
view.right_button.disabled = True
await msg.edit(content=None, embed=all_embeds[page_num], view=view)
async def get_test_pack(ctx, team):
pull_notifs = []
this_pack = await db_post('packs/one', payload={
'team_id': team['id'], 'pack_type_id': 1,
'open_time': int(datetime.datetime.timestamp(datetime.datetime.now())*1000)
})
ft_query = await db_get('players/random', params=[('max_rarity', 1), ('limit', 3)])
four_query = await db_get('players/random', params=[('min_rarity', 1), ('max_rarity', 3), ('limit', 1)])
five_query = await db_get('players/random', params=[('min_rarity', 5), ('max_rarity', 5), ('limit', 1)])
first_three = ft_query['players']
fourth = four_query['players']
fifth = five_query['players']
all_cards = [*first_three, *fourth, *fifth]
success = await db_post('cards', timeout=10, payload={'cards': [{
'player_id': x['player_id'], 'team_id': team['id'], 'pack_id': this_pack['id']} for x in all_cards]
})
if not success:
await ctx.send(f'I was not able to create these cards {get_emoji(ctx, "slight_frown")}')
return
for x in all_cards:
if x['rarity']['value'] >= 3:
pull_notifs.append(x)
for pull in pull_notifs:
await db_post('notifs', payload={
'created': int(datetime.datetime.timestamp(datetime.datetime.now())*1000),
'title': 'Rare Pull',
'field_name': f'{player_desc(pull)} ({pull["rarity"]["name"]})',
'message': f'Pulled by {team["abbrev"]}',
'about': f'Player-{pull["player_id"]}'
})
return [{'player': x, 'team': team} for x in all_cards]
async def roll_for_cards(all_packs: list, extra_val=None) -> list:
"""
Pack odds are calculated based on the pack type
Parameters
----------
extra_val
all_packs
Returns
-------
"""
all_players = []
team = all_packs[0]['team']
pack_ids = []
for pack in all_packs:
counts = {
'Rep': {
'count': 0,
'rarity': 0
},
'Res': {
'count': 0,
'rarity': 1
},
'Sta': {
'count': 0,
'rarity': 2
},
'All': {
'count': 0,
'rarity': 3
},
'MVP': {
'count': 0,
'rarity': 5
},
'HoF': {
'count': 0,
'rarity': 8
},
}
this_pack_players = []
if pack['pack_type']['name'] == 'Standard':
# Cards 1 - 2
for x in range(2):
d_1000 = random.randint(1, 1000)
if d_1000 <= 450:
counts['Rep']['count'] += 1
elif d_1000 <= 900:
counts['Res']['count'] += 1
else:
counts['Sta']['count'] += 1
# Card 3
d_1000 = random.randint(1, 1000)
if d_1000 <= 350:
counts['Rep']['count'] += 1
elif d_1000 <= 700:
counts['Res']['count'] += 1
elif d_1000 <= 950:
counts['Sta']['count'] += 1
else:
counts['All']['count'] += 1
# Card 4
d_1000 = random.randint(1, 1000)
if d_1000 <= 310:
counts['Rep']['count'] += 1
elif d_1000 <= 620:
counts['Res']['count'] += 1
elif d_1000 <= 940:
counts['Sta']['count'] += 1
elif d_1000 <= 990:
counts['All']['count'] += 1
else:
counts['MVP']['count'] += 1
# Card 5
d_1000 = random.randint(1, 1000)
if d_1000 <= 215:
counts['Rep']['count'] += 1
elif d_1000 <= 430:
counts['Res']['count'] += 1
elif d_1000 <= 930:
counts['Sta']['count'] += 1
elif d_1000 <= 980:
counts['All']['count'] += 1
elif d_1000 <= 990:
counts['MVP']['count'] += 1
else:
counts['HoF']['count'] += 1
elif pack['pack_type']['name'] == 'Premium':
# Card 1
d_1000 = random.randint(1, 1000)
if d_1000 <= 400:
counts['Rep']['count'] += 1
elif d_1000 <= 870:
counts['Res']['count'] += 1
elif d_1000 <= 970:
counts['Sta']['count'] += 1
elif d_1000 <= 990:
counts['All']['count'] += 1
else:
counts['MVP']['count'] += 1
# Card 2
d_1000 = random.randint(1, 1000)
if d_1000 <= 300:
counts['Rep']['count'] += 1
elif d_1000 <= 770:
counts['Res']['count'] += 1
elif d_1000 <= 970:
counts['Sta']['count'] += 1
elif d_1000 <= 990:
counts['All']['count'] += 1
else:
counts['MVP']['count'] += 1
# Card 3
d_1000 = random.randint(1, 1000)
if d_1000 <= 200:
counts['Rep']['count'] += 1
elif d_1000 <= 640:
counts['Res']['count'] += 1
elif d_1000 <= 940:
counts['Sta']['count'] += 1
elif d_1000 <= 990:
counts['All']['count'] += 1
else:
counts['MVP']['count'] += 1
# Card 4
d_1000 = random.randint(1, 1000)
if d_1000 <= 100:
counts['Rep']['count'] += 1
if d_1000 <= 530:
counts['Res']['count'] += 1
elif d_1000 <= 930:
counts['Sta']['count'] += 1
elif d_1000 <= 980:
counts['All']['count'] += 1
elif d_1000 <= 990:
counts['MVP']['count'] += 1
else:
counts['HoF']['count'] += 1
# Card 5
d_1000 = random.randint(1, 1000)
if d_1000 <= 380:
counts['Res']['count'] += 1
elif d_1000 <= 880:
counts['Sta']['count'] += 1
elif d_1000 <= 980:
counts['All']['count'] += 1
elif d_1000 <= 990:
counts['MVP']['count'] += 1
else:
counts['HoF']['count'] += 1
elif pack['pack_type']['name'] == 'Check-In Player':
logger.info(f'Building Check-In Pack // extra_val (type): {extra_val} {type(extra_val)}')
# Single Card
mod = 0
if isinstance(extra_val, int):
mod = extra_val
d_1000 = random.randint(1, 1000 + mod)
if d_1000 >= 1100:
counts['All']['count'] += 1
elif d_1000 >= 1000:
counts['Sta']['count'] += 1
elif d_1000 >= 500:
counts['Res']['count'] += 1
else:
counts['Rep']['count'] += 1
else:
raise TypeError(f'Pack type not recognized: {pack["pack_type"]["name"]}')
pull_notifs = []
for key in counts:
mvp_flag = None
if counts[key]['count'] > 0:
params = [
('min_rarity', counts[key]['rarity']), ('max_rarity', counts[key]['rarity']),
('limit', counts[key]['count'])
]
if all_packs[0]['pack_team'] is not None:
params.extend([('franchise', all_packs[0]['pack_team']['lname']), ('in_packs', True)])
elif all_packs[0]['pack_cardset'] is not None:
params.append(('cardset_id', all_packs[0]['pack_cardset']['id']))
else:
params.append(('in_packs', True))
pl = await db_get('players/random', params=params)
if pl['count'] != counts[key]['count']:
mvp_flag = counts[key]['count'] - pl['count']
logging.info(f'Set mvp flag to {mvp_flag} / cardset_id: {all_packs[0]["pack_cardset"]["id"]}')
for x in pl['players']:
this_pack_players.append(x)
all_players.append(x)
if x['rarity']['value'] >= 3:
pull_notifs.append(x)
if mvp_flag and all_packs[0]['pack_cardset']['id'] not in [23]:
logging.info(f'Adding {mvp_flag} MVPs for missing cards')
pl = await db_get('players/random', params=[('min_rarity', 5), ('limit', mvp_flag)])
for x in pl['players']:
this_pack_players.append(x)
all_players.append(x)
# Add dupes of Replacement/Reserve cards
elif mvp_flag:
logging.info(f'Adding {mvp_flag} duplicate pokemon cards')
for count in range(mvp_flag):
logging.info(f'Adding {pl["players"][0]["p_name"]} to the pack')
this_pack_players.append(x)
all_players.append(pl['players'][0])
success = await db_post(
'cards',
payload={'cards': [{
'player_id': x['player_id'], 'team_id': pack['team']['id'], 'pack_id': pack['id']} for x in this_pack_players]
},
timeout=10
)
if not success:
raise ConnectionError(f'Failed to create this pack of cards.')
await db_patch('packs', object_id=pack['id'], params=[
('open_time', int(datetime.datetime.timestamp(datetime.datetime.now())*1000))
])
pack_ids.append(pack['id'])
for pull in pull_notifs:
logger.info(f'good pull: {pull}')
await db_post('notifs', payload={
'created': int(datetime.datetime.timestamp(datetime.datetime.now())*1000),
'title': 'Rare Pull',
'field_name': f'{player_desc(pull)} ({pull["rarity"]["name"]})',
'message': f'Pulled by {team["abbrev"]}',
'about': f'Player-{pull["player_id"]}'
})
return pack_ids
async def give_packs(team: dict, num_packs: int, pack_type: dict = None) -> dict:
"""
Parameters
----------
pack_type
team
num_packs
Returns
-------
{ 'count': int, 'packs': [ all team packs ] }
"""
pt_id = pack_type['id'] if pack_type is not None else 1
await db_post(
'packs',
payload={'packs': [{'team_id': team['id'], 'pack_type_id': pt_id} for x in range(num_packs)]}
)
total_packs = await db_get('packs', params=[
('team_id', team['id']), ('opened', False)
])
return total_packs
def get_sheets(bot):
try:
return bot.get_cog('Gameplay').sheets
except Exception as e:
logger.error(f'Could not grab sheets auth: {e}')
raise ConnectionError(f'Bot has not authenticated with discord; please try again in 1 minute.')
def create_team_sheet(team, email: str, current, bot):
sheets = get_sheets(bot)
new_sheet = sheets.drive.copy_file(
f'{current["gsheet_template"]}',
f'{team["lname"]} Roster Sheet v{current["gsheet_version"]}',
'1539D0imTMjlUx2VF3NPMt7Sv85sb2XAJ'
)
logger.info(f'new_sheet: {new_sheet}')
this_sheet = sheets.open_by_key(new_sheet['id'])
this_sheet.share(email, role='writer')
team_data = this_sheet.worksheet_by_title('Team Data')
team_data.update_values(
crange='B1:B2',
values=[[f'{team["id"]}'], [f'\'{team_hash(team)}']]
)
logger.debug(f'this_sheet: {this_sheet}')
return this_sheet
async def refresh_sheet(team, bot, sheets=None) -> None:
return
if not sheets:
sheets = get_sheets(bot)
this_sheet = sheets.open_by_key(team['gsheet'])
my_cards = this_sheet.worksheet_by_title('My Cards')
all_cards = this_sheet.worksheet_by_title('All Cards')
my_cards.update_value('A2', 'FALSE')
all_cards.update_value('A2', 'FALSE')
await asyncio.sleep(1)
my_cards.update_value('A2', 'TRUE')
await asyncio.sleep(0.5)
all_cards.update_value('A2', 'TRUE')
def delete_sheet(team, bot):
sheets = get_sheets(bot)
this_sheet = sheets.open_by_key(team['gsheet'])
this_sheet.delete()
def share_sheet(team, email, bot) -> None:
sheets = get_sheets(bot)
this_sheet = sheets.open_by_key(team['gsheet'])
this_sheet.share(email, role='writer')
def int_timestamp(datetime_obj: datetime.datetime) -> int:
return int(datetime.datetime.timestamp(datetime_obj) * 1000)
def get_pos_abbrev(pos_name):
if pos_name == 'Catcher':
return 'C'
elif pos_name == 'First Base':
return '1B'
elif pos_name == 'Second Base':
return '2B'
elif pos_name == 'Third Base':
return '3B'
elif pos_name == 'Shortstop':
return 'SS'
elif pos_name == 'Left Field':
return 'LF'
elif pos_name == 'Center Field':
return 'CF'
elif pos_name == 'Right Field':
return 'RF'
elif pos_name == 'Pitcher':
return 'P'
elif pos_name == 'Designated Hitter':
return 'DH'
elif pos_name == 'Pinch Hitter':
return 'PH'
else:
raise KeyError(f'{pos_name} is not a recognized position name')
async def cardset_search(cardset: str, cardset_list: list) -> Optional[dict]:
cardset_name = fuzzy_search(cardset, cardset_list)
if not cardset_name:
return None
c_query = await db_get('cardsets', params=[('name', cardset_name)])
if c_query['count'] == 0:
return None
return c_query['cardsets'][0]
def get_blank_team_card(player):
return {'player': player, 'team': {'lname': 'Paper Dynasty', 'logo': IMAGES['logo'], 'season': PD_SEASON, 'id': None}}
def get_rosters(team, bot, roster_num: Optional[int] = None) -> list:
sheets = get_sheets(bot)
this_sheet = sheets.open_by_key(team['gsheet'])
r_sheet = this_sheet.worksheet_by_title(f'My Rosters')
logger.debug(f'this_sheet: {this_sheet} / r_sheet = {r_sheet}')
all_rosters = [None, None, None]
# Pull roster 1
if not roster_num or roster_num == 1:
roster_1 = r_sheet.range('B3:B28')
roster_name = r_sheet.cell('F30').value
logger.info(f'roster_1: {roster_1}')
if not roster_1[0][0].value == '':
all_rosters[0] = {'name': roster_name, 'roster_num': 1, 'team_id': team['id'], 'cards': None}
all_rosters[0]['cards'] = [int(x[0].value) for x in roster_1]
# Pull roster 2
if not roster_num or roster_num == 2:
roster_2 = r_sheet.range('B29:B54')
roster_name = r_sheet.cell('F31').value
logger.info(f'roster_2: {roster_2}')
if not roster_2[0][0].value == '':
all_rosters[1] = {'name': roster_name, 'roster_num': 2, 'team_id': team['id'], 'cards': None}
all_rosters[1]['cards'] = [int(x[0].value) for x in roster_2]
# Pull roster 3
if not roster_num or roster_num == 3:
roster_3 = r_sheet.range('B55:B80')
roster_name = r_sheet.cell('F32').value
logger.info(f'roster_3: {roster_3}')
if not roster_3[0][0].value == '':
all_rosters[2] = {'name': roster_name, 'roster_num': 3, 'team_id': team['id'], 'cards': None}
all_rosters[2]['cards'] = [int(x[0].value) for x in roster_3]
return all_rosters
def get_roster_lineups(team, bot, roster_num, lineup_num) -> list:
sheets = get_sheets(bot)
logger.debug(f'sheets: {sheets}')
this_sheet = sheets.open_by_key(team['gsheet'])
logger.debug(f'this_sheet: {this_sheet}')
r_sheet = this_sheet.worksheet_by_title('My Rosters')
logger.debug(f'r_sheet: {r_sheet}')
if lineup_num == 1:
row_start = 9
row_end = 17
else:
row_start = 18
row_end = 26
if roster_num == 1:
l_range = f'H{row_start}:I{row_end}'
elif roster_num == 2:
l_range = f'J{row_start}:K{row_end}'
else:
l_range = f'L{row_start}:M{row_end}'
logger.debug(f'l_range: {l_range}')
raw_cells = r_sheet.range(l_range)
logger.debug(f'raw_cells: {raw_cells}')
try:
lineup_cells = [(row[0].value, int(row[1].value)) for row in raw_cells]
except ValueError as e:
logger.error(f'Could not pull roster for {team["abbrev"]} due to a ValueError')
raise ValueError(f'Uh oh. Looks like your roster might not be saved. I am reading blanks when I try to '
f'get the card IDs')
logger.debug(f'lineup_cells: {lineup_cells}')
return lineup_cells
def post_ratings_guide(team, bot, this_sheet=None):
if not this_sheet:
sheets = get_sheets(bot)
this_sheet = sheets.open_by_key(team['gsheet'])
p_guide = this_sheet.worksheet_by_title('Full Guide - Pitchers')
b_guide = this_sheet.worksheet_by_title('Full Guide - Batters')
p_guide.update_value('A1', RATINGS_PITCHER_FORMULA)
b_guide.update_value('A1', RATINGS_BATTER_FORMULA)
async def legal_channel(ctx):
bad_channels = ['paper-dynasty-chat', 'pd-news-ticker', 'pd-network-news']
if isinstance(ctx, commands.Context):
if ctx.channel.name in bad_channels:
raise commands.CheckFailure(f'Slide on down to the {get_channel(ctx, "pd-bot-hole").mention} ;)')
else:
return True
elif ctx.channel.name in bad_channels:
# await ctx.message.add_reaction('❌')
# await ctx.send(f'Slide on down to the {get_channel(ctx, "pd-bot-hole").mention} ;)')
# logger.warning(f'{ctx.author.name} posted in illegal channel.')
# return False
raise discord.app_commands.AppCommandError(f'Slide on down to the {get_channel(ctx, "pd-bot-hole").mention} ;)')
else:
return True
def get_role(ctx, role_name):
return discord.utils.get(ctx.guild.roles, name=role_name)
async def team_summary_embed(team, ctx, include_roster: bool = True):
embed = get_team_embed(f'{team["lname"]} Overview', team)
embed.add_field(name='General Manager', value=team['gmname'], inline=False)
embed.add_field(name='Wallet', value=f'{team["wallet"]}')
# embed.add_field(name='Collection Value', value=team['collection_value'])
p_query = await db_get('packs', params=[('team_id', team['id']), ('opened', False)])
if p_query['count'] > 0:
all_packs = {}
for x in p_query['packs']:
if x['pack_type']['name'] not in all_packs:
all_packs[x['pack_type']['name']] = 1
else:
all_packs[x['pack_type']['name']] += 1
pack_string = ''
for pack_type in all_packs:
pack_string += f'{pack_type.title()}: {all_packs[pack_type]}\n'
else:
pack_string = 'None'
embed.add_field(name='Unopened Packs', value=pack_string)
embed.add_field(name='Team Rating', value=f'{team["ranking"]}')
r_query = await db_get(f'results/team/{team["id"]}?season={PD_SEASON}')
if r_query:
embed.add_field(
name='Record',
value=f'Ranked: {r_query["ranked_wins"]}-{r_query["ranked_losses"]}\n'
f'Unlimited: {r_query["casual_wins"]}-{r_query["casual_losses"]}'
)
# try:
# r_query = await db_get('rosters', params=[('team_id', team['id'])])
# if r_query['count']:
# embed.add_field(name=f'Rosters', value=f'** **', inline=False)
# for roster in r_query['rosters']:
# roster_string = ''
# for i in range(1, 27):
# card = roster[f'card_{i}']
# roster_string += f'{card["player"]["description"]} ({card["player"]["pos_1"]})\n'
# embed.add_field(
# name=f'{roster["name"]} Roster',
# value=roster_string if len(roster_string) else "Unknown"
# )
# else:
# embed.add_field(
# name='Rosters',
# value='You can set up to three rosters for quick switching from your team sheet.',
# inline=False
# )
# except Exception as e:
# logger.error(f'Could not pull rosters for {team["abbrev"]}')
# embed.add_field(
# name='Rosters',
# value='Unable to pull current rosters. `/pullroster` to sync.',
# inline=False
# )
if include_roster:
embed.add_field(name='Team Sheet', value=get_roster_sheet(team, allow_embed=True), inline=False)
embed.add_field(
name='For Help',
value=f'`/help-pd` has FAQs; feel free to post questions in '
f'{get_channel(ctx, "paper-dynasty-chat").mention}.',
inline=False
)
return embed
async def give_cards_to_team(team, players: list = None, player_ids: list = None, pack_id=None):
if not pack_id:
p_query = await db_post(
'packs/one',
payload={
'team_id': team['id'],
'pack_type_id': 4,
'open_time': datetime.datetime.timestamp(datetime.datetime.now()) * 1000}
)
pack_id = p_query['id']
if not players and not player_ids:
raise ValueError('One of players or player_ids must be provided to distribute cards')
if players:
await db_post('cards', payload={'cards': [
{'player_id': x['player_id'], 'team_id': team['id'], 'pack_id': pack_id} for x in players
]}, timeout=10)
elif player_ids:
await db_post('cards', payload={'cards': [
{'player_id': x, 'team_id': team['id'], 'pack_id': pack_id} for x in player_ids
]}, timeout=10)
def get_ratings_guide(sheets):
this_sheet = sheets.open_by_key(RATINGS_SHEET_KEY)
b_sheet = this_sheet.worksheet_by_title('ratings_Batters')
p_sheet = this_sheet.worksheet_by_title('ratings_Pitchers')
b_data = b_sheet.range('A2:N')
p_data = p_sheet.range('A2:N')
try:
batters = [
{
'player_id': int(x[0].value),
'p_name': x[1].value,
'rating': int(x[2].value),
'contact-r': int(x[3].value),
'contact-l': int(x[4].value),
'power-r': int(x[5].value),
'power-l': int(x[6].value),
'vision': int(x[7].value),
'speed': int(x[8].value),
'stealing': int(x[9].value),
'reaction': int(x[10].value),
'arm': int(x[11].value),
'fielding': int(x[12].value),
'hand': int(x[13].value),
} for x in b_data
]
pitchers = [
{
'player_id': int(x[0].value),
'p_name': x[1].value,
'rating': int(x[2].value),
'control-r': int(x[3].value),
'control-l': int(x[4].value),
'stuff-r': int(x[5].value),
'stuff-l': int(x[6].value),
'stamina': int(x[7].value),
'fielding': int(x[8].value),
'hit-9': int(x[9].value),
'k-9': int(x[10].value),
'bb-9': int(x[11].value),
'hr-9': int(x[12].value),
'hand': int(x[13].value),
} for x in p_data
]
except Exception as e:
return {'valid': False}
return {
'valid': True,
'batter_ratings': batters,
'pitcher_ratings': pitchers
}
async def paperdex_cardset_embed(team: dict, this_cardset: dict) -> list[discord.Embed]:
all_dex = await db_get(
'paperdex',
params=[('team_id', team['id']), ('cardset_id', this_cardset['id']), ('flat', True)]
)
dex_player_list = [x['player'] for x in all_dex['paperdex']]
hof_embed = get_team_embed(f'{team["lname"]} Collection', team=team)
mvp_embed = get_team_embed(f'{team["lname"]} Collection', team=team)
as_embed = get_team_embed(f'{team["lname"]} Collection', team=team)
sta_embed = get_team_embed(f'{team["lname"]} Collection', team=team)
res_embed = get_team_embed(f'{team["lname"]} Collection', team=team)
rep_embed = get_team_embed(f'{team["lname"]} Collection', team=team)
coll_data = {
99: {
'name': 'Hall of Fame',
'owned': 0,
'players': [],
'embeds': [hof_embed]
},
1: {
'name': 'MVP',
'owned': 0,
'players': [],
'embeds': [mvp_embed]
},
2: {
'name': 'All-Star',
'owned': 0,
'players': [],
'embeds': [as_embed]
},
3: {
'name': 'Starter',
'owned': 0,
'players': [],
'embeds': [sta_embed]
},
4: {
'name': 'Reserve',
'owned': 0,
'players': [],
'embeds': [res_embed]
},
5: {
'name': 'Replacement',
'owned': 0,
'players': [],
'embeds': [rep_embed]
},
'total_owned': 0
}
set_players = await db_get(
'players',
params=[('cardset_id', this_cardset['id']), ('flat', True), ('inc_dex', False)],
timeout=5
)
for player in set_players['players']:
if player['player_id'] in dex_player_list:
coll_data[player['rarity']]['owned'] += 1
coll_data['total_owned'] += 1
player['owned'] = True
else:
player['owned'] = False
logger.debug(f'player: {player} / type: {type(player)}')
coll_data[player['rarity']]['players'].append(player)
cover_embed = get_team_embed(f'{team["lname"]} Collection', team=team)
cover_embed.description = this_cardset['name']
cover_embed.add_field(name='# Total Cards', value=f'{set_players["count"]}')
cover_embed.add_field(name='# Collected', value=f'{coll_data["total_owned"]}')
display_embeds = [cover_embed]
for rarity_id in coll_data:
if rarity_id != 'total_owned':
if coll_data[rarity_id]['players']:
coll_data[rarity_id]['embeds'][0].description = f'Rarity: {coll_data[rarity_id]["name"]}'
coll_data[rarity_id]['embeds'][0].add_field(
name='# Collected / # Total Cards',
value=f'{coll_data[rarity_id]["owned"]} / {len(coll_data[rarity_id]["players"])}',
inline=False
)
chunk_string = ''
for index, this_player in enumerate(coll_data[rarity_id]['players']):
logger.debug(f'this_player: {this_player}')
chunk_string += '' if this_player['owned'] else ''
chunk_string += f'{this_player["p_name"]}\n'
if (index + 1) == len(coll_data[rarity_id]["players"]):
coll_data[rarity_id]['embeds'][0].add_field(
name=f'Group {math.ceil((index + 1) / 20)} / '
f'{math.ceil(len(coll_data[rarity_id]["players"]) / 20)}',
value=chunk_string
)
elif (index + 1) % 20 == 0:
coll_data[rarity_id]['embeds'][0].add_field(
name=f'Group {math.floor((index + 1) / 20)} / '
f'{math.ceil(len(coll_data[rarity_id]["players"]) / 20)}',
value=chunk_string
)
chunk_string = ''
display_embeds.append(coll_data[rarity_id]['embeds'][0])
return display_embeds
async def paperdex_team_embed(team: dict, mlb_team: dict) -> list[discord.Embed]:
all_dex = await db_get(
'paperdex',
params=[('team_id', team['id']), ('franchise', mlb_team['lname']), ('flat', True)]
)
dex_player_list = [x['player'] for x in all_dex['paperdex']]
c_query = await db_get('cardsets')
coll_data = {'total_owned': 0}
total_players = 0
for x in c_query['cardsets']:
set_players = await db_get(
'players',
params=[('cardset_id', x['id']), ('franchise', mlb_team['lname']), ('flat', True), ('inc_dex', False)]
)
if set_players is not None:
coll_data[x['id']] = {
'name': x['name'],
'owned': 0,
'players': [],
'embeds': [get_team_embed(f'{team["lname"]} Collection', team=team)]
}
total_players += set_players['count']
for player in set_players['players']:
if player['player_id'] in dex_player_list:
coll_data[x['id']]['owned'] += 1
coll_data['total_owned'] += 1
player['owned'] = True
else:
player['owned'] = False
logger.debug(f'player: {player} / type: {type(player)}')
coll_data[x['id']]['players'].append(player)
cover_embed = get_team_embed(f'{team["lname"]} Collection', team=team)
cover_embed.description = mlb_team['lname']
cover_embed.add_field(name='# Total Cards', value=f'{total_players}')
cover_embed.add_field(name='# Collected', value=f'{coll_data["total_owned"]}')
display_embeds = [cover_embed]
for cardset_id in coll_data:
if cardset_id != 'total_owned':
if coll_data[cardset_id]['players']:
coll_data[cardset_id]['embeds'][0].description = f'{mlb_team["lname"]} / ' \
f'{coll_data[cardset_id]["name"]}'
coll_data[cardset_id]['embeds'][0].add_field(
name='# Collected / # Total Cards',
value=f'{coll_data[cardset_id]["owned"]} / {len(coll_data[cardset_id]["players"])}',
inline=False
)
chunk_string = ''
for index, this_player in enumerate(coll_data[cardset_id]['players']):
logger.debug(f'this_player: {this_player}')
chunk_string += '' if this_player['owned'] else ''
chunk_string += f'{this_player["p_name"]}\n'
if (index + 1) == len(coll_data[cardset_id]["players"]):
coll_data[cardset_id]['embeds'][0].add_field(
name=f'Group {math.ceil((index + 1) / 20)} / '
f'{math.ceil(len(coll_data[cardset_id]["players"]) / 20)}',
value=chunk_string
)
elif (index + 1) % 20 == 0:
coll_data[cardset_id]['embeds'][0].add_field(
name=f'Group {math.floor((index + 1) / 20)} / '
f'{math.ceil(len(coll_data[cardset_id]["players"]) / 20)}',
value=chunk_string
)
chunk_string = ''
display_embeds.append(coll_data[cardset_id]['embeds'][0])
return display_embeds
def get_pack_cover(pack):
if pack['pack_cardset'] is not None and pack['pack_cardset'] == 23:
return IMAGES['pack-pkmnbs']
elif pack['pack_type']['name'] in ['Premium', 'MVP']:
return IMAGES['pack-pre']
elif pack['pack_type']['name'] == 'Standard':
return IMAGES['pack-sta']
elif pack['pack_type']['name'] == 'Mario':
return IMAGES['pack-mar']
else:
return None
async def open_st_pr_packs(all_packs: list, team: dict, context):
pack_channel = get_channel(context, 'pack-openings')
pack_cover = get_pack_cover(all_packs[0])
if pack_cover is None:
pack_channel = context.channel
if not pack_channel:
raise ValueError(f'I cannot find the pack-openings channel. {get_cal_user(context).mention} - halp?')
pack_ids = await roll_for_cards(all_packs)
if not pack_ids:
logger.error(f'open_packs - unable to roll_for_cards for packs: {all_packs}')
raise ValueError(f'I was not able to unpack these cards')
all_cards = []
for p_id in pack_ids:
new_cards = await db_get('cards', params=[('pack_id', p_id)])
all_cards.extend(new_cards['cards'])
if not all_cards:
logger.error(f'open_packs - unable to get cards for packs: {pack_ids}')
raise ValueError(f'I was not able to display these cards')
# Present cards to opening channel
if type(context) == commands.Context:
author = context.author
else:
author = context.user
await context.channel.send(content=f'Let\'s head down to {pack_channel.mention}!')
await display_cards(all_cards, team, pack_channel, author, pack_cover=pack_cover)
async def get_choice_from_cards(
interaction: discord.Interaction, all_players: list = None, cover_title: str = None,
cover_desc: str = None, cover_image_url: str = None, callback=None, temp_message: str = None,
conf_message: str = None, delete_message: bool = False):
# Display them with pagination, prev/next/select
card_embeds = [
await get_card_embeds(
{'player': x, 'team': {'lname': 'Paper Dynasty', 'season': PD_SEASON, 'logo': IMAGES['logo']}}
) for x in all_players
]
logger.debug(f'card embeds: {card_embeds}')
if cover_title is not None and cover_image_url is not None:
page_num = 0
view = Pagination([interaction.user], timeout=30)
view.left_button.disabled = True
view.left_button.label = f'Prev: -/{len(card_embeds)}'
view.cancel_button.label = f'Take This Card'
view.cancel_button.style = discord.ButtonStyle.success
view.cancel_button.disabled = True
view.right_button.label = f'Next: 1/{len(card_embeds)}'
msg = await interaction.channel.send(
content=None,
embed=image_embed(
image_url=cover_image_url,
title=cover_title,
desc=cover_desc
),
view=view
)
else:
page_num = 1
view = Pagination([interaction.user], timeout=30)
view.left_button.label = f'Prev: -/{len(card_embeds)}'
view.left_button.disabled = True
view.cancel_button.label = f'Take This Card'
view.cancel_button.style = discord.ButtonStyle.success
view.right_button.label = f'Next: {page_num + 1}/{len(card_embeds)}'
msg = await interaction.channel.send(content=None, embeds=card_embeds[page_num - 1], view=view)
if temp_message is not None:
temp_msg = await interaction.channel.send(content=temp_message)
else:
temp_msg = None
while True:
await view.wait()
if view.value:
if view.value == 'cancel':
await msg.edit(view=None)
if callback is not None:
callback(all_players[page_num - 1])
if conf_message is not None:
if temp_msg is not None:
await temp_msg.edit(content=conf_message)
else:
await interaction.channel.send(content=conf_message)
break
if view.value == 'left':
page_num -= 1 if page_num > 1 else len(card_embeds)
if view.value == 'right':
page_num += 1 if page_num < len(card_embeds) else 1
else:
if page_num == len(card_embeds):
page_num = 1
else:
page_num += 1
view.value = None
view = Pagination([interaction.user], timeout=30)
view.left_button.label = f'Prev: {page_num - 1}/{len(card_embeds)}'
view.cancel_button.label = f'Take This Card'
view.cancel_button.style = discord.ButtonStyle.success
view.right_button.label = f'Next: {page_num + 1}/{len(card_embeds)}'
if page_num == 1:
view.left_button.label = f'Prev: -/{len(card_embeds)}'
view.left_button.disabled = True
elif page_num == len(card_embeds):
view.right_button.label = f'Next: -/{len(card_embeds)}'
view.right_button.disabled = True
await msg.edit(content=None, embeds=card_embeds[page_num - 1], view=view)
if delete_message:
await msg.delete()
return all_players[page_num - 1]
async def open_choice_pack(this_pack, team: dict, context, cardset_id: Optional[int] = None):
pack_channel = get_channel(context, 'pack-openings')
pack_cover = get_pack_cover(this_pack)
pack_type = this_pack['pack_type']['name']
players = []
if pack_type == 'Mario':
d1000 = random.randint(1, 1000)
if d1000 > 800:
rarity_id = 5
elif d1000 > 550:
rarity_id = 3
else:
rarity_id = 2
pl = await db_get(
'players/random',
params=[
('cardset_id', 8), ('min_rarity', rarity_id), ('max_rarity', rarity_id), ('limit', 4)
]
)
players = pl['players']
elif pack_type == 'Team Choice':
if this_pack['pack_team'] is None:
raise KeyError(f'Team not listed for Team Choice pack')
d1000 = random.randint(1, 1000)
pack_cover = this_pack['pack_team']['logo']
if d1000 > 800:
rarity_id = 5
pack_cover = IMAGES['mvp'][this_pack['pack_team']['lname']]
elif d1000 > 550:
rarity_id = 3
else:
rarity_id = 2
# # HAX FOR SOCC TO GET HIS MVP PACK
# if (team['abbrev'] in ['KSK', 'NJY']) and (datetime.datetime.today().day == 24):
# rarity_id = 5
min_rarity = rarity_id
while len(players) < 4 and rarity_id < 10:
params = [
('min_rarity', min_rarity), ('max_rarity', rarity_id), ('limit', 4 - len(players)),
('franchise', this_pack['pack_team']['lname'])
]
if this_pack['pack_team']['abbrev'] not in ['MSS']:
params.append(('in_packs', True))
if cardset_id is not None:
params.append(('cardset_id', cardset_id))
pl = await db_get(
'players/random',
params=params
)
if pl['count'] >= 0:
for x in pl['players']:
if x not in players:
players.append(x)
if len(players) < 4:
min_rarity += 1
rarity_id += 1
elif pack_type == 'Promo Choice':
if this_pack['pack_cardset'] is None:
raise KeyError(f'Cardset not listed for Promo Choice pack')
d1000 = random.randint(1, 1000)
pack_cover = IMAGES['mvp-hype']
cardset_id = this_pack['pack_cardset']['id']
rarity_id = 5
if d1000 > 800:
rarity_id = 8
while len(players) < 4 and rarity_id < 10:
pl = await db_get(
'players/random',
params=[('cardset_id', cardset_id), ('min_rarity', rarity_id), ('max_rarity', rarity_id),
('limit', 8)]
)
if pl['count'] >= 0:
for x in pl['players']:
if len(players) >= 4:
break
if x not in players:
players.append(x)
if len(players) < 4:
cardset_id = LIVE_CARDSET_ID
else:
# Get 4 MVP cards
rarity_id = 5
if pack_type == 'HoF':
rarity_id = 8
elif pack_type == 'All Star':
rarity_id = 3
min_rarity = rarity_id
while len(players) < 4 and rarity_id < 10:
params = [
('min_rarity', min_rarity), ('max_rarity', rarity_id), ('limit', 4), ('in_packs', True)
]
if this_pack['pack_team'] is not None:
params.append(('franchise', this_pack['pack_team']['lname']))
if cardset_id is not None:
params.append(('cardset_id', cardset_id))
pl = await db_get('players/random', params=params)
if pl['count'] > 0:
players.extend(pl['players'])
if len(players) < 4:
rarity_id += 3
if len(players) == 0:
logger.error(f'Could not create choice pack')
raise ConnectionError(f'Could not create choice pack')
if type(context) == commands.Context:
author = context.author
else:
author = context.user
logger.info(f'helpers - open_choice_pack - players: {players}')
# Display them with pagination, prev/next/select
card_embeds = [
await get_card_embeds(
# {'player': x, 'team': {'lname': 'Paper Dynasty', 'season': PD_SEASON, 'logo': IMAGES['logo']}}
{'player': x, 'team': team} # Show team and dupe info
) for x in players
]
logger.debug(f'card embeds: {card_embeds}')
page_num = 0
view = Pagination([author], timeout=30)
view.left_button.disabled = True
view.left_button.label = f'Prev: -/{len(card_embeds)}'
view.cancel_button.label = f'Take This Card'
view.cancel_button.style = discord.ButtonStyle.success
view.cancel_button.disabled = True
view.right_button.label = f'Next: 1/{len(card_embeds)}'
# React to selection
await context.channel.send(f'Let\'s head down to {pack_channel.mention}!')
msg = await pack_channel.send(
content=None,
embed=image_embed(pack_cover, title=f'{team["lname"]}', desc=f'{pack_type} Pack - Choose 1 of 4 {pack_type}s!'),
view=view
)
if rarity_id >= 5:
tmp_msg = await pack_channel.send(content=f'<@&1163537676885033010> we\'ve got an MVP!')
else:
tmp_msg = await pack_channel.send(content=f'We\'ve got a choice pack here!')
while True:
await view.wait()
if view.value:
if view.value == 'cancel':
await msg.edit(view=None)
try:
await give_cards_to_team(team, players=[players[page_num - 1]], pack_id=this_pack['id'])
except Exception as e:
logger.error(f'failed to create cards: {e}')
raise ConnectionError(f'Failed to distribute these cards.')
await db_patch('packs', object_id=this_pack['id'], params=[
('open_time', int(datetime.datetime.timestamp(datetime.datetime.now()) * 1000))
])
await tmp_msg.edit(
content=f'{players[page_num - 1]["p_name"]} has been added to the '
f'**{team["sname"]}** binder!'
)
break
if view.value == 'left':
page_num -= 1 if page_num > 1 else len(card_embeds)
if view.value == 'right':
page_num += 1 if page_num < len(card_embeds) else 1
else:
if page_num == len(card_embeds):
page_num = 1
else:
page_num += 1
view.value = None
view = Pagination([author], timeout=30)
view.left_button.label = f'Prev: {page_num - 1}/{len(card_embeds)}'
view.cancel_button.label = f'Take This Card'
view.cancel_button.style = discord.ButtonStyle.success
view.right_button.label = f'Next: {page_num + 1}/{len(card_embeds)}'
if page_num == 1:
view.left_button.label = f'Prev: -/{len(card_embeds)}'
view.left_button.disabled = True
elif page_num == len(card_embeds):
view.right_button.label = f'Next: -/{len(card_embeds)}'
view.right_button.disabled = True
await msg.edit(content=None, embeds=card_embeds[page_num - 1], view=view)
async def confirm_pack_purchase(interaction, owner_team, num_packs, total_cost, pack_embed):
view = Confirm(responders=[interaction.user], timeout=30)
await interaction.channel.send(
content=None,
embed=pack_embed
)
question = await interaction.channel.send(
content=f'Your Wallet: {owner_team["wallet"]}\n'
f'Pack{"s" if num_packs > 1 else ""} Price: {total_cost}\n'
f'After Purchase: {owner_team["wallet"] - total_cost}\n\n'
f'Would you like to make this purchase?',
view=view
)
await view.wait()
if not view.value:
await question.edit(
content='Saving that money. Smart.',
view=None
)
return None
else:
return question
def player_desc(this_player) -> str:
if this_player['p_name'] in this_player['description']:
return this_player['description']
return f'{this_player["description"]} {this_player["p_name"]}'
def player_pcard(this_player):
if this_player['image'] is not None and 'pitching' in this_player['image']:
return this_player['image']
elif this_player['image2'] is not None and 'pitching' in this_player['image2']:
return this_player['image2']
else:
return this_player['image']
def player_bcard(this_player):
if this_player['image'] is not None and 'batting' in this_player['image']:
return this_player['image']
elif this_player['image2'] is not None and 'batting' in this_player['image2']:
return this_player['image2']
# elif this_player['image'] is not None and 'pitching' in this_player['image']:
# return PITCHER_BATTING_CARD
else:
return this_player['image']