
    X&pi?A                         d Z ddlZddlZddlZddlZddlmZmZmZ dZd Z	d Z
d Zd Zd	 Zd
 Zd Zedk(  r e        yy)z4
Critical Data Gap Backfill - Final Working Version
    N)datetimetimezone	timedeltag333333?c                  ~   d} 	 t        | d      5 }|D ]S  }|j                  d      s|j                  dd      d   j                         j                  d      d   c cd d d        S  	 d d d        t
        j                  j                  dd	      j                  d      d   S # 1 sw Y   ;xY w# t        $ r Y Iw xY w)
Nz/var/www/html/eventheodds/.envrzSPORTS_DATABASE_URL==   ?r   SPORTS_DATABASE_URL )open
startswithsplitstripFileNotFoundErrorosenvironget)env_pathflines      A/var/www/html/eventheodds/scripts/backfill_critical_gaps_final.pyload_db_urlr      s    /H(C  	GA G??#9:::c1-a0668>>sCAFF	G 	GG	G ::>>/4::3?BB	G 	G  s9   B0 B$6B$	B0 (B$*B0 $B-)B0 0	B<;B<c                  Z    t               } | st        d      t        j                  |       S )NzSPORTS_DATABASE_URL not set)r   RuntimeErrorpsycopg2connect)db_urls    r   get_db_connectionr      s)    ]F899F##    c                     t        d       t        d       t        d       t               } | j                         }|j                  d       |j                  d       | j	                          d}dD ]  }t        d| d	       d
}dddddd| dd}	 t        j                  ||d      }|j                  dk7  rt        d|j                          c|j                         }|j                  dg       }t        dt        |       d       |D ]  }		 |j                  d||	j                  d      |	j                  d      |	j                  d      xs |	j                  d      |	j                  d      |	j                  d      |	j                  d      |	j                  d      |	j                  d       |	j                  d!      |	j                  d"      |	j                  d#      |	j                  d$      |	j                  d%      |	j                  d&      |	j                  d'      f       |d(z  }" | j	                           |j                          | j                          t        d,| d-       |S # t        $ r)}
t        d)|
        | j                          Y d*}
~
d*}
~
ww xY w# t        $ r)}
t        d+|
        | j                          Y d*}
~
hd*}
~
ww xY w).z1Backfill NHL goalie stats from NHL Stats REST API=
============================================================z1. NHL GOALIE STATS BACKFILL<============================================================a  
        CREATE TABLE IF NOT EXISTS "NHLGoalieStats" (
            id BIGSERIAL PRIMARY KEY,
            season VARCHAR(20),
            player_id INT,
            goalie_name VARCHAR(100),
            team_abbrev VARCHAR(10),
            games_played INT,
            games_started INT,
            wins INT,
            losses INT,
            ot_losses INT,
            save_pctg FLOAT,
            goals_against_avg FLOAT,
            shutouts INT,
            shots_against INT,
            saves INT,
            goals_against INT,
            time_on_ice INT,
            updated_at TIMESTAMP DEFAULT NOW(),
            UNIQUE(season, player_id)
        )
    zWCREATE INDEX IF NOT EXISTS idx_nhlgoalie_team ON "NHLGoalieStats" (team_abbrev, season)r   )2025202620242025z
Fetching goalies for season z...z1https://api.nhle.com/stats/rest/en/goalie/summaryfalsez/[{"property":"gamesPlayed","direction":"DESC"}]   z	seasonId=z and gameTypeId=2)isAggregateisGamesortstartlimit
cayenneExp   )paramstimeoutz  API returned dataz  Found z goaliesa  
                        INSERT INTO "NHLGoalieStats" (
                            season, player_id, goalie_name, team_abbrev,
                            games_played, games_started, wins, losses, ot_losses,
                            save_pctg, goals_against_avg, shutouts, shots_against,
                            saves, goals_against, time_on_ice
                        )
                        VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
                        ON CONFLICT (season, player_id) DO UPDATE SET
                            games_played = EXCLUDED.games_played,
                            wins = EXCLUDED.wins,
                            losses = EXCLUDED.losses,
                            save_pctg = EXCLUDED.save_pctg,
                            goals_against_avg = EXCLUDED.goals_against_avg,
                            shutouts = EXCLUDED.shutouts,
                            saves = EXCLUDED.saves,
                            updated_at = NOW()
                    playerIdgoalieFullNameteamAbbrevslastTeamAbbrevgamesPlayedgamesStartedwinslossesotLossessavePctggoalsAgainstAverageshutoutsshotsAgainstsavesgoalsAgainst	timeOnIcer	   z    Insert error: Nz  Fetch error: u   
✅ Inserted z goalie records)printr   cursorexecutecommitrequestsr   status_codejsonlen	Exceptionrollbackclose)conncurtotal	season_idurlr/   respr1   goaliesgoaliees              r   backfill_nhl_goaliesrV   #   s   	-	
()	&MD
++-C KK  	. KKijKKME- =	.yk=>A"E%i[0AB
0	<<FB?D3&(8(8'9:;99;Dhhvr*GHS\N(34!  $$KK !$ "6::j#96::FV;W

=1QVZZ@P5Q

=16::n3M

6*FJJx,@&**ZBX

:.

;P0Q

:.

>0J

7+VZZ-G

;/	#6 QJE; $D KKMs=~ IIKJJL	OE7/
23L ! $.qc23MMOO$  	OA3'(MMOO	sJ   ?J-A J-DI81J-8	J*J%J-%J**J--	K6KKc                     t        d       t        d       t        d       t               } | j                         }|j                  d       |j                  d       |j                  d       |j                  d       | j	                          |j                  d       |j
                  }| j	                          |j                          | j                          t        d	| d
       |S )z>Copy NBA player on/off impact from existing PlayerImpact tabler"   z2. NBA PLAYER ON/OFF BACKFILLr#   z-DROP TABLE IF EXISTS "NBAPlayerOnOff" CASCADEa  
        CREATE TABLE "NBAPlayerOnOff" (
            id BIGSERIAL PRIMARY KEY,
            season VARCHAR(20),
            player_id VARCHAR(100),
            player_name VARCHAR(100),
            team VARCHAR(50),
            games_played INT,
            games_missed INT,
            team_wins_with INT,
            team_losses_with INT,
            team_wins_without INT,
            team_losses_without INT,
            win_pct_with FLOAT,
            win_pct_without FLOAT,
            win_pct_diff FLOAT,
            avg_pts_with FLOAT,
            avg_pts_without FLOAT,
            net_impact FLOAT,
            updated_at TIMESTAMP DEFAULT NOW(),
            UNIQUE(season, player_id)
        )
    zACREATE INDEX idx_nbaonoff_team ON "NBAPlayerOnOff" (team, season)zHCREATE INDEX idx_nbaonoff_impact ON "NBAPlayerOnOff" (win_pct_diff DESC)a  
        INSERT INTO "NBAPlayerOnOff" (
            season, player_id, player_name, team,
            games_played, games_missed,
            team_wins_with, team_losses_with,
            team_wins_without, team_losses_without,
            win_pct_with, win_pct_without, win_pct_diff,
            avg_pts_with, avg_pts_without, net_impact
        )
        SELECT
            CAST(season AS VARCHAR),
            "playerId",
            "playerName",
            team,
            "gamesPlayed",
            "gamesMissed",
            "teamWinsWithPlayer",
            "teamLossesWithPlayer",
            "teamWinsWithoutPlayer",
            "teamLossesWithoutPlayer",
            "winPctWithPlayer",
            "winPctWithoutPlayer",
            "winPctDiff",
            "avgPointsWithPlayer",
            "avgPointsWithoutPlayer",
            "netImpact"
        FROM "PlayerImpact"
        WHERE league = 'nba'
        ON CONFLICT (season, player_id) DO NOTHING
       ✅ Created z, NBA player on/off records from PlayerImpact)rB   r   rC   rD   rE   rowcountrL   )rM   rN   copieds      r   backfill_nba_on_offr[      s    	-	
)*	&MD
++-C KK?@KK  	. KKSTKKZ[KKM KK  	< \\FKKMIIKJJL	L L
MNMr    c                     t        d       t        d       t        d       t               } | j                         }|j                  d       |j                  d       | j	                          d}t        j                         }t        dd      D ]B  }|t        |      z
  }|j                  d	      }t        j                  t               d
| }	 t        j                  |d      }|j                  dk7  rj|j!                         }	|	j                  dg       }
|
D ]  }|j                  d      }|s|j                  dg       }|s-|d   }|j                  di       j                  di       j                  dd      set        j                  t               d| }	 t        j                  |d      }|j                  dk7  r|j!                         }|j                  di       }|j                  dg       }|sdx}}|d   j                  dg       D ]  }|j                  d      dk(  r|}|} |r|s|j                  dg       }|j                  dg       }t#        |      dk\  r/t#        |      dk\  r |j                  dd||j                  d      |j                  d i       j                  d!      |j                  d i       j                  d!      t%        |d   j                  d"d            t%        |d#   j                  d"d            t%        |d   j                  d"d            t%        |d#   j                  d"d            t%        |j                  d$d            t%        |j                  d$d            f       |j&                  dkD  r|d#z  } 	 |dkD  s|d%z  dk(  s$t        d&| d'       | j	                          E | j	                          |j+                          | j+                          t        d(| d)       |S # t(        $ r}Y d}~d}~ww xY w# t(        $ r}Y d}~d}~ww xY w)*zABackfill soccer half scoring from ESPN API using summary endpointr"   z3. SOCCER HALF SCORING BACKFILLr#   a  
        CREATE TABLE IF NOT EXISTS "SoccerPeriodScoring" (
            id BIGSERIAL PRIMARY KEY,
            league VARCHAR(20),
            external_game_id VARCHAR(100),
            game_date TIMESTAMP,
            home_team VARCHAR(100),
            away_team VARCHAR(100),
            home_1h INT,
            home_2h INT,
            away_1h INT,
            away_2h INT,
            home_total INT,
            away_total INT,
            created_at TIMESTAMP DEFAULT NOW(),
            UNIQUE(league, external_game_id)
        )
    z]CREATE INDEX IF NOT EXISTS idx_soccerperiod_date ON "SoccerPeriodScoring" (league, game_date)r   Z   )daysz%Y%m%dzLhttps://site.api.espn.com/apis/site/v2/sports/soccer/eng.1/scoreboard?dates=r.   )r0   r'   eventsidcompetitionsstatustype	completedFzIhttps://site.api.espn.com/apis/site/v2/sports/soccer/eng.1/summary?event=headerNcompetitorshomeAwayhome
linescores   a  
                            INSERT INTO "SoccerPeriodScoring" (
                                league, external_game_id, game_date,
                                home_team, away_team,
                                home_1h, home_2h, away_1h, away_2h,
                                home_total, away_total
                            )
                            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
                            ON CONFLICT (league, external_game_id) DO NOTHING
                        epldateteamdisplayNamedisplayValuer	   score
   z  Progress: z matches with half scoring...u
   ✅ Added z! soccer matches with half scoring)rB   r   rC   rD   rE   r   nowranger   strftimetimesleepREQUEST_DELAYrF   r   rG   rH   rI   intrY   rJ   rL   )rM   rN   rO   	base_date	days_backrl   date_strrQ   rR   r1   r_   eventevent_idra   compsummary_urlsummary_respsummary_datare   comps	home_data	away_datachome_lsaway_lsrU   s                             r   backfill_soccer_half_scoringr      s   	-	
+,	&MD
++-C KK  	$ KKopKKMEI1b\ W	9)44==*

=! ]]e\fgK	<<R0D3&99;DXXh+F @ 99T?  %yy<##Axx"-11&"=AA+uU 

=) ijrist0#+<<R#HL#//36 #/#4#4#6L)--h;F"JJ~r:E  ,00I	"1X\\-< *55,6()I()I	* %I 'mmL"=G'mmL"=G7|q(S\Q-> 	% "8UYYv->%MM&"599-H%MM&"599-H
~q AB
~q AB
~q AB
~q AB	gq 9:	gq 9:
( <<!+!QJE}@J 19qL'DEFKKMoWr 	KKMIIKJJL	Jug>
?@L !   		sb   &P.:B'P."&PP.	6P?P. ;P;P.=E"PP.	P+ P.&P++P..	Q=Qc                     t        d       t        d       t        d       t               } | j                         }|j                  d       |j                  d       | j	                          	 |j                  d       | j	                          |j                  d       |j                  }| j	                          t        d| d	       |j                  d
       |j                  }| j	                          |j                          | j                          t        d| d       |S #  | j                          Y xY w)z%Create injury status history trackingr"   z4. INJURY TIMESTAMP HISTORYr#   a  
        CREATE TABLE IF NOT EXISTS "InjuryStatusHistory" (
            id BIGSERIAL PRIMARY KEY,
            league VARCHAR(20),
            player_external_id VARCHAR(100),
            player_name VARCHAR(200),
            team VARCHAR(50),
            status VARCHAR(50),
            previous_status VARCHAR(50),
            injury VARCHAR(200),
            status_changed_at TIMESTAMP,
            created_at TIMESTAMP DEFAULT NOW()
        )
    ztCREATE INDEX IF NOT EXISTS idx_injuryhistory_player ON "InjuryStatusHistory" (player_external_id, status_changed_at)zOALTER TABLE "PlayerInjury" ADD COLUMN IF NOT EXISTS status_changed_at TIMESTAMPz
        UPDATE "PlayerInjury"
        SET status_changed_at = COALESCE(status_changed_at, "updatedAt", "createdAt", NOW())
        WHERE status_changed_at IS NULL
    z  Set timestamps for z injury recordsa  
        INSERT INTO "InjuryStatusHistory" (
            league, player_external_id, player_name, team, status, injury, status_changed_at
        )
        SELECT
            league,
            "playerExternalId",
            "playerName",
            team,
            status,
            "injuryType",
            COALESCE(status_changed_at, "updatedAt", NOW())
        FROM "PlayerInjury"
        WHERE status IS NOT NULL
    rX   z injury history records)rB   r   rC   rD   rE   rK   rY   rL   )rM   rN   updatedsnapshots       r   backfill_injury_timestampsr   j  s   	-	
'(	&MD
++-C KK  	 KK  G  HKKMef
 KK  	
 llGKKM	!'/
:; KK  	 ||HKKMIIKJJL	L
"9
:;OIs   /!D* *D>c                  n   t        d       t        d       t        dt        j                  t        j                        j                                 t        d       i } 	 t               | d<   	 t               | d<   	 t               | d	<   	 t               | d<   t        d       t        d       t        d       t        d| j                  dd              t        d| j                  dd              t        d| j                  d	d              t        d| j                  dd              t        d       | S # t        $ r2}t        d|        dd l}|j                          d| d<   Y d }~d }~ww xY w# t        $ r2}t        d|        dd l}|j                          d| d<   Y d }~6d }~ww xY w# t        $ r2}t        d
|        dd l}|j                          d| d	<   Y d }~fd }~ww xY w# t        $ r2}t        d|        dd l}|j                          d| d<   Y d }~d }~ww xY w)Nr#   z"CRITICAL DATA GAP BACKFILL - FINALzTime: nhl_goalieszNHL Goalie error: r   
nba_on_offzNBA On/Off error: soccer_halveszSoccer error: injury_historyzInjury error: r"   zBACKFILL COMPLETEzNHL Goalies: zNBA On/Off: zSoccer Half Scores: zInjury History: )rB   r   rr   r   utc	isoformatrV   rJ   	traceback	print_excr[   r   r   r   )resultsrU   r   s      r   mainr     s   	&M	
./	F8<<-779:
;<	&MG#!5!7" 3 5%#?#A &$>$@ ! 
-	
	&M	M'++mQ78
9:	L\156
78	 _a!@ A
BC	W[[)91=>
?@	&MNU  #"1#&'!"	#  ""1#&' !	"  %qc"##$ 	%  &qc"#$% !	&s`   "D? 0E= >F; G9 ?	E:'E55E:=	F8'F33F8;	G6'G11G69	H4'H//H4__main__)__doc__rF   r   r   ru   r   r   r   rw   r   r   rV   r[   r   r   r   __name__ r    r   <module>r      sd      	  2 2	C$i^Ld@LCR5p zF r    