""" Submit Tony Smehrik to Paper Dynasty Database Custom pitcher with: - Hand: Left - Position: SP/RP (starter_rating: 5, relief_rating: 5) - Combined OPS: 0.585 - OPS vs L: 0.465 (dominant same-side) - OPS vs R: 0.645 (weaker opposite-side) - K-rate vs L: ~20% (average) - K-rate vs R: ~8% (very low) - FB% vs L: ~44% (average) - FB% vs R: ~56% (high) - Team: Custom Ballplayers - Cardset ID: 29 NO AWS UPLOAD - preview via PD API first """ import asyncio from datetime import datetime from db_calls import db_get, db_post, db_patch, db_put from custom_cards.tony_smehrik_preview import calculate_pitcher_rating, DEFAULT_XCHECKS # Configuration CARDSET_ID = 29 CARDSET_NAME = "2005 Custom" SEASON = 2005 PLAYER_DESCRIPTION = "2005 Custom" # Player info PLAYER_NAME_FIRST = "Tony" PLAYER_NAME_LAST = "Smehrik" HAND = "L" STARTER_RATING = 5 RELIEF_RATING = 5 CLOSER_RATING = None async def main(): """Create Tony Smehrik pitcher card in database.""" print("\n" + "="*70) print("SUBMITTING TONY SMEHRIK TO DATABASE") print("="*70) # Step 1: Calculate ratings (same as preview) print("\nCalculating ratings...") pit_hand = 'L' vl = calculate_pitcher_rating( vs_hand='L', pit_hand=pit_hand, avg=0.185, obp=0.240, slg=0.225, bb_pct=0.055, k_pct=0.20, hr_per_hit=0.04, triple_per_hit=0.02, double_per_hit=0.22, fb_pct=0.35, gb_pct=0.45, hard_pct=0.30, med_pct=0.50, soft_pct=0.20, oppo_pct=0.26, hr_fb_pct=0.06, ) vr = calculate_pitcher_rating( vs_hand='R', pit_hand=pit_hand, avg=0.245, obp=0.305, slg=0.340, bb_pct=0.075, k_pct=0.08, hr_per_hit=0.07, triple_per_hit=0.02, double_per_hit=0.24, fb_pct=0.45, gb_pct=0.35, hard_pct=0.34, med_pct=0.46, soft_pct=0.20, oppo_pct=0.26, hr_fb_pct=0.09, ) # Apply same manual adjustments as preview # HR adjustments: half of all OB chances go to HR vl_total_hits = (vl['homerun'] + vl['bp_homerun'] + vl['triple'] + vl['double_three'] + vl['double_two'] + vl['double_cf'] + vl['single_two'] + vl['single_one'] + vl['single_center'] + vl['bp_single']) vl_total_ob = vl_total_hits + vl['walk'] + vl['hbp'] vl_hr_total = vl_total_ob / 2 vl['bp_homerun'] = round(vl_hr_total / 2) vl['homerun'] = round((vl_hr_total - vl['bp_homerun']) * 20) / 20 vl['hbp'] = 1.0 vr_total_hits = (vr['homerun'] + vr['bp_homerun'] + vr['triple'] + vr['double_three'] + vr['double_two'] + vr['double_cf'] + vr['single_two'] + vr['single_one'] + vr['single_center'] + vr['bp_single']) vr_total_ob = vr_total_hits + vr['walk'] + vr['hbp'] vr_hr_total = vr_total_ob / 2 vr['bp_homerun'] = round(vr_hr_total / 2) vr['homerun'] = round((vr_hr_total - vr['bp_homerun']) * 20) / 20 vr['hbp'] = 1.0 # Reduce singles to compensate for HR increase vl_new_hr_total = vl['homerun'] + vl['bp_homerun'] vl_hr_increase = vl_new_hr_total vl_singles_to_reduce = vl_hr_increase reduce_from_one = min(vl['single_one'], vl_singles_to_reduce) vl['single_one'] -= reduce_from_one vl_singles_to_reduce -= reduce_from_one reduce_from_two = min(vl['single_two'], vl_singles_to_reduce) vl['single_two'] -= reduce_from_two vl_singles_to_reduce -= reduce_from_two reduce_from_bp = min(vl['bp_single'], vl_singles_to_reduce) vl['bp_single'] -= reduce_from_bp vl_singles_to_reduce -= reduce_from_bp if vl_singles_to_reduce > 0: vl['double_cf'] = max(0, vl['double_cf'] - vl_singles_to_reduce) vr_new_hr_total = vr['homerun'] + vr['bp_homerun'] vr_old_hr_total = 0.80 + 1.00 vr_hr_increase = vr_new_hr_total - vr_old_hr_total vr_singles_to_reduce = vr_hr_increase reduce_from_one = min(vr['single_one'], vr_singles_to_reduce) vr['single_one'] -= reduce_from_one vr_singles_to_reduce -= reduce_from_one reduce_from_two = min(vr['single_two'], vr_singles_to_reduce) vr['single_two'] -= reduce_from_two vr_singles_to_reduce -= reduce_from_two reduce_from_bp = min(vr['bp_single'], vr_singles_to_reduce) vr['bp_single'] -= reduce_from_bp vr_singles_to_reduce -= reduce_from_bp if vr_singles_to_reduce > 0: vr['double_cf'] = max(0, vr['double_cf'] - vr_singles_to_reduce) # Force BP-SI values vl['bp_single'] = 5.0 vr['bp_single'] = 3.0 # Adjust strikeouts to hit 108 for rating in [vl, vr]: total = sum([ rating['homerun'], rating['bp_homerun'], rating['triple'], rating['double_three'], rating['double_two'], rating['double_cf'], rating['single_two'], rating['single_one'], rating['single_center'], rating['bp_single'], rating['hbp'], rating['walk'], rating['strikeout'], rating['flyout_lf_b'], rating['flyout_cf_b'], rating['flyout_rf_b'], rating['groundout_a'], rating['groundout_b'], rating['xcheck_p'], rating['xcheck_c'], rating['xcheck_1b'], rating['xcheck_2b'], rating['xcheck_3b'], rating['xcheck_ss'], rating['xcheck_lf'], rating['xcheck_cf'], rating['xcheck_rf'] ]) diff = 108 - total rating['strikeout'] = round((rating['strikeout'] + diff) * 20) / 20 # Calculate OPS for verification ops_vl = vl['obp'] + vl['slg'] ops_vr = vr['obp'] + vr['slg'] combined_ops = (ops_vr + ops_vl + max(ops_vl, ops_vr)) / 3 print(f" OPS vs L: {ops_vl:.3f}") print(f" OPS vs R: {ops_vr:.3f}") print(f" Combined OPS: {combined_ops:.3f}") # Step 2: Verify cardset exists print(f"\nVerifying cardset '{CARDSET_NAME}' (ID: {CARDSET_ID})...") c_query = await db_get('cardsets', params=[('id', CARDSET_ID)]) if c_query['count'] == 0: print(f" ERROR: Cardset ID {CARDSET_ID} not found!") return print(f" ✓ Cardset verified") # Step 3: Create Player record print("\nCreating Player record...") now = datetime.now() release_date = f"{now.year}-{now.month}-{now.day}" bbref_id = f"custom_{PLAYER_NAME_LAST.lower()}{PLAYER_NAME_FIRST[0].lower()}01" player_payload = { 'p_name': f'{PLAYER_NAME_FIRST} {PLAYER_NAME_LAST}', 'cost': '100', # Default cost 'image': 'change-me', 'mlbclub': 'Custom Ballplayers', 'franchise': 'Custom Ballplayers', 'cardset_id': CARDSET_ID, 'set_num': 99999, 'rarity_id': 3, # Starter rarity 'pos_1': 'SP', 'pos_2': 'RP', 'description': PLAYER_DESCRIPTION, 'bbref_id': bbref_id, 'fangr_id': 0, 'mlbplayer_id': None, 'is_custom': True, } player = await db_post('players', payload=player_payload) player_id = player['player_id'] print(f" ✓ Created Player ID: {player_id}") # Update player with API image URL for preview api_image_url = f"https://pd.manticorum.com/api/v2/players/{player_id}/pitchingcard?d={release_date}" await db_patch('players', object_id=player_id, params=[('image', api_image_url)]) print(f" ✓ Updated Player with API image URL") # Step 4: Create PitchingCard print("\nCreating PitchingCard...") pitching_card_payload = { 'cards': [{ 'player_id': player_id, 'key_bbref': bbref_id, 'key_fangraphs': 0, 'key_mlbam': 0, 'key_retro': '', 'name_first': PLAYER_NAME_FIRST, 'name_last': PLAYER_NAME_LAST, 'hand': HAND, 'starter_rating': STARTER_RATING, 'relief_rating': RELIEF_RATING, 'closer_rating': CLOSER_RATING, }] } await db_put('pitchingcards', payload=pitching_card_payload, timeout=10) # Get the created card ID pc_query = await db_get('pitchingcards', params=[('player_id', player_id)]) pitchingcard_id = pc_query['cards'][0]['id'] print(f" ✓ Created PitchingCard ID: {pitchingcard_id}") # Step 5: Create PitchingCardRatings print("\nCreating PitchingCardRatings...") # Build ratings payload (remove display-only fields) def build_rating_payload(rating, pitchingcard_id): return { 'pitchingcard_id': pitchingcard_id, 'vs_hand': rating['vs_hand'], 'homerun': rating['homerun'], 'bp_homerun': rating['bp_homerun'], 'triple': rating['triple'], 'double_three': rating['double_three'], 'double_two': rating['double_two'], 'double_cf': rating['double_cf'], 'single_two': rating['single_two'], 'single_one': rating['single_one'], 'single_center': rating['single_center'], 'bp_single': rating['bp_single'], 'hbp': rating['hbp'], 'walk': rating['walk'], 'strikeout': rating['strikeout'], 'flyout_lf_b': rating['flyout_lf_b'], 'flyout_cf_b': rating['flyout_cf_b'], 'flyout_rf_b': rating['flyout_rf_b'], 'groundout_a': rating['groundout_a'], 'groundout_b': rating['groundout_b'], 'xcheck_p': rating['xcheck_p'], 'xcheck_c': rating['xcheck_c'], 'xcheck_1b': rating['xcheck_1b'], 'xcheck_2b': rating['xcheck_2b'], 'xcheck_3b': rating['xcheck_3b'], 'xcheck_ss': rating['xcheck_ss'], 'xcheck_lf': rating['xcheck_lf'], 'xcheck_cf': rating['xcheck_cf'], 'xcheck_rf': rating['xcheck_rf'], } ratings_payload = { 'ratings': [ build_rating_payload(vl, pitchingcard_id), build_rating_payload(vr, pitchingcard_id), ] } await db_put('pitchingcardratings', payload=ratings_payload, timeout=10) print(f" ✓ Created ratings for vs L and vs R") # Step 6: Create CardPositions print("\nCreating CardPositions...") positions_payload = { 'positions': [ { 'player_id': player_id, 'position': 'P', } ] } await db_put('cardpositions', payload=positions_payload, timeout=10) print(f" ✓ Created position record: P") # Summary print("\n" + "="*70) print("✓ TONY SMEHRIK CREATED SUCCESSFULLY!") print("="*70) print(f"\nPlayer ID: {player_id}") print(f"PitchingCard ID: {pitchingcard_id}") print(f"Cardset: {CARDSET_NAME} (ID: {CARDSET_ID})") print(f"Hand: {HAND}") print(f"Starter Rating: {STARTER_RATING} | Relief Rating: {RELIEF_RATING}") print(f"\nOffensive Profile (OPS Against):") print(f" vs LHB: .185/.240/.225 ({ops_vl:.3f} OPS)") print(f" vs RHB: .245/.305/.340 ({ops_vr:.3f} OPS)") print(f" Combined: {combined_ops:.3f}") print(f"\nPreview card (NO S3 upload yet):") print(f" PNG: {api_image_url}") print(f" HTML: {api_image_url}&html=true") print("") if __name__ == "__main__": asyncio.run(main())