
     Ki"+                     n   d Z ddlZddlZddlmZmZ ddlZddlZddlZej                  j                  dej                  j                  ej                  j                  e                   ddlmZ dZdddd	d
ddZd ZddZd Zd Zd Zd Zd Zedk(  r e       Z eded    ded    d       yy)a	  
Capture Live Scores from ESPN API (Free, no proxy needed)
Captures in-game scores and period data for pace tracking.

Run: Every hour during game hours (or every 15 min for more granularity)
Cron: 0 * * * * /var/www/html/eventheodds/scripts/capture_live_scores.py
    N)datetimetimezone)normalize_to_fullz-https://site.api.espn.com/apis/site/v2/sports)
basketballnba)footballnfl)hockeynhl)baseballmlb)r   zmens-college-basketball)r   zcollege-football)r   r	   r   r   ncaabncaafc                      t        dd      5 } | D ]S  }|j                  d      s|j                  dd      d   j                         j                  d      d   c cd d d        S  	 d d d        y# 1 sw Y   yxY w)	Nz/var/www/html/eventheodds/.envrzSPORTS_DATABASE_URL==   ?r    )open
startswithsplitstrip)flines     scripts/capture_live_scores.pyload_db_urlr      s    	.	4 C 	CD56zz#q)!,224::3?BBC C	CC 	C s   A06A0%A00A9c                 H   | t         vrg S t         |    \  }}t         d| d| d}i }|r||d<   	 t        j                  ||d      }|j                  dk7  rg S |j                         }|j                  dg       S # t        $ r}t        d|  d	|        g cY d
}~S d
}~ww xY w)z?Get scoreboard from ESPN for a specific date (or today if None)/z/scoreboarddates   )paramstimeout   eventsz  Error fetching : N)	SPORT_MAPESPN_APIrequestsgetstatus_codejson	Exceptionprint)	leaguedatesportespn_leagueurlr"   respdataes	            r   get_espn_scoreboardr7   &   s    Y	"6*E;Jawa}K
8CFw	||C;s"Iyy{xx"%% !&A3/0	s#   (A; !A; ;	B!BB!B!c                    | j                  di       }|j                  di       }|j                  dd      }|j                  dd      }|j                  dd      }|j                  dd      }d	}|d
k(  rKd|v sd|v r
|dk  rdnd}n9|dk(  r	d|v rdnd}n+|dk(  r	d|v rdnd}n|dk(  r	d|v rdnd}n|dk(  rd}n|dkD  rd}||||||d
k(  |dk(  dS )z,Parse game status and period from ESPN eventstatustypestater   detailperiodr   displayClockNinHalftimeIntermission   HALFTIMEINTERMISSIONr   QQ1P1Q2P2   Q3P3   Q4OTpost)r;   r<   r=   period_nameclockis_liveis_final)r*   )eventr9   status_typer;   r<   r=   rR   rQ   s           r   parse_game_statusrW   >   s	   YYx$F**VR(KOOGR(E__Xr*FZZ!$FJJ~r*E K}>V#;(.!*Kq["%-$TKq["%-$TKq["%-$TKq[KaZK "D=VO     c                 ~   | j                  dg       }|sy|d   }|j                  dg       }dx}}dx}}|D ]v  }|j                  di       }	|j                  dd      }
|j                  d	d
      }	 |
rt        |
      nd}|dk(  r|}|	j                  dd
      }c|}|	j                  dd
      }x ||||fS #  d}Y <xY w)z&Parse home/away scores from ESPN eventcompetitions)NNNNr   competitorsNteamscore0homeAwayr   homeabbreviation)r*   int)rU   rZ   competitionr[   
home_score
away_score	home_team	away_teamcompr\   r]   	home_away	score_ints                r   parse_scoresrk   c   s    99^R0L%q/K//-4K""J  I	 5xx##&HHZ,		&+E
I "J4I"J4I5" iZ77	Is   1B66B<c                 `   | j                  dg       }|si i fS |d   }|j                  dg       }i }i }|D ]j  }|j                  dd      }|j                  dg       }t        |      D ]6  \  }	}
|	dz   }	 t        |
j                  dd            }|d	k(  r|||<   2|||<   8 l ||fS #  d}Y xY w)
z*Parse period-by-period scores (linescores)rZ   r   r[   r_   r   
linescoresr   valuer`   )r*   	enumeraterb   )rU   rZ   rc   r[   home_periodsaway_periodsrh   ri   rm   ir=   
period_numr]   s                r   parse_period_scoresrt      s    99^R0L2vq/K//-4KLL 1HHZ,	XXlB/
":. 
	1IAvQJFJJw23 F"+0Z(+0Z(
	1	1  %%s   4B''B-c                      t               } | st        d      t        j                  |       }|j	                         }|j                  d       |j                  d       |j                          t        d       t        d       t        dt        j                  t        j                        j                                 t        d       g d}d}d}d}dd	lm} t        j                  t        j                        }| |d
      z
  j                  d      }	|j                  d      }
|D ]  }t        |      }t        ||	      }|r||z   }|s%t        d|j!                          dt#        |       d       |t#        |      z  }|D ]=  }|j%                  dd      }|j%                  dd      }|j%                  dd      }d}|r4	 t        j&                  |j)                  dd            j+                         }t-        |      }t/        |      \  }}}}t1        ||      }t1        ||      }t3        |      \  }}|d   dk(  r||d   rd
ndz  }	 |j                  d||||||d   |d   ||t5        j6                  |      t5        j6                  |      |d   f       |d
z  }|d   rt        d| d| d | d!| d"|d    d#       @  |j                          t        dd        t        d%| d&| d'| d(       t        d       |dkD  rt        d)       t=        ||       |j?                          |j?                          |||d*S #  Y WxY w# t8        $ r,}t        d$| d|        |j;                          Y d}~d}~ww xY w)+z$Main function to capture live scoreszSPORTS_DATABASE_URL not seta  
        CREATE TABLE IF NOT EXISTS "LiveOddsSnapshot" (
            id SERIAL PRIMARY KEY,
            league VARCHAR(20) NOT NULL,
            "gameId" BIGINT,
            "externalGameId" VARCHAR(100),
            "gameDate" DATE,
            "homeTeam" VARCHAR(100),
            "awayTeam" VARCHAR(100),
            "gameStatus" VARCHAR(30),
            "gameTime" VARCHAR(50),
            "homeScore" INTEGER,
            "awayScore" INTEGER,
            "homePeriodScores" JSONB,
            "awayPeriodScores" JSONB,
            "currentPeriod" VARCHAR(20),
            "liveSpread" DOUBLE PRECISION,
            "liveTotal" DOUBLE PRECISION,
            "liveMoneylineHome" INTEGER,
            "liveMoneylineAway" INTEGER,
            "snapshotAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
            source VARCHAR(50) DEFAULT 'espn',
            "createdAt" TIMESTAMP WITH TIME ZONE DEFAULT NOW()
        )
    z
        CREATE INDEX IF NOT EXISTS idx_live_snapshot_game
        ON "LiveOddsSnapshot"(league, "externalGameId", "snapshotAt")
    z<============================================================zCAPTURE LIVE SCORES (ESPN API)zTime: )r   r	   r   r   r   )	timedeltar   )daysz%Y%m%d
r&   z games on scoreboardidr   namer0   NZz+00:00r;   prerS   a  
                    INSERT INTO "LiveOddsSnapshot" (
                        league, "externalGameId", "gameDate", "homeTeam", "awayTeam",
                        "gameStatus", "gameTime", "homeScore", "awayScore",
                        "homePeriodScores", "awayPeriodScores", "currentPeriod",
                        "snapshotAt", source
                    )
                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), 'espn')
                r<   rR   rQ   z  LIVE: z @ z - -z ()z  Error capturing z	RESULTS: z games,  live, 	 capturedz
Updating pace tracking...)gameslivecaptured) r   RuntimeErrorpsycopg2connectcursorexecutecommitr.   r   nowr   utc	isoformatrv   strftimer7   upperlenr*   fromisoformatreplacer0   rW   rk   r   rt   r,   dumpsr-   rollbackupdate_pace_from_snapshotsclose)db_urlconncurleaguestotal_games
total_livetotal_capturedrv   today	yesterday	today_strr/   r%   yesterday_eventsrU   event_idrz   date_str	game_dater9   rf   rg   rd   re   rp   rq   r6   s                              r   capture_live_scoresr      s   ]F899F#D
++-C KK  	4 KK  	 	KKM	(O	
*+	F8<<-779:
;<	(O,GKJN #LL&E**44X>Ix(I E $V, /vyA..F6<<>""S[M1EFGs6{" 6	 Eyyr*H99VR(Dyy,H I ( 6 6x7G7GX7V W \ \ ^I
 'u-F <H;N8Iy*j))V<I))V<I *=U)C&L, g%'vi0!a7J   HiI8$fWoz:JJ|,djj.F=)	 !#)$HYKs9+SAj\Y[\bck\l[mmnope6	 E N 	KKM	Bvh-	Ik](:,gn=MY
WX	(O +,"3-IIKJJL *.QQyR   *8*Bqc:; s%   3MA5MM	N!!NNc                     	 | j                  d       | j                  }|j                          t        d|        y# t        $ r(}t        d|        |j                          Y d}~yd}~ww xY w)z-Update GamePaceTracking from LiveOddsSnapshotan  
            INSERT INTO "GamePaceTracking"
            (league, "gameId", "gameDate", "homeTeam", "awayTeam", period,
             "homeScore", "awayScore", "totalScore", "snapshotAt")
            SELECT DISTINCT ON (league, "externalGameId", "snapshotAt")
                league,
                "externalGameId",
                "gameDate",
                "homeTeam",
                "awayTeam",
                "currentPeriod",
                "homeScore",
                "awayScore",
                "homeScore" + "awayScore",
                "snapshotAt"
            FROM "LiveOddsSnapshot"
            WHERE "homeScore" IS NOT NULL
              AND "awayScore" IS NOT NULL
              AND "snapshotAt" > NOW() - INTERVAL '1 hour'
            ORDER BY league, "externalGameId", "snapshotAt"
            ON CONFLICT (league, "gameId", "snapshotAt") DO NOTHING
        z  Pace records added: z  Pace update error: N)r   rowcountr   r.   r-   r   )r   r   
pace_addedr6   s       r   r   r   4  sg      	, \\
&zl34 %aS)*s   ;> 	A/A**A/__main__z
Complete: r   r   r   r   )N)__doc__r)   r   r   r   r,   sysospathinsertdirnameabspath__file__
team_namesr   r(   r'   r   r7   rW   rk   rt   r   r   __name__resultr.    rX   r   <module>r      s      '   277??277??8#<= > (: !6-	0"J8@&>ORdD z "F	L(z0B/C9
MN rX   