
    oi7                        d Z ddlZddlZddlmZmZ i ddddddddd	d
dd
dd
dd
ddddddddddddddddddi ddddddddddd dd!dd"dd#d$d%d$d&d$d'd$d(d$d)d*d+d*d,d*d-d*i d.d/d0d/d1d/d2d/d3d4d5d4d6d4d7d4d8d4d9d:d;d:d<d:d=d:d>d?d@d?dAd?dBd?i dCdDdEdDdFdDdGdDdHdIdJdIdKdIdLdIdMdNdOdNdPdNdQdNdRdSdTdSdUdSdVdSdWdXi dYdXdZdXd[dXd\d]d^d]d_d]d`d]dad]dbdcdddcdedcdfdcdgdcdhdidjdidkdidldii dmdndodndpdndqdndrdsdtdsdudsdvdsdwdxdydxdzdxd{dxd|dxd}d~dd~dd~dd~i dd~ddddddddddddddddddddddddddddddddddddddddddddi ddddddddddddddddddddddddddddddddddi ddddddddddddddddddddddd"ddd$dd$d(d$dd*dd*i d-d*dd/dd/d2d/dddddddddd:dd:d=d:dd?dd?dd?dBd?ddʓddʓi ddʓddʓddʓddГddГddГddГddՓddՓddՓddՓddՓddDddDdGdDddݓddݓi ddݓddSddSdVdSdd]dd]dad]dddddddddddddeddgdddddi ddddddddddxddxd|dxddddddddddddddddd dddi ddddddddddd	dd
dddddddddddddddddddi dddddddddd
dd
dd
ddddddddd dd!dd"dd#dd$dd%di ddd&dd'dddd(d)d*d)d+d)d,d)d-d)d.d/d0d/d1d/d2d/d3d$d4d$d(d$d5d/i d6d/d2d/d7d8d9d8d:d8d;d8d<d=dd=d>d=d?d=d@dAddAdBdAdCdAdDd]dEd]dad]i dFdGdHdGdIdGdJdGdKdGdLdMdNdMdOdMdPdMdQdMdRdSdTdSdUdSdVdSdWdSdXdYdZdYi d[dYd\d]d^d]d_d]d`dadbdadcdadddadedadfdxdgdxd|dxdhddiddjddddkdli dmdldndldodldpdldqddrddddsdtdudtdvdtdwdtdxdydzdyd{dyd|dyddyd}di d~dddddddddddddddddddddddddddddddddddddddddZd Zd Zd Ze	dk(  r e        yy(  z
Sync odds from GameOdds to SportsGame using team name matching.
Fixes games that have odds in GameOdds but not in SportsGame.

Run: python3 scripts/sync_gameodds_to_sportsgame.py
    N)datetimetimezonezatlanta hawksATLhawksatlantaatlzboston celticsBOScelticsbostonboszbrooklyn netsBKNnetsbrooklynbknzcharlotte hornetsCHAhornets	charlottechazchicago bullsCHIbullschicagochizcleveland cavaliersCLE	cavalierscavs	clevelandclezdallas mavericksDAL	mavericksmavsdallasdalzdenver nuggetsDENnuggetsdenverdenzdetroit pistonsDETpistonsdetroitdetzgolden state warriorsGSWwarriorszgolden stategswgszhouston rocketsHOUrocketshoustonhouzindiana pacersINDpacersindianaindzlos angeles clippersLACclipperszla clipperslaczlos angeles lakersLALlakersz	la lakerslalzmemphis grizzliesMEM	grizzliesmemphismemz
miami heatMIAheatmiamimiazmilwaukee bucksMILbucks	milwaukeemilzminnesota timberwolvesMINtimberwolveswolves	minnesotaminznew orleans pelicansNOPpelicansznew orleansnopnoznew york knicksNYKknicksznew yorknykzoklahoma city thunderOKCthunderzoklahoma cityokczorlando magicORLmagicorlandoorlzphiladelphia 76ersPHI76erssixersphiladelphiaphizphoenix sunsPHXsunsphoenixphxphozportland trail blazersPORztrail blazersblazersportlandporzsacramento kingsSACkings
sacramentosaczsan antonio spursSASspurszsan antoniosassaztoronto raptorsTORraptorsUTAWAS)torontotorz	utah jazzjazzutahutazwashington wizardswizards
washingtonwaswshzarizona cardinalsARI	cardinalsarizonaarizatlanta falconsfalconszbaltimore ravensBALravens	baltimorebalzbuffalo billsBUFbillsbuffalobufzcarolina panthersCARpantherscarolinacarzchicago bearsbearszcincinnati bengalsCINbengals
cincinnaticinzcleveland brownsbrownszdallas cowboyscowboyszdenver broncosbroncoszdetroit lionslionszgreen bay packersGBpackersz	green baygbzhouston texanstexanszindianapolis coltscoltsindianapoliszjacksonville jaguarsJAXjaguarsjacksonvillejaxjaczkansas city chiefsKCchiefszkansas citykczlas vegas raidersLVraidersz	las vegaslvlvrzlos angeles chargerschargerszlos angeles ramsLARramslarzmiami dolphinsdolphinszminnesota vikingsvikingsznew england patriotsNEpatriotsznew englandneznew orleans saintsNOsaintsznew york giantsNYGgiantsnygznew york jetsNYJjetsnyjzphiladelphia eagleseagleszpittsburgh steelersPITsteelers
pittsburghpitzsan francisco 49ersSF49erszsan franciscosfninerszseattle seahawksSEAseahawksseattleseaztampa bay buccaneersTB
buccaneersbucsz	tampa baytbztennessee titansTENtitans	tennesseetenzwashington commanders
commandersr}   r~   zanaheim ducksANAducksanaheimanazboston bruinsbruinszbuffalo sabressabreszcalgary flamesCGYflamescalgarycgyzcarolina hurricanes
hurricanescaneszchicago blackhawks
blackhawkszcolorado avalancheCOL	avalancheavscoloradocolzcolumbus blue jacketsCBJzblue jacketscolumbuscbjzdallas starsstarszdetroit red wingsz	red wingszedmonton oilersEDMoilersedmontonedmzflorida panthersFLAfloridaflazlos angeles kingsLAKlaklazminnesota wildwildzmontreal canadiensMTL	canadienshabsmontrealmtlznashville predatorsNSH	predatorspreds	nashvillenshznew jersey devilsNJDdevilsz
new jerseynjdnjznew york islandersNYI	islandersnyiznew york rangersNYRrangersnyrzottawa senatorsOTTsenatorssensottawaottzphiladelphia flyersflyerszpittsburgh penguinspenguinspenszsan jose sharksSJSsharkszsan josesjssjzseattle krakenkrakenzst. louis bluesSTLblueszst louis bluesstlztampa bay lightningTBL	lightningboltstblztoronto maple leafszmaple leafsleafsrw   zutah hockey clubry   rz   zvancouver canucksVANcanucks	vancouvervanzvegas golden knightsVGKzgolden knightsknightsvegasvgkzwashington capitalsWSHcapitalsWPG)capsr~   zwinnipeg jetsr   winnipegwpg)nbanflnhlc                 F   | sy t        |       j                         }t        |      dk  r|j                         r|S |j	                         }t
        j                  |i       }||v r||   S |j                         D ]  \  }}||v s||v s|c S  |d d j                         S )N      )	strstriplenisupperlowerTEAM_ALIASESgetitemsupper)	team_nameleagueteam_str
team_lowerleague_aliasesaliasabbrevs          @/var/www/html/eventheodds/scripts/sync_gameodds_to_sportsgame.pynormalize_teamrA  u   s    9~##%H
8}h..0!J!%%fb1N^#j))'--/ vJ*"5M BQ<    c                     d} 	 t        | d      5 }|D ]b  }|j                  d      s|j                  dd      d   j                         j                  d      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splitr1  FileNotFoundErrorosenvironr6  )env_pathflines      r@  load_db_urlrT     s    /H(C  	RA R??#9:::c1-a0668>>sCII#NqQQ	R 	RR	R ::>>/4::3?BB	R 	R  s:   B? B3AB3-	B? 7B39B? 3B<8B? ?	C
Cc                      t        d       t        d       t        dt        j                  t        j                        j                                 t        d       t               } t        j                  |       }|j                         }t        d       |j                  d       i }|j                         D ]:  \  }}}}}t        ||      }	t        ||      }
|	s$|
s'|t        |      |	|
f}|||<   < t        dt        |       d       t        d       |j                  d	       |j                         }t        dt        |       d
       t        d       g }|D ]n  }|\	  }}}}}}}}}|r|st        ||      }	t        ||      }
|t        |      |	|
f}|j                  |      }|sO|R|j!                  ||r| nd |||d|f       p |r+|j#                  d|       t        dt        |       d       nt        d       |j%                          t        d       |j                  d       t        dddddddddddd       t        dd dd dd dd        |j                         D ])  }|\  }}}}t        d|dd|dd|dd|xs d d!d	       + |j'                          |j'                          t        d"       t        d#t        |       d$       t        d       t        |      S )%Nz<============================================================zSYNC GAMEODDS TO SPORTSGAMEzTime: z"
[1] Building SportsGame lookup...z
        SELECT id, league, DATE("gameDate") as gd, "homeTeam", "awayTeam"
        FROM "SportsGame"
        WHERE "gameDate" >= '2024-10-01'
          AND "spreadHome" IS NULL
    z  Found z# SportsGame records missing spreadsz'
[2] Getting best odds from GameOdds...a  
        WITH best_spreads AS (
            SELECT DISTINCT ON (league, "gameId")
                league, "gameId", DATE("gameDate") as gd, "homeTeam", "awayTeam",
                "lineValue" as spread, "homeOdds" as spread_home_odds, "awayOdds" as spread_away_odds
            FROM "GameOdds"
            WHERE market = 'spreads' AND "gameDate" >= '2024-10-01'
            ORDER BY league, "gameId", "isBestLine" DESC NULLS LAST, "fetchedAt" DESC
        ),
        best_ml AS (
            SELECT DISTINCT ON (league, "gameId")
                league, "gameId", "homeOdds" as ml_home, "awayOdds" as ml_away
            FROM "GameOdds"
            WHERE market = 'h2h' AND "gameDate" >= '2024-10-01'
            ORDER BY league, "gameId", "isBestLine" DESC NULLS LAST, "fetchedAt" DESC
        ),
        best_total AS (
            SELECT DISTINCT ON (league, "gameId")
                league, "gameId", "lineValue" as total, "overOdds", "underOdds"
            FROM "GameOdds"
            WHERE market = 'totals' AND "gameDate" >= '2024-10-01'
            ORDER BY league, "gameId", "isBestLine" DESC NULLS LAST, "fetchedAt" DESC
        )
        SELECT
            s.league, s."gameId", s.gd, s."homeTeam", s."awayTeam",
            s.spread, m.ml_home, m.ml_away, t.total
        FROM best_spreads s
        LEFT JOIN best_ml m ON s.league = m.league AND s."gameId" = m."gameId"
        LEFT JOIN best_total t ON s.league = t.league AND s."gameId" = t."gameId"
    z games with odds in GameOddsz"
[3] Syncing odds to SportsGame...zodds-api-synca:  
            UPDATE "SportsGame"
            SET "spreadHome" = %s,
                "spreadAway" = %s,
                "moneylineHome" = %s,
                "moneylineAway" = %s,
                "total" = %s,
                "oddsSource" = %s,
                "updatedAt" = NOW()
            WHERE id = %s
        z
  Updated z SportsGame records with oddsz  No updates neededz
[4] Coverage Report:a  
        SELECT league,
            COUNT(*) FILTER (WHERE "homeScore" IS NOT NULL) as completed,
            COUNT(*) FILTER (WHERE "spreadHome" IS NOT NULL) as has_spread,
            ROUND(100.0 * COUNT(*) FILTER (WHERE "spreadHome" IS NOT NULL) /
                NULLIF(COUNT(*) FILTER (WHERE "homeScore" IS NOT NULL), 0), 1) as pct
        FROM "SportsGame"
        WHERE "gameDate" >= '2024-10-01'
          AND league IN ('nba', 'nfl', 'nhl', 'ncaab', 'ncaaf', 'epl', 'mlb')
        GROUP BY league
        ORDER BY completed DESC
    z  Leaguez<10 	Completedz>10z
Has Spreadz>12%z>8z
----------z------------z--------r   z>7.1fz=
============================================================zSync complete: z games updated)printr   nowr   utc	isoformatrT  psycopg2connectcursorexecutefetchallrA  r0  r2  r6  appendexecutemanycommitclose)db_urlconncur	sg_lookupsg_idr:  gdhomeaway	home_norm	away_normkeygameoddsupdatesrowgame_idspreadml_homeml_awaytotal	completed
has_spreadpcts                          r@  run_syncr}     s'   	(O	
'(	F8<<-779:
;<	(O]FF#D
++-C 

/0KK  	 I), #%vr4"40	"40	3r7Iy9C"IcN# 
HS^$$G
HI 

45KK  	< ||~H	HS]O#?
@A 

/0G KNHT4'54"40	"40	s2w	95c"V'NN!t *  
 
	 	
3w<.(EFG#$KKM 

"#KK  	 
BxnAk#.aS/A3r(
KL	Bvhaxq%
12||~ T-0*	:s6#,a	#a
3/?q%@PPQRST IIKJJL	/	OCL>
89	(Ow<rB  __main__)
__doc__r^  rO  r   r   r5  rA  rT  r}  __name__ rB  r@  <module>r     s$    	 ' '095BG%!*E3;UDI5 	 !' 0:5 CH 	U	 %.u	 7B5	 KPQV	
 	
 !(
 1:5
 CH 	u '25 ;A% JUV[ ^cdi 	E $/ 8>u GOPU X]^c 	% "+E 4<U EJ5 	5 #,U 5>u GLU 	  )3E <J5 SXY^ aefk 	5 #,U 5>u GLU 	% "*5 3<U EJ5 	 (25 ;H QVW\ 	e &.u 7B5 KPQV 	U %0 9B5 KPQV  	e!  $U!  -4U!  =B5!" 	5#" #*5#" 3>u#" GLU#$ 	!%%$ *8%$ AI%%$ R]^c%$ fklq%& 	'& (25'& ;H'& QVW\'& _cdi'( 	5)( #+E)( 4>u)( GLU)* 	 +* )25+* ;J5+* SXY^+, 	-, !(-, 1:5-, CH-. 	e/. &-e/. 6>u/. GUV[/. ^cdi/0 	10  &u10 /810 AFu10 OTUZ12 	!%32 *9%32 BKE32 T^_d32 glmr34 	E54 $+E54 4@54 INu56 	U76 %,U76 5B576 KPQV76 Y]^c78 	598 #,U98 @EUE5#USXaf=@!U!$/!8A5!JOQV!5!"+U!495! 	E! $,U! 5@! INu! 		! !(	! 1:5	! CH	!
 	U!
 %/!
 8B5!
 KPQV! 	! !(! 16u! 	e! &/! 8DU! MRSX! 	E! $,U! 5:5! 	%! "+E! 49%! 	%! "+E! 49%! 	! !(! 16u! 	T! $-d! 5@! HLT! 	%! "*5! 38! 	e! &-e! 6DU! MRSX! 	! (1%! :H! QVW\! _dej!  	d!!  %-d!!  5B4!!  JNt!!" 	T#!" $-d#!" 5@#!" HLT#!" TYZ^#!$ 	%!$ (25%!$ ;@%!& 	E'!& $*5'!& 38'!( 	%)!( ",U)!( 5:5)!* 	U+!* %.u+!* 7<U+!, 	-!, '1$-!, 9Ft-!, NRSW-!. 	d/!. %-d/!. 5B4/!. JNt/!0 	51!0 #+E1!0 49%1!2 	3!2 !'3!2 05e3!4 	u5!4 '/5!4 8=e5!6 	u7!6 '1%7!6 :Fu7!6 OTUZ7!8 	t9!8 &-d9!8 5DT9!8 LPQU9!8 X`ae9!: 	E;!: $.u;!: 7@;!: INu;!< 	=!< '3D=!< ;A$=!< ITUY=!< \`ae=!> 	E?!> $,U?!> 5@?!> INu?!@ 	 A!@ )5eA!@ >CEA!@ LQRWA!D!! '!095!BG!! (%!16! 	%! "*5! 38! 	%	! "*5	! 3<U	! EJ5	!
 	u!
 '3E!
 <CE!
 LQRW! 	e! &25! ;@! 	e! &1%! :?! HRSX! [`af! 	 ! )7! @J5! SXY^! 	!  '! 05e! 	U! %0! 9>u! 	5! #+E! 4>u! GLU! 	E! $.u! 7@! INu! 	U! %,U! 5:5! CG! 	%! "(! 16u! 	e! &1%! :@! ISTY! \abg!  	u!!  '25!!  ;B5!!  KVW\!!  _dej!!" 	U#!" %-e#!" 6B5#!" KPQV#!" Y]^c#!$ 	e%!$ &1%%!$ :?%!& 	E'!& $-e'!& 6;E'!( 	5)!( #-e)!( 6<U)!( EMe)!( V[\a)!* 	u+!* '/+!* 8=e+!, 	u-!, '1%-!, :@-!, INu-!. 	5/!. #+E/!. 4>u/!. GLU/!. UYZ_/!0 	%1!0 "*51!0 381!2 	53!2 #*53!2 3CE3!2 LQRW3!4 	u5!4 '255!4 ;B55!4 KPQV5!4 Y]^c5!6 	u7!6 '4U7!6 =DU7!6 MRSX7!8 	E9!8 $*59!8 389!: 	U;!: %.u;!: 7B5;!: KPQV;!< 	=!< (8=!< AJ5=!< SZ[`=!< chin=!> 	u?!> '1%?!> BGu5A!GeP  	CCL zJ rB  