
    i7              
          S r SSKrSSKrSSKrSSKJs  Jr  SSKJrJ	r	  \R                  " S5      rSSS.SS	S.S
SS.SSS./SSS.SSS./SSS.SSS.SSS.SSS.SSS.SSS./SSS.SSS.SSS.SSS./S.r0 SS_S S _S!S"_S#S"_S$S"_S%S"_S&S"_S'S"_S(S"_S)S"_S*S*_S+S"_S,S"_S-S"_S.S"_S/S"_S0S"_S"S"S1.Er0 S2/ S3Q_S4/ S5Q_S6/ S7Q_S8S9S:/_S;S</_S=/ S>Q_S?S@SA/_SBSCSD/_SESFSG/_SHSISJ/_SKSLSM/_SNSOSP/_SQ/ SRQ_SSSTSU/_SVSW/_SXSY/_SZS[S\/_0 S]/ S^Q_S_S`Sa/_SbScSd/_Se/ SfQ_SgShSi/_SjSkSl/_SmSnSo/_SpSqSr/_SsSt/_SuSvSw/_SxSySz/_S{S|S}/_S~SS/_SSS/_SSS/_SS/_SSS/_E0 S/ SQ_SS/_SSS/_SS/_SSS/_SSS/_SSSo/_SSS/_SSSa/_S/ SQ_SSS/_SSSl/_SSS/_S/ SQ_S/ SQ_SSS/_SS/_E0 SS/_SS/_SS/_SS/_SSS/_SSS/_SSS/_SS/_SS/_SS/_SS/_S/ SQ_SS/_SS/_SSS/_SSS/_SSS/_E0 SSS/_SS/_SS/_SSS/_SSS/_SSS/_SSS/_S/ SQ_SSS/_SSS/_SS/_SSS/_SSS/_GS GSGS/_GSGSGS/_GSGS/_GSGS	GS
/_E0 GSGSGS/_GSGSGS/_GSGS/_GSGS/_GSGSGS/_GSGS/_GSGSGS/_GSGS/_GSGS GS!/_GS"GS#GS$/_GS%GS&GS'/_GS(GS)GS*/_GS+GS,GS-/_GS./ GS/Q_GS0GS1/_GS2GS3/_GS4/ GS5Q_EGS6GS7/GS8GS9/GS:/GS;.ErGS< rGS= rGSCGS> jrGS? rGSDGS@ jrGSA rGSDGSB jrg(E  u  
Pre-Game Chatter Module for Luke.

Pulls headlines, injury news, and betting buzz from RSS feeds
and free sports news sources. Filters for teams in the matchup
so Bill gets relevant context alongside his strategy picks.

Sources:
  - ESPN (NHL, Soccer, NFL)
  - TSN (Canadian — Bill's home turf)
  - BBC Sport (Football + General)
  - Sportsnet (NHL/Canadian sports)
  - Sky Sports (Football)
  - The Guardian (Football)
  - Goal.com (Global football)

No API key required — pure RSS.
    N)datetime	timedeltazpregame-chatterzESPN NHLz&https://www.espn.com/espn/rss/nhl/news)nameurlz
TSN Hockeyzhttps://www.tsn.ca/rss/hockeyzSportsnet NHLz)https://www.sportsnet.ca/hockey/nhl/feed/z	BBC Sportz&https://feeds.bbci.co.uk/sport/rss.xmlzESPN NFLz&https://www.espn.com/espn/rss/nfl/newszTSN NFLzhttps://www.tsn.ca/rss/nflzESPN FCz)https://www.espn.com/espn/rss/soccer/newszBBC Footballz/https://feeds.bbci.co.uk/sport/football/rss.xmlz
TSN Soccerzhttps://www.tsn.ca/rss/soccerzSky Sports Footballz#https://www.skysports.com/rss/11095zThe Guardian Footballz(https://www.theguardian.com/football/rsszGoal.comz)http://www.goal.com/en/feeds/news?fmt=rss)nhlnflsoccermlsr   r   eplr	   serieaserie_aligue1ligue_1laligala_ligaliga_portugalr
   
bundesliga
eredivisieuclchampions_leagueeuropaeuropa_league)
conferenceconference_leaguezMontreal Canadiens)	canadienshabsmontrealzToronto Maple Leafs)zmaple leafsleafstorontozOttawa Senators)senatorssensottawazBoston BruinsbruinsbostonzNew York RangersrangerszPittsburgh Penguins)penguinspens
pittsburghzEdmonton OilersoilersedmontonzCalgary FlamesflamescalgaryzWinnipeg JetsjetswinnipegzVancouver Canuckscanucks	vancouverzTampa Bay Lightning	lightningz	tampa bayzFlorida PantherspanthersfloridazWashington Capitals)capitalscaps
washingtonzCarolina Hurricanes
hurricanescarolinazNew Jersey DevilsdevilszNew York Islanders	islanderszMinnesota Wildwild	minnesotazColorado Avalanche)	avalancheavscoloradozDallas StarsstarsdallaszSt. Louis Bluesbluesz	st. louiszNashville Predators)	predatorspreds	nashvillezChicago Blackhawks
blackhawkschicagozDetroit Red Wingsz	red wingsdetroitzBuffalo SabressabresbuffalozSeattle KrakenkrakenseattlezUtah Hockey ClubutahzAnaheim DucksducksanaheimzSan Jose Sharkssharkszsan josezLos Angeles Kingskingszla kingszVegas Golden Knightszgolden knightsvegaszColumbus Blue Jacketszblue jacketscolumbusArsenalarsenalgunners	Liverpool	liverpoolzManchester Cityzman cityzmanchester cityzManchester United)z
man unitedzmanchester unitedzman utdChelseachelseazTottenham Hotspur	tottenhamspurszNewcastle United	newcastlezAston Villazaston villavillazKansas City Chiefschiefszkansas cityzBuffalo BillsbillszPhiladelphia EagleseaglesphiladelphiazDallas CowboyscowboyszSan Francisco 49ers)49erszsan francisconinerszBaltimore Ravensravens	baltimorezDetroit LionslionszGreen Bay Packerspackersz	green bayzAC Milan)milanzac milan	rossonerizInter Milan)interzinter milan
nerazzurriJuventusjuventusjuveNapolinapolizAS RomaromaLaziolazioAtalantaatalanta
Fiorentina
fiorentinazParis Saint-Germainpsgzparis saint-germainzOlympique Marseille	marseilleomLyonlyonzolympique lyonnaisMonacomonacoLillelilleBenficabenficaPortoportozSporting CP)sportingzsporting cpzsporting lisbonBragabragazReal Madridzreal madrid	Barcelona	barcelonabarcazAtletico Madridatleticozatletico madridzReal Sociedadzreal sociedadsociedadzAthletic Bilbaozathletic bilbaobilbao
Villarreal
villarrealSevillasevillazBayern Munichbayernzbayern munichzBorussia Dortmunddortmundbvbz
RB Leipzigleipzigz
rb leipzigzBayer Leverkusen
leverkusenzbayer leverkusenzCF Montreal)zcf montrealzmontreal cfu   cf montréalz
Toronto FCz
toronto fctfczVancouver Whitecaps	whitecapszvancouver whitecapszInter Miamizinter miamiLAFClafczlos angeles fcz	LA Galaxyz	la galaxygalaxyzNew York Red Bullsz	red bullszny red bullszNew York City FCnycfcznew york city fczAtlanta Unitedzatlanta unitedzSeattle Sounderssounderszseattle sounderszPortland Timberstimberszportland timberszColumbus Crewzcolumbus crewcrewzNashville SCznashville sczCharlotte FCzcharlotte fczSt. Louis City SCzst. louis cityzstl cityz	Austin FCz	austin fczFC Cincinnatizfc cincinnatifcczOrlando Cityzorlando cityzHouston Dynamodynamozhouston dynamozMinnesota Unitedzminnesota unitedloonszReal Salt Lakezreal salt lakerslzColorado Rapidsrapidszcolorado rapidszPhiladelphia Unionunionzphiladelphia unionzNew England Revolution)
revolutionrevsznew englandzChicago Firezchicago firez	FC Dallasz	fc dallaszSporting Kansas City)zsporting kczsporting kansas cityskcearthquakeszsan jose earthquakesz	dc unitedzd.c. unitedzsan diego fc)zSan Jose EarthquakeszD.C. UnitedzSan Diego FCc                 ^   / n [         R                  " U 5      nUR                  S5       GHC  n0 nUR                  S5      nUR                  S5      nUR                  S5      nUR                  S5      nUb.  UR                  (       a  UR                  R                  5       US'   UbI  UR                  (       a8  [        R                  " SSUR                  5      n	U	R                  5       SS	 US
'   Ub.  UR                  (       a  UR                  R                  5       US'   Ub.  UR                  (       a  UR                  R                  5       US'   SU;   d  GM2  UR                  U5        GMF     U$ ! [         R                   a#  n
[        R                  SU
 35         Sn
A
U$ Sn
A
ff = f)z7Parse RSS XML using stdlib xml.etree (no dependencies).itemtitledescriptionlinkpubDateNz<[^>]+>    summary	publishedzRSS parse error: )ET
fromstringiterfindtextstripresubappend
ParseErrorloggerwarning)contentitemsrootr   entrytitle_eldesc_ellink_elpub_elcleanes              6/Users/bsyrros/clawd/whatsapp-agent/pregame_chatter.py_parse_rss_stdlibr      sW   E0}}W%IIf%DEyy)Hii.Gii'GYYy)F#!)!4!4!6g"w||z2w||<#(;;=##6i "w|| ' 2 2 4f!fkk%+[[%6%6%8k"%U#' &, L == 0*1#.//L0s   EE5 E5 5F,	F''F,c                     SSK nUR                  U 5      n/ nUR                   HH  nUR                  [	        USS5      [	        USS5      SS [	        USS5      [	        USS5      S	.5        MJ     U$ ! [
         a    [        U 5      s $ f = f)
z6Parse RSS content, preferring feedparser if available.r   Nr   r   r   r   r   r   )r   r   r   r   )
feedparserparseentriesr   getattrImportErrorr   )r   r   feedr   r   s        r   
_parse_rssr      s    *(\\ELL 4"5)R8#>vr2$UK<	  "  * ))*s   A0A3 3B
Bc                 2    [         R                  " XSS0S9nUR                  S:X  a  [        UR                  5      $ [
        R                  SUR                   SU  35        / $ ! [         a'  n[
        R                  SU  SU 35        / s S	nA$ S	nAff = f)
z"Fetch and parse a single RSS feed.z
User-AgentzLuke-Sports-Agent/1.0)timeoutheadersr   zFeed returned z: zFeed fetch failed (z): N)requestsgetstatus_coder   r   r   debug	Exception)r   r   respr   s       r   _fetch_feedr      s    ||C1;
  s"dii((LL>$*:*:);2cUCDI *3%s1#67	s"   ;A% &A% %
B/BBBc                     U (       d  gU R                  5       n[        R                  XR                  5       /5      nU H  nUR                  5       U;   d  M    g   UR                  5       U;   a  gg)zCheck if text mentions a team.FT)lowerTEAM_SEARCH_NAMESr   )r   	team_name
text_lowersearch_namesr   s        r   _matches_teamr      s_    J$((__5F4GHL::<:%  J&    c                    [         R                  X"5      n[        R                  U/ 5      nU(       d  [        R	                  SU 35        / $ / nU H  n[        US   5      nU H  n	U	R                  SS5      n
U	R                  SS5      nU
 SU 3n[        X5      n[        X5      nU(       d	  U(       d  MT  U(       a	  U(       a  SO
U(       a  SOS	nUR                  U
UUS
   U	R                  SS5      US.5        M     M     [        5       n/ nU HC  nUS   R                  5       SS nUU;  d  M!  UR                  U5        UR                  U5        ME     UR                  S S9  USU $ )z
Fetch pre-game chatter for a matchup.

Returns a list of dicts with:
  - title: headline
  - summary: short snippet
  - source: feed name
  - relevance: 'home', 'away', or 'both'

Sorted by relevance (both > single team).
z#No RSS feeds configured for sport: r   r   r   r    bothhomeawayr   r   )r   r   sourcer   	relevanceN(   c                     U S   S:X  a  S$ S$ )Nr   r   r       )xs    r   <lambda>%get_pregame_chatter.<locals>.<lambda>B  s    AkNf$<qC!Cr   )key)SPORT_TO_FEEDr   	RSS_FEEDSr   r   r   r   r   setr   addsort)	home_team	away_teamsport	max_itemsfeed_categoryfeedsall_matches	feed_infor   r   r   r   combined
home_match
away_matchr   seen_titlesuniquemr   s                       r   get_pregame_chatterr
    se    "%%e3MMM-,E:5'BC	K	Ie,-DHHWb)Ehhy"-G'+H&x;J&x;JZZ'1jFR\bh	"""&'/ HHVR0!*$   * %KFj "%k!OOC MM!  KKDKE*9r   c                    U (       d  gS/nU  H  nSnUS   S:X  a  SnO0US   S:X  a  UR                  5       S   nOUR                  5       S   nUR                  SU S	US
    35        UR                  S5      (       aE  [        US   5      S:  a3  US   SS n[        US   5      S:  a  US-  nUR                  SU 35        UR                  SUS    35        M     SR	                  U5      $ )ze
Format chatter items into a WhatsApp-friendly text block.
Returns empty string if no chatter found.
r   zPRE-GAME BUZZ:r   r   H2Hr   z  [z] r   r      Nx   z...z    u       — r   
)splitr   r   lenjoin)chatter_itemsr   r   linesr   iconsnippets          r   format_chatter_for_whatsappr  G  s   
 E&D+&(??$R(D??$R(Ds4&4=/2388I3tI#7"#<9ods+G4	?#c)5 LL4y)*xX/01# & 99Ur   c           	         [         R                  X 5      n[        R                  U/ 5      nU(       d  / $ / nU HU  n[        US   5      nU H>  nUR	                  UR                  SS5      UR                  SS5      SS US   S.5        M@     MW     [        5       n/ n	U HB  nUS   R                  5       SS	 n
X;  d  M   UR                  U
5        U	R	                  U5        MD     U	SU $ )
zZ
Get general sport headlines (not filtered by team).
Useful for the daily slate overview.
r   r   r   r   N   r   )r   r   r   r   )r   r   r   r   r   r   r   r   )r   r   r   r  	all_itemsr  r   r   seenr  r   s              r   get_general_sport_headlinesr  g  s    
 "%%e3MMM-,E	I	Ie,-D'2.88Ir24C8#F+    5DF7m!!#CR(?HHSMMM$	  *9r   )   )r      )__doc__loggingr   r   xml.etree.ElementTreeetreeElementTreer   r   r   	getLoggerr   r   r   r   r   r   r   r   r
  r  r  r   r   r   <module>r&     sO	  &   	 " " (			,	- $LM&EF )TU%MN	 $LM#?@
 #NO(YZ&EF&/TU(1[\$OP #NO$OP(YZ&EF	'	8	5	5 
8 h	 "8	
 h
 "8 h "8 X 
5 ( ( 
8 ( h ( $o;o >o 5	o
 h)o o =o *-o x+o fj)o )[1o K5o Y/o =o L*5o  (!o" ;-#o$ v{+%o& :'o( Wh')o* -+o, >-o. <3/o0 +y11o2 x+3o4 x+5o6 7o8 gy)9o: *-;o< ':.=o> -w7?o@ nj9AoD 	9%EoF +GoH 
$56IoJ GKoL 	{MoN +w/OoP QoR M7+SoV 8]3WoX gy)YoZ Hn5[o\ y(+]o^ ?_o` ;/aob gy)cod )[1eoh 2ioj 9kol V$mon xjoop xqor gYsot uov <.wox E#89yoz K.{o| V)*}o~ xjo@ gYAoB 	{CoD gYEoF AGoH gYIoJ M?KoL +w'MoN 
$56OoP oz2QoR )84SoT <.UoV 	{WoX h0YoZ *e,[o\ 9l+]o^ '9:_ob Acod <'eof K)>?goh M?ioj V%&kol +x(mon ;7oop "45qor '(sot %78uov $67wox ov.yoz ^${o| ^$}o~ *J7o@ +AoB ou-CoD ^$EoF x!12GoH +W5IoJ '/KoL "34MoN 7$89OoP CQoR ^$SoT +UoV JWoX +,BC/#$]o d>*$ 6r@r   