diff --git a/assets/sports/all_team_abbreviations.txt b/assets/sports/all_team_abbreviations.txt new file mode 100644 index 00000000..349c4fdc --- /dev/null +++ b/assets/sports/all_team_abbreviations.txt @@ -0,0 +1,1148 @@ +NCAAF + AAMU => Alabama A&M Bulldogs + ACU => Abilene Christian Wildcats + ADA => Adams State Grizzlies + ADR => Adrian Bulldogs + AFA => Air Force Falcons + AIC => American International Yellow Jackets + AKR => Akron Zips + ALA => Alabama Crimson Tide + ALB => Albright Lions + ALBS => Albany State (GA) Golden Rams + ALCN => Alcorn State Braves + ALD => Alderson Broaddus Battlers + ALF => Alfred Saxons + ALL => Allegheny Gators + ALST => Alabama State Hornets + AMH => Amherst College Mammoths + AND => Anderson (IN) Ravens + ANG => Angelo State Rams + ANN => Anna Maria College Amcats + APP => Appalachian State Mountaineers + APSU => Austin Peay Governors + ARIZ => Arizona Wildcats + ARK => Arkansas-Monticello Boll Weevils + ARMY => Army Black Knights + ARST => Arkansas State Red Wolves + ASH => Ashland Eagles + ASP => Assumption Greyhounds + ASU => Arizona State Sun Devils + AUB => Auburn Tigers + AUG => St. Augustine's Falcons + AUR => Aurora Spartans + AUS => Austin College 'Roos + AVE => Averett Cougars + AVI => Avila College Eagles + AZU => Azusa Pacific Cougars + BAK => Baker University Wildcats + BAL => Baldwin Wallace Yellow Jackets + BALL => Ball State Cardinals + BAT => Bates College Bobcats + BAY => Baylor Bears + BC => Boston College Eagles + BEC => Becker College Hawks + BEL => Beloit College Buccaneers + BEN => Benedictine University (IL) Eagles + BENT => Bentley Falcons + BET => Bethel (TN) Wildcats + BGSU => Bowling Green Falcons + BHS => Black Hills State Yellow Jackets + BIR => Birmingham-Southern Panthers + BKN => Bacone College Warriors + BLA => Blackburn Beavers + BLOM => Bloomsburg Huskies + BLU => Bluffton Beavers + BOW => Bowdoin Polar Bears + BRI => British Columbia Thunderbirds + BRWN => Brown Bears + BST => Bemidji State Beavers + BSU => Bowie State Bulldogs + BUCK => Bucknell Bison + BUE => Buena Vista Beavers + BUF => Buffalo State Bengals + BUFF => Buffalo Bulls + BUT => Butler Bulldogs + BYU => BYU Cougars + CAL => California Lutheran Kingsmen + CAM => Campbell Fighting Camels + CAP => Capital University Crusaders + CAR => Carthage College Red Men + CARK => Central Arkansas Bears + CAS => Castleton Spartans + CAT => Catholic University Cardinals + CCSU => Central Connecticut Blue Devils + CCU => Coastal Carolina Chanticleers + CEN => Centre College Colonels + CHA => Chapman University Panthers + CHI => Chicago Maroons + CHSO => Charleston Southern Buccaneers + CIN => Cincinnati Bearcats + CLA => Clarion Golden Eagles + CLEM => Clemson Tigers + CLMB => Columbia Lions + CLT => Charlotte 49ers + CMU => Central Michigan Chippewas + COE => Coe College Kohawks + COL => Colorado School of Mines Orediggers + COLC => Colorado College Tigers + COLG => Colgate Raiders + COLO => Colorado Buffaloes + CON => Concordia-Minnesota Cobbers + COR => Cornell College (IA) Rams + CP => Cal Poly Mustangs + CRO => Crown Storm + CSU => Colorado State Rams + CUL => Culver-Stockton Wildcats + CUM => Cumberland College Indians + CUR => Curry College Colonels + DAK => Dakota Wesleyan Tigers + DART => Dartmouth Big Green + DAV => Davidson Wildcats + DAY => Dayton Flyers + DEF => Defiance Yellow Jackets + DEL => Delta State Statesmen + DEN => Denison Big Red + DEP => DePauw Tigers + DIC => Dickinson State Blue Hawks + DRKE => Drake Bulldogs + DSU => Delaware State Hornets + DUB => Dubuque Spartans + DUKE => Duke Blue Devils + DUQ => Duquesne Dukes + EAS => Eastern New Mexico Greyhounds + ECU => East Carolina Pirates + EDI => Edinboro Fighting Scots + EIU => Eastern Illinois Panthers + EKU => Eastern Kentucky Colonels + ELI => Elizabeth City State Vikings + ELM => Elmhurst Blue Jays + ELON => Elon Phoenix + EMO => Emory & Henry Wasps + EMP => Emporia State Hornets + EMU => Eastern Michigan Eagles + END => Endicott College Gulls + EOR => Eastern Oregon Mountaineers + ETSU => East Tennessee State Buccaneers + EUR => Eureka College Red Devils + EWU => Eastern Washington Eagles + FAU => Florida Atlantic Owls + FAY => Fayetteville State Broncos + FDU => FDU-Florham Devils + FER => Ferrum Panthers + FIN => Findlay Oilers + FIT => Fitchburg State Falcons + FIU => Florida International Panthers + FLA => Florida Gators + FOR => Fort Valley State Wildcats + FRA => Franklin Grizzlies + FRES => Fresno State Bulldogs + FRO => Frostburg State Bobcats + FRST => Ferris State Bulldogs + FSU => Florida State Seminoles + FTLW => Fort Lewis Skyhawks + FUR => Furman Paladins + GAL => Gallaudet Bison + GAN => Gannon Golden Knights + GASO => Georgia Southern Eagles + GAST => Georgia State Panthers + GEN => Geneva College Golden Tornadoes + GEO => George Fox University Bruins + GET => Gettysburg Bullets + GLE => Glenville State Pioneers + GMU => George Mason Patriots + GRA => Grand Valley State Lakers + GRE => Greenville Panthers + GRI => Grinnell Pioneers + GRO => Grove City College Wolverines + GT => Georgia Tech Yellow Jackets + GUI => Guilford Quakers + GWEB => Gardner-Webb Bulldogs + HAM => Hampden-Sydney Tigers + HAMP => Hampton Pirates + HAN => Hanover Panthers + HAR => Hartwick Hawks + HARV => Harvard Crimson + HAS => Haskell Indian Nations Jayhawks + HAW => Hawai'i Rainbow Warriors + HBU => Houston Baptist Huskies + HC => Holy Cross Crusaders + HEI => Heidelberg Student Princes + HEN => Hendrix College Warriors + HIL => Hillsdale Chargers + HIR => Hiram College Terriers + HOB => Hobart Statesmen + HOU => Houston Cougars + HOW => Howard Bison + HUS => Husson Eagles + IDHO => Idaho Vandals + IDST => Idaho State Bengals + ILL => Illinois Fighting Illini + ILST => Illinois State Redbirds + ILW => Illinois Wesleyan Titans + IND => Indianapolis + INST => Indiana State Sycamores + IOW => Iowa Wesleyan Tigers + IOWA => Iowa Hawkeyes + ISU => Iowa State Cyclones + ITH => Ithaca Bombers + IU => Indiana Hoosiers + JKST => Jackson State Tigers + JMU => James Madison Dukes + JOH => Johnson C Smith Golden Bulls + JUN => Juniata Eagles + JVST => Jacksonville State Gamecocks + KAL => Kalamazoo Hornets + KAN => Kansas Wesleyan University Coyotes + KEN => Kenyon Lords + KENN => Kennesaw State Owls + KENT => Kent State Golden Flashes + KIN => King's College (PA) Monarchs + KNO => Knox College Prairie Fire + KSU => Kansas State Wildcats + KU => Kansas Jayhawks + KUT => Kutztown Golden Bears + KYST => Kentucky State Thorobreds + KYW => Kentucky Wesleyan Panthers + LA => La Verne Leopards + LAC => Lane Dragons + LAF => Lafayette Leopards + LAG => LaGrange College Panthers + LAK => Lake Forest Foresters + LAM => Lambuth Eagles + LAN => Langston Lions + LAW => Lawrence Vikings + LEB => Lebanon Valley Flying Dutchmen + LEH => Lehigh Mountain Hawks + LEN => Lenoir-Rhyne Bears + LEW => Lewis & Clark Pioneers + LIB => Liberty Flames + LIM => Limestone Saints + LIN => Linfield Wildcats + LOC => Lock Haven Bald Eagles + LOR => Loras College Duhawks + LOU => Louisville Cardinals + LSU => LSU Tigers + LT => Louisiana Tech Bulldogs + LUT => Luther Norse + LYC => Lycoming Warriors + M-OH => Miami (OH) RedHawks + MAC => Macalester Scots + MAI => Maine Maritime Mariners + MAN => Mansfield Mountaineers + MAR => Maryville College Fighting Scots + MAS => Mass Maritime Buccaneers + MASS => UMass Minutemen + MAY => Mayville State Comets + MCM => McMurry War Hawks + MCN => McNeese Cowboys + MD => Maryland Terrapins + MEM => Memphis Tigers + MEN => Menlo College Oaks + MER => Merchant Marine Mariners + MERC => Mercyhurst Lakers + MES => Colorado Mesa Mavericks + MET => Methodist Monarchs + MH => Mars Hill Mountain Lions + MIAMI => Miami Hurricanes + MICH => Michigan Wolverines + MID => Midwestern State Mustangs + MIL => Millsaps Majors + MIN => Minot State Beavers + MINN => Minnesota Golden Gophers + MIS => Missouri Western Griffons + MISS => Ole Miss Rebels + MIZ => Missouri Tigers + MNST => Minnesota State Mavericks + MONM => Monmouth Hawks + MONT => Montana Grizzlies + MOR => Morningside Chiefs + MORE => Morehead State Eagles + MORG => Morgan State Bears + MOU => Mount Union Raiders + MRSH => Marshall Thundering Herd + MRST => Marist Red Foxes + MSST => Mississippi State Bulldogs + MSU => Michigan State Spartans + MTST => Montana State Bobcats + MTSU => Middle Tennessee Blue Raiders + MTU => Michigan Tech Huskies + MUH => Muhlenberg Mules + MUR => Murray State Racers + MUS => Muskingum Fighting Muskies + MVSU => Mississippi Valley State Delta Devils + NAU => Northern Arizona Lumberjacks + NAVY => Navy Midshipmen + NBY => Newberry Wolves + NCAT => North Carolina A&T Aggies + NCCU => North Carolina Central Eagles + NCST => NC State Wolfpack + ND => Notre Dame Fighting Irish + NDOH => Notre Dame College Falcons + NDSU => North Dakota State Bison + NEB => Nebraska-Kearney Lopers + NEV => Nevada Wolf Pack + NH => New Haven Chargers + NICH => Nicholls Colonels + NIU => Northern Illinois Huskies + NMH => New Mexico Highlands Cowboys + NMI => Northern Michigan Wildcats + NMSU => New Mexico State Aggies + NOR => Univ. of Northwestern-St. Paul Eagles + NORF => Norfolk State Spartans + NW => Northwestern Wildcats + OBE => Oberlin Yeomen + ODU => Old Dominion Monarchs + OHI => Ohio Northern Polar Bears + OHIO => Ohio Bobcats + OKL => Oklahoma Baptist Bison + OKST => Oklahoma State Cowboys + OLI => Olivet College Comets + OMA => Omaha Mavericks + ORST => Oregon State Beavers + OSU => Ohio State Buckeyes + OTT => Otterbein Cardinals + OU => Oklahoma Sooners + PAC => Pacific (OR) Boxers + PENN => Pennsylvania Quakers + PIKE => Pikeville Bears + PITT => Pittsburgh Panthers + PRE => Presentation College Saints + PRI => Principia College Panthers + PRIN => Princeton Tigers + PST => Pittsburg State Gorillas + PSU => Penn State Nittany Lions + RED => Redlands Bulldogs + RICE => Rice Owls + RICH => Richmond Spiders + RIT => Rochester Yellow Jackets + ROB => Robert Morris (IL) Eagles + ROS => Rose-Hulman Engineers + RUTG => Rutgers Scarlet Knights + SAC => Sacramento State Hornets + SAG => Saginaw Valley Cardinals + SDAK => South Dakota Coyotes + SDSU => San Diego State Aztecs + SET => Seton Hill Griffins + SIU => Southern Illinois Salukis + SJSU => San José State Spartans + SLI => Slippery Rock The Rock + SOU => Southwestern College Moundbuilders + SPR => Springfield College Pride + ST => St. Scholastica Saints + STAN => Stanford Cardinal + STE => Stevenson University Mustangs + STET => Stetson Hatters + STO => Stonehill College Skyhawks + SUS => Susquehanna University River Hawks + SUU => Southern Utah Thunderbirds + SYR => Syracuse Orange + TA&M => Texas A&M Aggies + TAY => Taylor Trojans + TEM => Temple Owls + TEX => Texas Longhorns + TIF => Tiffin University Dragons + TLSA => Tulsa Golden Hurricane + TRI => Trinity University (TX) Tigers + TUF => Tufts University Jumbos + TXST => Texas State Bobcats + UAB => UAB Blazers + UAPB => Arkansas-Pine Bluff Golden Lions + UCD => UC Davis Aggies + UCF => UCF Knights + UCLA => UCLA Bruins + UCONN => UConn Huskies + UGA => Georgia Bulldogs + UK => Kentucky Wildcats + UL => Louisiana Ragin' Cajuns + ULM => UL Monroe Warhawks + UMD => Minnesota-Duluth Bulldogs + UMDA => UMASS Dartmouth Corsairs + UML => UMass Lowell River Hawks + UNA => North Alabama Lions + UNC => North Carolina Tar Heels + UNCO => Northern Colorado Bears + UND => North Dakota Fighting Hawks + UNH => New Hampshire Wildcats + UNI => University of Mary Marauders + UNLV => UNLV Rebels + UNM => New Mexico Lobos + UNNY => Union Dutchmen + UNT => North Texas Mean Green + UPP => Upper Iowa Peacocks + URI => Rhode Island Rams + USA => South Alabama Jaguars + USC => USC Trojans + USD => San Diego Toreros + USF => South Florida Bulls + USU => Utah State Aggies + UTAH => Utah Utes + UTC => Chattanooga Mocs + UTI => Utica College Pioneers + UVA => Virginia Cavaliers + VAL => Valley City State Vikings + VAN => Vanderbilt Commodores + VILL => Villanova Wildcats + VIR => Virginia State Trojans + VT => Virginia Tech Hokies + WAB => Wabash College Little Giants + WAKE => Wake Forest Demon Deacons + WAS => Washington-Missouri Bears + WASH => Washington Huskies + WAY => Wayne State (MI) Warriors + WES => Westminster College (MO) Blue Jays + WHE => Wheaton College Illinois Thunder + WIL => Wilkes University Colonels + WIN => Wingate Bulldogs + WIS => Wisconsin-Platteville Pioneers + WISC => Wisconsin Badgers + WKU => Western Kentucky Hilltoppers + WOR => Worcester State College Lancers + WSU => Washington State Cougars + WVU => West Virginia Mountaineers + YALE => Yale Bulldogs + +NBA + ATL => Atlanta Hawks + BKN => Brooklyn Nets + BOS => Boston Celtics + CHA => Charlotte Hornets + CHI => Chicago Bulls + CLE => Cleveland Cavaliers + DAL => Dallas Mavericks + DEN => Denver Nuggets + DET => Detroit Pistons + GS => Golden State Warriors + HOU => Houston Rockets + IND => Indiana Pacers + LAC => LA Clippers + LAL => Los Angeles Lakers + MEM => Memphis Grizzlies + MIA => Miami Heat + MIL => Milwaukee Bucks + MIN => Minnesota Timberwolves + NO => New Orleans Pelicans + NY => New York Knicks + OKC => Oklahoma City Thunder + ORL => Orlando Magic + PHI => Philadelphia 76ers + PHX => Phoenix Suns + POR => Portland Trail Blazers + SA => San Antonio Spurs + SAC => Sacramento Kings + TOR => Toronto Raptors + UTAH => Utah Jazz + WSH => Washington Wizards + +NFL + ARI => Arizona Cardinals + ATL => Atlanta Falcons + BAL => Baltimore Ravens + BUF => Buffalo Bills + CAR => Carolina Panthers + CHI => Chicago Bears + CIN => Cincinnati Bengals + CLE => Cleveland Browns + DAL => Dallas Cowboys + DEN => Denver Broncos + DET => Detroit Lions + GB => Green Bay Packers + HOU => Houston Texans + IND => Indianapolis Colts + JAX => Jacksonville Jaguars + KC => Kansas City Chiefs + LAC => Los Angeles Chargers + LAR => Los Angeles Rams + LV => Las Vegas Raiders + MIA => Miami Dolphins + MIN => Minnesota Vikings + NE => New England Patriots + NO => New Orleans Saints + NYG => New York Giants + NYJ => New York Jets + PHI => Philadelphia Eagles + PIT => Pittsburgh Steelers + SEA => Seattle Seahawks + SF => San Francisco 49ers + TB => Tampa Bay Buccaneers + TEN => Tennessee Titans + WSH => Washington + +NCAA BASKETBALL + AAMU => Alabama A&M Bulldogs + ACU => Abilene Christian Wildcats + AFA => Air Force Falcons + AKR => Akron Zips + ALA => Alabama Crimson Tide + ALB => Albany Great Danes + ALCN => Alcorn State Braves + ALST => Alabama State Hornets + AMCC => Texas A&M-CC Islanders + AMER => American Eagles + APP => Appalachian State Mountaineers + APSU => Austin Peay Governors + ARIZ => Arizona Wildcats + ARK => Arkansas Razorbacks + ARMY => Army Black Knights + ARST => Arkansas State Red Wolves + ASU => Arizona State Sun Devils + AUB => Auburn Tigers + BALL => Ball State Cardinals + BAY => Baylor Bears + BC => Boston College Eagles + BEL => Belmont Bruins + BELL => Bellarmine Knights + BGSU => Bowling Green Falcons + BING => Binghamton Bearcats + BRAD => Bradley Braves + BRWN => Brown Bears + BRY => Bryant Bulldogs + BSU => Boise State Broncos + BU => Boston University Terriers + BUCK => Bucknell Bison + BUFF => Buffalo Bulls + BUT => Butler Bulldogs + BYU => BYU Cougars + CAL => California Golden Bears + CAM => Campbell Fighting Camels + CAN => Canisius Golden Griffins + CCAR => Coastal Carolina Chanticleers + CCSU => Central Connecticut Blue Devils + CHAR => Charlotte 49ers + CHIC => Chicago State Cougars + CHSO => Charleston Southern Buccaneers + CIN => Cincinnati Bearcats + CLEM => Clemson Tigers + CLEV => Cleveland State Vikings + CLMB => Columbia Lions + CMU => Central Michigan Chippewas + COFC => Charleston Cougars + COLG => Colgate Raiders + COLO => Colorado Buffaloes + CONN => UConn Huskies + COPP => Coppin State Eagles + COR => Cornell Big Red + CP => Cal Poly Mustangs + CREI => Creighton Bluejays + CSU => Colorado State Rams + CSUB => CSU Bakersfield Roadrunners + CSUF => CSU Fullerton Titans + CSUN => CSU Northridge Matadors + DART => Dartmouth Big Green + DAV => Davidson Wildcats + DAY => Dayton Flyers + DEL => Delaware Blue Hens + DEN => Denver Pioneers + DEP => DePaul Blue Demons + DET => Detroit Mercy Titans + DREX => Drexel Dragons + DRKE => Drake Bulldogs + DSU => Delaware State Hornets + DUKE => Duke Blue Devils + DUQ => Duquesne Dukes + ECU => East Carolina Pirates + EIU => Eastern Illinois Panthers + EKU => Eastern Kentucky Colonels + ELON => Elon Phoenix + EMU => Eastern Michigan Eagles + ETSU => East Tennessee State Buccaneers + EVAN => Evansville Purple Aces + EWU => Eastern Washington Eagles + FAIR => Fairfield Stags + FAMU => Florida A&M Rattlers + FAU => Florida Atlantic Owls + FDU => Fairleigh Dickinson Knights + FGCU => Florida Gulf Coast Eagles + FIU => Florida International Panthers + FLA => Florida Gators + FOR => Fordham Rams + FRES => Fresno State Bulldogs + FSU => Florida State Seminoles + FUR => Furman Paladins + GASO => Georgia Southern Eagles + GAST => Georgia State Panthers + GB => Green Bay Phoenix + GCU => Grand Canyon Antelopes + GMU => George Mason Patriots + GONZ => Gonzaga Bulldogs + GT => Georgia Tech Yellow Jackets + GTWN => Georgetown Hoyas + GW => George Washington Colonials + GWEB => Gardner-Webb Bulldogs + HALL => Seton Hall Pirates + HAMP => Hampton Pirates + HART => Hartford Hawks + HARV => Harvard Crimson + HAW => Hawai'i Rainbow Warriors + HBU => Houston Baptist Huskies + HC => Holy Cross Crusaders + HOF => Hofstra Pride + HOU => Houston Cougars + HOW => Howard Bison + HP => High Point Panthers + IDHO => Idaho Vandals + IDST => Idaho State Bengals + ILL => Illinois Fighting Illini + ILST => Illinois State Redbirds + INST => Indiana State Sycamores + IONA => Iona Gaels + IOWA => Iowa Hawkeyes + ISU => Iowa State Cyclones + IU => Indiana Hoosiers + IUPU => IUPUI Jaguars + JAX => Jacksonville Dolphins + JKST => Jackson State Tigers + JMU => James Madison Dukes + JOES => Saint Joseph's Hawks + JVST => Jacksonville State Gamecocks + KENN => Kennesaw State Owls + KENT => Kent State Golden Flashes + KSU => Kansas State Wildcats + KU => Kansas Jayhawks + L-MD => Loyola (MD) Greyhounds + LAF => Lafayette Leopards + LAM => Lamar Cardinals + LAS => La Salle Explorers + LBSU => Long Beach State Beach + LEH => Lehigh Mountain Hawks + LIB => Liberty Flames + LIP => Lipscomb Bisons + LIU => Long Island University Sharks + LMU => Loyola Marymount Lions + LONG => Longwood Lancers + LOU => Louisville Cardinals + LSU => LSU Tigers + LT => Louisiana Tech Bulldogs + LUC => Loyola Chicago Ramblers + M-OH => Miami (OH) Redhawks + MAN => Manhattan Jaspers + MARQ => Marquette Golden Eagles + MASS => UMass Minutemen + MD => Maryland Terrapins + ME => Maine Black Bears + MEM => Memphis Tigers + MIA => Miami Hurricanes + MICH => Michigan Wolverines + MILW => Milwaukee Panthers + MINN => Minnesota Golden Gophers + MISS => Ole Miss Rebels + MIZ => Missouri Tigers + MONM => Monmouth Hawks + MONT => Montana Grizzlies + MORE => Morehead State Eagles + MORG => Morgan St Bears + MOST => Missouri State Bears + MRMK => Merrimack Warriors + MRSH => Marshall Thundering Herd + MRST => Marist Red Foxes + MSM => Mount St. Mary's Mountaineers + MSST => Mississippi State Bulldogs + MSU => Michigan State Spartans + MTST => Montana State Bobcats + MTU => Middle Tennessee Blue Raiders + MUR => Murray State Racers + NAU => Northern Arizona Lumberjacks + NAVY => Navy Midshipmen + NCAT => North Carolina A&T Aggies + NCCU => North Carolina Central Eagles + NCST => NC State Wolfpack + ND => Notre Dame Fighting Irish + NE => Northeastern Huskies + NEB => Nebraska Cornhuskers + NEV => Nevada Wolf Pack + NIAG => Niagara Purple Eagles + NIU => Northern Illinois Huskies + NJIT => NJIT Highlanders + NKU => Northern Kentucky Norse + NMSU => New Mexico State Aggies + NORF => Norfolk St Spartans + NW => Northwestern Wildcats + OAK => Oakland Golden Grizzlies + ODU => Old Dominion Monarchs + OHIO => Ohio Bobcats + OKST => Oklahoma State Cowboys + ORE => Oregon Ducks + ORST => Oregon State Beavers + ORU => Oral Roberts Golden Eagles + OSU => Ohio State Buckeyes + OU => Oklahoma Sooners + PAC => Pacific Tigers + PENN => Pennsylvania Quakers + PFW => Purdue Fort Wayne Mastodons + PITT => Pittsburgh Panthers + PRES => Presbyterian Blue Hose + PRIN => Princeton Tigers + PROV => Providence Friars + PRST => Portland State Vikings + PSU => Penn State Nittany Lions + PUR => Purdue Boilermakers + QUIN => Quinnipiac Bobcats + RAD => Radford Highlanders + RICE => Rice Owls + RICH => Richmond Spiders + RID => Rider Broncs + RMU => Robert Morris Colonials + RUTG => Rutgers Scarlet Knights + SAC => Sacramento State Hornets + SBU => St. Bonaventure Bonnies + SC => South Carolina Gamecocks + SCST => South Carolina State Bulldogs + SCUP => South Carolina Upstate Spartans + SDAK => South Dakota Coyotes + SDSU => San Diego State Aztecs + SEMO => Southeast Missouri State Redhawks + SFBK => St. Francis (BKN) Terriers + SFPA => St. Francis (PA) Red Flash + SHU => Sacred Heart Pioneers + SIE => Siena Saints + SIU => Southern Illinois Salukis + SIUE => SIU Edwardsville Cougars + SJSU => San José St Spartans + SJU => St. John's Red Storm + SLU => Saint Louis Billikens + SMU => SMU Mustangs + SPU => Saint Peter's Peacocks + STAN => Stanford Cardinal + STBK => Stony Brook Seawolves + STET => Stetson Hatters + SUU => Southern Utah Thunderbirds + SYR => Syracuse Orange + TA&M => Texas A&M Aggies + TCU => TCU Horned Frogs + TEM => Temple Owls + TENN => Tennessee Volunteers + TEX => Texas Longhorns + TLSA => Tulsa Golden Hurricane + TNST => Tennessee State Tigers + TNTC => Tennessee Tech Golden Eagles + TOL => Toledo Rockets + TOW => Towson Tigers + TTU => Texas Tech Red Raiders + TULN => Tulane Green Wave + TXST => Texas State Bobcats + UAB => UAB Blazers + UALR => Little Rock Trojans + UAPB => Arkansas-Pine Bluff Golden Lions + UCA => Central Arkansas Bears + UCD => UC Davis Aggies + UCF => UCF Knights + UCI => UC Irvine Anteaters + UCLA => UCLA Bruins + UCR => UC Riverside Highlanders + UCSB => UC Santa Barbara Gauchos + UCSD => UC San Diego Tritons + UGA => Georgia Bulldogs + UIC => UIC Flames + UK => Kentucky Wildcats + ULL => Louisiana Ragin' Cajuns + UMBC => UMBC Retrievers + UMKC => UM Kansas City Roos + UML => UMass Lowell River Hawks + UNA => North Alabama Lions + UNC => North Carolina Tar Heels + UNCA => UNC Asheville Bulldogs + UNCO => Northern Colorado Bears + UNCW => UNC Wilmington Seahawks + UND => North Dakota Fighting Hawks + UNF => North Florida Ospreys + UNH => New Hampshire Wildcats + UNI => Northern Iowa Panthers + UNLV => UNLV Rebels + UNM => New Mexico Lobos + UNT => North Texas Mean Green + URI => Rhode Island Rams + USA => South Alabama Jaguars + USC => USC Trojans + USD => San Diego Toreros + USF => South Florida Bulls + USM => Southern Miss Golden Eagles + USU => Utah State Aggies + UTA => UT Arlington Mavericks + UTAH => Utah Utes + UTC => Chattanooga Mocs + UTEP => UTEP Miners + UTM => UT Martin Skyhawks + UTRGV => UT Rio Grande Valley Vaqueros + UTSA => UTSA Roadrunners + UVA => Virginia Cavaliers + UVM => Vermont Catamounts + VALP => Valparaiso + VAN => Vanderbilt Commodores + VCU => VCU Rams + VILL => Villanova Wildcats + VT => Virginia Tech Hokies + W&M => William & Mary Tribe + WAG => Wagner Seahawks + WAKE => Wake Forest Demon Deacons + WASH => Washington Huskies + WEB => Weber State Wildcats + WICH => Wichita State Shockers + WIN => Winthrop Eagles + WISC => Wisconsin Badgers + WKU => Western Kentucky Hilltoppers + WMU => Western Michigan Broncos + WRST => Wright State Raiders + WSU => Washington State Cougars + WVU => West Virginia Mountaineers + WYO => Wyoming Cowboys + XAV => Xavier Musketeers + YALE => Yale Bulldogs + YSU => Youngstown State Penguins + +MLB + ARI => Arizona Diamondbacks + ATL => Atlanta Braves + BAL => Baltimore Orioles + BOS => Boston Red Sox + CHC => Chicago Cubs + CHW => Chicago White Sox + CIN => Cincinnati Reds + CLE => Cleveland Indians + COL => Colorado Rockies + DET => Detroit Tigers + HOU => Houston Astros + KC => Kansas City Royals + LAA => Los Angeles Angels + LAD => Los Angeles Dodgers + MIA => Miami Marlins + MIL => Milwaukee Brewers + MIN => Minnesota Twins + NYM => New York Mets + NYY => New York Yankees + OAK => Oakland Athletics + PHI => Philadelphia Phillies + PIT => Pittsburgh Pirates + SD => San Diego Padres + SEA => Seattle Mariners + SF => San Francisco Giants + STL => St. Louis Cardinals + TB => Tampa Bay Rays + TEX => Texas Rangers + TOR => Toronto Blue Jays + WSH => Washington Nationals + +MLS + ATL => Atlanta United FC + ATX => Austin FC + CHI => Chicago Fire FC + CIN => FC Cincinnati + CLB => Columbus Crew + COL => Colorado Rapids + DAL => FC Dallas + DC => DC United + HOU => Houston Dynamo FC + LA => LA Galaxy + LAFC => LAFC + MIA => Inter Miami CF + MIN => Minnesota United FC + MTL => CF Montréal + NE => New England Revolution + NSH => Nashville SC + NY => New York Red Bulls + NYC => New York City FC + ORL => Orlando City SC + PHI => Philadelphia Union + POR => Portland Timbers + RSL => Real Salt Lake + SEA => Seattle Sounders FC + SJ => San Jose Earthquakes + SKC => Sporting Kansas City + TOR => Toronto FC + VAN => Vancouver Whitecaps + +NHL + ANA => Anaheim Ducks + ARI => Arizona Coyotes + BOS => Boston Bruins + BUF => Buffalo Sabres + CAR => Carolina Hurricanes + CBJ => Columbus Blue Jackets + CGY => Calgary Flames + CHI => Chicago Blackhawks + COL => Colorado Avalanche + DAL => Dallas Stars + DET => Detroit Red Wings + EDM => Edmonton Oilers + FLA => Florida Panthers + LA => Los Angeles Kings + MIN => Minnesota Wild + MTL => Montreal Canadiens + NJ => New Jersey Devils + NSH => Nashville Predators + NYI => New York Islanders + NYR => New York Rangers + OTT => Ottawa Senators + PHI => Philadelphia Flyers + PIT => Pittsburgh Penguins + SEA => Seattle Kraken + SJ => San Jose Sharks + STL => St. Louis Blues + TB => Tampa Bay Lightning + TOR => Toronto Maple Leafs + VAN => Vancouver Canucks + VGS => Vegas Golden Knights + WPG => Winnipeg Jets + WSH => Washington Capitals + +NCAAF Conferences/Divisions + Conferences currently unsupported + +NBA Conferences/Divisions + East_SE + ATL => Atlanta Hawks + CHA => Charlotte Hornets + MIA => Miami Heat + ORL => Orlando Magic + WSH => Washington Wizards + East_AT + BKN => Brooklyn Nets + BOS => Boston Celtics + NY => New York Knicks + PHI => Philadelphia 76ers + TOR => Toronto Raptors + East_CE + CHI => Chicago Bulls + CLE => Cleveland Cavaliers + DET => Detroit Pistons + IND => Indiana Pacers + MIL => Milwaukee Bucks + West_SW + DAL => Dallas Mavericks + HOU => Houston Rockets + MEM => Memphis Grizzlies + NO => New Orleans Pelicans + SA => San Antonio Spurs + West_NW + DEN => Denver Nuggets + MIN => Minnesota Timberwolves + OKC => Oklahoma City Thunder + POR => Portland Trail Blazers + UTAH => Utah Jazz + West_PA + GS => Golden State Warriors + LAC => LA Clippers + LAL => Los Angeles Lakers + PHX => Phoenix Suns + SAC => Sacramento Kings +NFL Conferences/Divisions + AFC_SOUTH + HOU => Houston Texans + IND => Indianapolis Colts + JAX => Jacksonville Jaguars + TEN => Tennessee Titans + NFC_WEST + ARI => Arizona Cardinals + LAR => Los Angeles Rams + SEA => Seattle Seahawks + SF => San Francisco 49ers + NFC_SOUTH + ATL => Atlanta Falcons + CAR => Carolina Panthers + NO => New Orleans Saints + TB => Tampa Bay Buccaneers + AFC_NORTH + BAL => Baltimore Ravens + CIN => Cincinnati Bengals + CLE => Cleveland Browns + PIT => Pittsburgh Steelers + AFC_EAST + BUF => Buffalo Bills + MIA => Miami Dolphins + NE => New England Patriots + NYJ => New York Jets + NFC_NORTH + CHI => Chicago Bears + DET => Detroit Lions + GB => Green Bay Packers + MIN => Minnesota Vikings + NFC_EAST + DAL => Dallas Cowboys + NYG => New York Giants + PHI => Philadelphia Eagles + WSH => Washington + AFC_WEST + DEN => Denver Broncos + KC => Kansas City Chiefs + LAC => Los Angeles Chargers + LV => Las Vegas Raiders +NCAA BASKETBALL Conferences/Divisions + NCAA_pat + NAVY => Navy Midshipmen + NCAA_aac + SMU => SMU Mustangs + TULN => Tulane Green Wave + WICH => Wichita State Shockers + NCAA_atl10 + JOES => Saint Joseph's Hawks + VCU => VCU Rams + NCAA_meac + MORG => Morgan St Bears + NCAT => North Carolina A&T Aggies + NCCU => North Carolina Central Eagles + NORF => Norfolk St Spartans + SCST => South Carolina State Bulldogs + NCAA_mvc + MOST => Missouri State Bears + UNI => Northern Iowa Panthers + VALP => Valparaiso + NCAA_midam + NIU => Northern Illinois Huskies + TOL => Toledo Rockets + WMU => Western Michigan Broncos + NCAA_big12 + TCU => TCU Horned Frogs + TTU => Texas Tech Red Raiders + NCAA_neast + BRY => Bryant Bulldogs + LIU => Long Island University Sharks + MRMK => Merrimack Warriors + SFBK => St. Francis (BKN) Terriers + SFPA => St. Francis (PA) Red Flash + SHU => Sacred Heart Pioneers + WAG => Wagner Seahawks + NCAA_bige + HALL => Seton Hall Pirates + PROV => Providence Friars + SJU => St. John's Red Storm + XAV => Xavier Musketeers + NCAA_bsky + NAU => Northern Arizona Lumberjacks + PRST => Portland State Vikings + UNCO => Northern Colorado Bears + WEB => Weber State Wildcats + NCAA_mwest + NEV => Nevada Wolf Pack + UNLV => UNLV Rebels + WYO => Wyoming Cowboys + NCAA_aeast + NJIT => NJIT Highlanders + STBK => Stony Brook Seawolves + UMBC => UMBC Retrievers + NCAA_pac12 + ORE => Oregon Ducks + NCAA_bsou + PRES => Presbyterian Blue Hose + RAD => Radford Highlanders + SCUP => South Carolina Upstate Spartans + UNCA => UNC Asheville Bulldogs + WIN => Winthrop Eagles + NCAA_big10 + PUR => Purdue Boilermakers + NCAA_maac + MAN => Manhattan Jaspers + MONM => Monmouth Hawks + MRST => Marist Red Foxes + QUIN => Quinnipiac Bobcats + RID => Rider Broncs + SIE => Siena Saints + SPU => Saint Peter's Peacocks + NCAA_acc + MIA => Miami Hurricanes + NCAA_a-sun + UNA => North Alabama Lions + UNF => North Florida Ospreys + NCAA_hor + GB => Green Bay Phoenix + OAK => Oakland Golden Grizzlies + PFW => Purdue Fort Wayne Mastodons + RMU => Robert Morris Colonials + WRST => Wright State Raiders + YSU => Youngstown State Penguins + NCAA_ovc + MORE => Morehead State Eagles + SEMO => Southeast Missouri State Redhawks + SIUE => SIU Edwardsville Cougars + TNST => Tennessee State Tigers + TNTC => Tennessee Tech Golden Eagles + UTM => UT Martin Skyhawks + NCAA_sec + SC => South Carolina Gamecocks + TENN => Tennessee Volunteers + NCAA_col + W&M => William & Mary Tribe + NCAA_usa + CHAR => Charlotte 49ers + MTU => Middle Tennessee Blue Raiders + USM => Southern Miss Golden Eagles + UTEP => UTEP Miners + UTSA => UTSA Roadrunners + NCAA_bigw + CSUB => CSU Bakersfield Roadrunners + CSUN => CSU Northridge Matadors + UCSB => UC Santa Barbara Gauchos +MLB Conferences/Divisions + NL_NLW + ARI => Arizona Diamondbacks + COL => Colorado Rockies + LAD => Los Angeles Dodgers + SD => San Diego Padres + SF => San Francisco Giants + NL_NLE + ATL => Atlanta Braves + MIA => Miami Marlins + NYM => New York Mets + PHI => Philadelphia Phillies + WSH => Washington Nationals + AL_ALE + BAL => Baltimore Orioles + BOS => Boston Red Sox + NYY => New York Yankees + TB => Tampa Bay Rays + TOR => Toronto Blue Jays + NL_NLC + CHC => Chicago Cubs + CIN => Cincinnati Reds + MIL => Milwaukee Brewers + PIT => Pittsburgh Pirates + STL => St. Louis Cardinals + AL_ALC + CHW => Chicago White Sox + CLE => Cleveland Indians + DET => Detroit Tigers + KC => Kansas City Royals + MIN => Minnesota Twins + AL_ALW + HOU => Houston Astros + LAA => Los Angeles Angels + OAK => Oakland Athletics + SEA => Seattle Mariners + TEX => Texas Rangers +MLS Conferences/Divisions + Conferences currently unsupported + +NHL Conferences/Divisions + West_PAC + ANA => Anaheim Ducks + CGY => Calgary Flames + EDM => Edmonton Oilers + LA => Los Angeles Kings + SEA => Seattle Kraken + SJ => San Jose Sharks + VAN => Vancouver Canucks + VGS => Vegas Golden Knights + West_CEN + ARI => Arizona Coyotes + CHI => Chicago Blackhawks + COL => Colorado Avalanche + DAL => Dallas Stars + MIN => Minnesota Wild + NSH => Nashville Predators + STL => St. Louis Blues + WPG => Winnipeg Jets + East_ATL + BOS => Boston Bruins + BUF => Buffalo Sabres + DET => Detroit Red Wings + FLA => Florida Panthers + MTL => Montreal Canadiens + OTT => Ottawa Senators + TB => Tampa Bay Lightning + TOR => Toronto Maple Leafs + East_MET + CAR => Carolina Hurricanes + CBJ => Columbus Blue Jackets + NJ => New Jersey Devils + NYI => New York Islanders + NYR => New York Rangers + PHI => Philadelphia Flyers + PIT => Pittsburgh Penguins + WSH => Washington Capitals diff --git a/assets/sports/nhl_logos/ANA.png b/assets/sports/nhl_logos/ANA.png new file mode 100644 index 00000000..0681dc4d Binary files /dev/null and b/assets/sports/nhl_logos/ANA.png differ diff --git a/assets/sports/nhl_logos/BOS.png b/assets/sports/nhl_logos/BOS.png new file mode 100644 index 00000000..88b8828b Binary files /dev/null and b/assets/sports/nhl_logos/BOS.png differ diff --git a/assets/sports/nhl_logos/BUF.png b/assets/sports/nhl_logos/BUF.png new file mode 100644 index 00000000..7993267b Binary files /dev/null and b/assets/sports/nhl_logos/BUF.png differ diff --git a/assets/sports/nhl_logos/CAR.png b/assets/sports/nhl_logos/CAR.png new file mode 100644 index 00000000..206132ab Binary files /dev/null and b/assets/sports/nhl_logos/CAR.png differ diff --git a/assets/sports/nhl_logos/CBJ.png b/assets/sports/nhl_logos/CBJ.png new file mode 100644 index 00000000..9394989e Binary files /dev/null and b/assets/sports/nhl_logos/CBJ.png differ diff --git a/assets/sports/nhl_logos/CGY.png b/assets/sports/nhl_logos/CGY.png new file mode 100644 index 00000000..8b1f2d22 Binary files /dev/null and b/assets/sports/nhl_logos/CGY.png differ diff --git a/assets/sports/nhl_logos/CHI.png b/assets/sports/nhl_logos/CHI.png new file mode 100644 index 00000000..a197f567 Binary files /dev/null and b/assets/sports/nhl_logos/CHI.png differ diff --git a/assets/sports/nhl_logos/COL.png b/assets/sports/nhl_logos/COL.png new file mode 100644 index 00000000..eabf5d42 Binary files /dev/null and b/assets/sports/nhl_logos/COL.png differ diff --git a/assets/sports/nhl_logos/DAL.png b/assets/sports/nhl_logos/DAL.png new file mode 100644 index 00000000..556f5ec9 Binary files /dev/null and b/assets/sports/nhl_logos/DAL.png differ diff --git a/assets/sports/nhl_logos/DET.png b/assets/sports/nhl_logos/DET.png new file mode 100644 index 00000000..3a33fa76 Binary files /dev/null and b/assets/sports/nhl_logos/DET.png differ diff --git a/assets/sports/nhl_logos/EDM.png b/assets/sports/nhl_logos/EDM.png new file mode 100644 index 00000000..e8ba5e90 Binary files /dev/null and b/assets/sports/nhl_logos/EDM.png differ diff --git a/assets/sports/nhl_logos/FLA.png b/assets/sports/nhl_logos/FLA.png new file mode 100644 index 00000000..2c125e3e Binary files /dev/null and b/assets/sports/nhl_logos/FLA.png differ diff --git a/assets/sports/nhl_logos/LA.png b/assets/sports/nhl_logos/LA.png new file mode 100644 index 00000000..b3640b47 Binary files /dev/null and b/assets/sports/nhl_logos/LA.png differ diff --git a/assets/sports/nhl_logos/MIN.png b/assets/sports/nhl_logos/MIN.png new file mode 100644 index 00000000..f7ebe830 Binary files /dev/null and b/assets/sports/nhl_logos/MIN.png differ diff --git a/assets/sports/nhl_logos/MTL.png b/assets/sports/nhl_logos/MTL.png new file mode 100644 index 00000000..9d794fd0 Binary files /dev/null and b/assets/sports/nhl_logos/MTL.png differ diff --git a/assets/sports/nhl_logos/NHL.png b/assets/sports/nhl_logos/NHL.png new file mode 100644 index 00000000..eaebd594 Binary files /dev/null and b/assets/sports/nhl_logos/NHL.png differ diff --git a/assets/sports/nhl_logos/NJ.png b/assets/sports/nhl_logos/NJ.png new file mode 100644 index 00000000..4f743ba7 Binary files /dev/null and b/assets/sports/nhl_logos/NJ.png differ diff --git a/assets/sports/nhl_logos/NSH.png b/assets/sports/nhl_logos/NSH.png new file mode 100644 index 00000000..41bca66a Binary files /dev/null and b/assets/sports/nhl_logos/NSH.png differ diff --git a/assets/sports/nhl_logos/NYI.png b/assets/sports/nhl_logos/NYI.png new file mode 100644 index 00000000..991d173a Binary files /dev/null and b/assets/sports/nhl_logos/NYI.png differ diff --git a/assets/sports/nhl_logos/NYR.png b/assets/sports/nhl_logos/NYR.png new file mode 100644 index 00000000..7855f4c2 Binary files /dev/null and b/assets/sports/nhl_logos/NYR.png differ diff --git a/assets/sports/nhl_logos/OTT.png b/assets/sports/nhl_logos/OTT.png new file mode 100644 index 00000000..8352c1c8 Binary files /dev/null and b/assets/sports/nhl_logos/OTT.png differ diff --git a/assets/sports/nhl_logos/PHI.png b/assets/sports/nhl_logos/PHI.png new file mode 100644 index 00000000..b2a34476 Binary files /dev/null and b/assets/sports/nhl_logos/PHI.png differ diff --git a/assets/sports/nhl_logos/PIT.png b/assets/sports/nhl_logos/PIT.png new file mode 100644 index 00000000..e26aa858 Binary files /dev/null and b/assets/sports/nhl_logos/PIT.png differ diff --git a/assets/sports/nhl_logos/SEA.png b/assets/sports/nhl_logos/SEA.png new file mode 100644 index 00000000..166103c9 Binary files /dev/null and b/assets/sports/nhl_logos/SEA.png differ diff --git a/assets/sports/nhl_logos/SJ.png b/assets/sports/nhl_logos/SJ.png new file mode 100644 index 00000000..11d02de7 Binary files /dev/null and b/assets/sports/nhl_logos/SJ.png differ diff --git a/assets/sports/nhl_logos/STL.png b/assets/sports/nhl_logos/STL.png new file mode 100644 index 00000000..5ac27884 Binary files /dev/null and b/assets/sports/nhl_logos/STL.png differ diff --git a/assets/sports/nhl_logos/TB.png b/assets/sports/nhl_logos/TB.png new file mode 100644 index 00000000..bcb3bb72 Binary files /dev/null and b/assets/sports/nhl_logos/TB.png differ diff --git a/assets/sports/nhl_logos/TOR.png b/assets/sports/nhl_logos/TOR.png new file mode 100644 index 00000000..2cf67787 Binary files /dev/null and b/assets/sports/nhl_logos/TOR.png differ diff --git a/assets/sports/nhl_logos/VAN.png b/assets/sports/nhl_logos/VAN.png new file mode 100644 index 00000000..b3d4c395 Binary files /dev/null and b/assets/sports/nhl_logos/VAN.png differ diff --git a/assets/sports/nhl_logos/VGS.png b/assets/sports/nhl_logos/VGS.png new file mode 100644 index 00000000..a89ba5b1 Binary files /dev/null and b/assets/sports/nhl_logos/VGS.png differ diff --git a/assets/sports/nhl_logos/WPG.png b/assets/sports/nhl_logos/WPG.png new file mode 100644 index 00000000..93bc4257 Binary files /dev/null and b/assets/sports/nhl_logos/WPG.png differ diff --git a/assets/sports/nhl_logos/WSH.png b/assets/sports/nhl_logos/WSH.png new file mode 100644 index 00000000..68b37254 Binary files /dev/null and b/assets/sports/nhl_logos/WSH.png differ diff --git a/config/config.json b/config/config.json index d4d18d71..928c9e0d 100644 --- a/config/config.json +++ b/config/config.json @@ -8,7 +8,7 @@ "display": { "hardware": { "rows": 32, - "cols": 64, + "cols": 128, "chain_length": 2, "parallel": 1, "brightness": 60, @@ -60,5 +60,15 @@ "scroll_delay": 0.001, "max_headlines_per_symbol": 1, "headlines_per_rotation": 2 + }, + "nhl_scoreboard": { + "enabled": true, + "favorite_teams": [ + "TBL", + "DAL" + ], + "test_mode": true, + "update_interval_seconds": 15, + "show_only_favorites": true } } \ No newline at end of file diff --git a/src/nhl_scoreboard.py b/src/nhl_scoreboard.py new file mode 100644 index 00000000..ef463d65 --- /dev/null +++ b/src/nhl_scoreboard.py @@ -0,0 +1,474 @@ +import requests +import json +import time +from pathlib import Path +from PIL import Image, ImageDraw, ImageFont +import logging +from datetime import datetime, timedelta, timezone +try: + from zoneinfo import ZoneInfo, ZoneInfoNotFoundError +except ImportError: + # Fallback for Python < 3.9 (requires pytz install: pip install pytz) + from pytz import timezone as ZoneInfo, UnknownTimeZoneError as ZoneInfoNotFoundError + +# --- Constants --- +CONFIG_FILE = Path("../config/config.json") # Correct path relative to src/ +# Default values in case config loading fails +DEFAULT_DISPLAY_WIDTH = 64 +DEFAULT_DISPLAY_HEIGHT = 32 +DEFAULT_NHL_ENABLED = False +DEFAULT_FAVORITE_TEAMS = [] +DEFAULT_NHL_TEST_MODE = False +DEFAULT_UPDATE_INTERVAL = 60 +DEFAULT_LOGO_DIR = Path("../assets/sports/nhl_logos") # Relative to src/ +DEFAULT_TEST_DATA_FILE = Path("../test_nhl_data.json") # Relative to src/ +DEFAULT_OUTPUT_IMAGE_FILE = Path("../nhl_scorebug_output.png") # Relative to src/ +DEFAULT_TIMEZONE = "UTC" +DEFAULT_NHL_SHOW_ONLY_FAVORITES = False +RECENT_GAME_HOURS = 24 # How many hours back to check for recent finals + +ESPN_NHL_SCOREBOARD_URL = "https://site.api.espn.com/apis/site/v2/sports/hockey/nhl/scoreboard" + +# --- Global Config Variables --- +# These will be populated by load_config() +DISPLAY_WIDTH = DEFAULT_DISPLAY_WIDTH +DISPLAY_HEIGHT = DEFAULT_DISPLAY_HEIGHT +NHL_ENABLED = DEFAULT_NHL_ENABLED +FAVORITE_TEAMS = DEFAULT_FAVORITE_TEAMS +TEST_MODE = DEFAULT_NHL_TEST_MODE +UPDATE_INTERVAL_SECONDS = DEFAULT_UPDATE_INTERVAL +LOGO_DIR = DEFAULT_LOGO_DIR +TEST_DATA_FILE = DEFAULT_TEST_DATA_FILE +OUTPUT_IMAGE_FILE = DEFAULT_OUTPUT_IMAGE_FILE +LOCAL_TIMEZONE = None # Will be ZoneInfo object +SHOW_ONLY_FAVORITES = DEFAULT_NHL_SHOW_ONLY_FAVORITES + +# --- Logging Setup --- +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + +# --- Configuration Loading --- +def load_config(): + """Loads configuration from config.json.""" + global DISPLAY_WIDTH, DISPLAY_HEIGHT, NHL_ENABLED, FAVORITE_TEAMS, TEST_MODE, UPDATE_INTERVAL_SECONDS, LOGO_DIR, TEST_DATA_FILE, OUTPUT_IMAGE_FILE, LOCAL_TIMEZONE, SHOW_ONLY_FAVORITES + + try: + with open(CONFIG_FILE, 'r') as f: + config_data = json.load(f) + + # Read display dimensions from the 'display' -> 'hardware' section + display_config = config_data.get("display", {}) + hardware_config = display_config.get("hardware", {}) + # Calculate total width: cols * chain_length + cols = hardware_config.get("cols", DEFAULT_DISPLAY_WIDTH / hardware_config.get("chain_length", 1) if hardware_config.get("chain_length") else DEFAULT_DISPLAY_WIDTH) # Default handling needs care + chain = hardware_config.get("chain_length", 1) + DISPLAY_WIDTH = int(cols * chain) # Ensure integer + DISPLAY_HEIGHT = hardware_config.get("rows", DEFAULT_DISPLAY_HEIGHT) + + # Load timezone + tz_string = config_data.get("timezone", DEFAULT_TIMEZONE) + try: + LOCAL_TIMEZONE = ZoneInfo(tz_string) + logging.info(f"Timezone loaded: {tz_string}") + except ZoneInfoNotFoundError: + logging.warning(f"Timezone '{tz_string}' not found. Defaulting to {DEFAULT_TIMEZONE}.") + LOCAL_TIMEZONE = ZoneInfo(DEFAULT_TIMEZONE) + + nhl_config = config_data.get("nhl_scoreboard", {}) + NHL_ENABLED = nhl_config.get("enabled", DEFAULT_NHL_ENABLED) + FAVORITE_TEAMS = nhl_config.get("favorite_teams", DEFAULT_FAVORITE_TEAMS) + TEST_MODE = nhl_config.get("test_mode", DEFAULT_NHL_TEST_MODE) + UPDATE_INTERVAL_SECONDS = nhl_config.get("update_interval_seconds", DEFAULT_UPDATE_INTERVAL) + SHOW_ONLY_FAVORITES = nhl_config.get("show_only_favorites", DEFAULT_NHL_SHOW_ONLY_FAVORITES) + + logging.info("Configuration loaded successfully.") + logging.info(f"Display: {DISPLAY_WIDTH}x{DISPLAY_HEIGHT}") + logging.info(f"NHL Enabled: {NHL_ENABLED}") + logging.info(f"Favorite Teams: {FAVORITE_TEAMS}") + logging.info(f"Test Mode: {TEST_MODE}") + logging.info(f"Update Interval: {UPDATE_INTERVAL_SECONDS}s") + logging.info(f"Show Only Favorites: {SHOW_ONLY_FAVORITES}") + + except FileNotFoundError: + logging.warning(f"Configuration file {CONFIG_FILE} not found. Using default settings.") + except json.JSONDecodeError: + logging.error(f"Error decoding configuration file {CONFIG_FILE.name}. Using default settings.") # Use .name + except Exception as e: + logging.error(f"An unexpected error occurred loading config: {e}. Using default settings.") + +# --- Display Simulation (Uses global config) --- +# (Keep existing function, it now uses global width/height) + +# --- Helper Functions --- + +def get_espn_data(): + """Fetches scoreboard data from ESPN API or loads test data.""" + try: + response = requests.get(ESPN_NHL_SCOREBOARD_URL) + response.raise_for_status() # Raise an exception for bad status codes + data = response.json() + logging.info("Successfully fetched live data from ESPN.") + # Save live data for testing if needed + if TEST_MODE: + # Ensure TEST_DATA_FILE is used + with open(TEST_DATA_FILE, 'w') as f: + json.dump(data, f, indent=2) + logging.info(f"Saved live data to {TEST_DATA_FILE.name}") # Use .name for logging + return data + except requests.exceptions.RequestException as e: + logging.error(f"Error fetching data from ESPN: {e}") + if TEST_MODE: + logging.warning("Fetching failed, attempting to load test data.") + try: + # Ensure TEST_DATA_FILE is used + with open(TEST_DATA_FILE, 'r') as f: + data = json.load(f) + logging.info(f"Successfully loaded test data from {TEST_DATA_FILE.name}") + return data + except FileNotFoundError: + logging.error(f"Test data file {TEST_DATA_FILE.name} not found.") + return None + except json.JSONDecodeError: + logging.error(f"Error decoding test data file {TEST_DATA_FILE.name}.") + return None + return None + +def find_favorite_game(data): + """Finds the first game involving a favorite team.""" + if not data or "events" not in data: + return None + + for event in data["events"]: + competitions = event.get("competitions", []) + if not competitions: + continue + competition = competitions[0] + competitors = competition.get("competitors", []) + if len(competitors) == 2: + team1_abbr = competitors[0].get("team", {}).get("abbreviation") + team2_abbr = competitors[1].get("team", {}).get("abbreviation") + if team1_abbr in FAVORITE_TEAMS or team2_abbr in FAVORITE_TEAMS: + logging.info(f"Found favorite game: {team1_abbr} vs {team2_abbr}") + return event # Return the whole event data + logging.info("No games involving favorite teams found.") + return None + +def find_relevant_favorite_event(data): + """Finds the most relevant game for favorite teams: Live > Recent Final > Next Upcoming.""" + if not data or "events" not in data: + return None + + live_event = None + recent_final_event = None + next_upcoming_event = None + + now_utc = datetime.now(timezone.utc) + cutoff_time_utc = now_utc - timedelta(hours=RECENT_GAME_HOURS) + + for event in data["events"]: + competitions = event.get("competitions", []) + if not competitions: + continue + competition = competitions[0] + competitors = competition.get("competitors", []) + if len(competitors) == 2: + team1_abbr = competitors[0].get("team", {}).get("abbreviation") + team2_abbr = competitors[1].get("team", {}).get("abbreviation") + + is_favorite = team1_abbr in FAVORITE_TEAMS or team2_abbr in FAVORITE_TEAMS + + if is_favorite: + details = extract_game_details(event) # Use extract to get parsed date and states + if not details or not details["start_time_utc"]: + continue # Skip if details couldn't be parsed + + # --- Check Categories (Priority Order) --- + + # 1. Live Game? + if details["is_live"]: + logging.debug(f"Found live favorite game: {team1_abbr} vs {team2_abbr}") + live_event = event + break # Found the highest priority, no need to check further + + # 2. Recent Final? + if details["is_final"] and details["start_time_utc"] > cutoff_time_utc: + # Keep the *most* recent final game + if recent_final_event is None or details["start_time_utc"] > extract_game_details(recent_final_event)["start_time_utc"]: + logging.debug(f"Found potential recent final: {team1_abbr} vs {team2_abbr}") + recent_final_event = event + + # 3. Upcoming Game? + if details["is_upcoming"] and details["start_time_utc"] > now_utc: + # Keep the *soonest* upcoming game + if next_upcoming_event is None or details["start_time_utc"] < extract_game_details(next_upcoming_event)["start_time_utc"]: + logging.debug(f"Found potential upcoming game: {team1_abbr} vs {team2_abbr}") + next_upcoming_event = event + + # Return the highest priority event found + if live_event: + logging.info("Displaying live favorite game.") + return live_event + elif recent_final_event: + logging.info("Displaying recent final favorite game.") + return recent_final_event + elif next_upcoming_event: + logging.info("Displaying next upcoming favorite game.") + return next_upcoming_event + else: + logging.info("No relevant (live, recent final, or upcoming) favorite games found.") + return None + +def extract_game_details(game_event): + """Extracts relevant details for the score bug display.""" + if not game_event: + return None + + details = {} + try: + competition = game_event["competitions"][0] + status = competition["status"] + competitors = competition["competitors"] + game_date_str = game_event["date"] # ISO 8601 format (UTC) + + # Parse game date/time + try: + details["start_time_utc"] = datetime.fromisoformat(game_date_str.replace("Z", "+00:00")) + except ValueError: + logging.warning(f"Could not parse game date: {game_date_str}") + details["start_time_utc"] = None + + home_team = next(c for c in competitors if c.get("homeAway") == "home") + away_team = next(c for c in competitors if c.get("homeAway") == "away") + + details["status_text"] = status["type"]["shortDetail"] # e.g., "7:30 - 1st" or "Final" + details["period"] = status.get("period", 0) + details["clock"] = status.get("displayClock", "0:00") + details["is_live"] = status["type"]["state"] in ("in", "halftime") # 'in' for ongoing + details["is_final"] = status["type"]["state"] == "post" + details["is_upcoming"] = status["type"]["state"] == "pre" + + details["home_abbr"] = home_team["team"]["abbreviation"] + details["home_score"] = home_team.get("score", "0") + details["home_logo_path"] = LOGO_DIR / f"{details['home_abbr']}.png" + + details["away_abbr"] = away_team["team"]["abbreviation"] + details["away_score"] = away_team.get("score", "0") + details["away_logo_path"] = LOGO_DIR / f"{details['away_abbr']}.png" + + # Check if logo files exist + if not details["home_logo_path"].is_file(): + logging.warning(f"Home logo not found: {details['home_logo_path']}") + details["home_logo_path"] = None + if not details["away_logo_path"].is_file(): + logging.warning(f"Away logo not found: {details['away_logo_path']}") + details["away_logo_path"] = None + + return details + + except (KeyError, IndexError, StopIteration) as e: + logging.error(f"Error parsing game details: {e} - Data: {game_event}") + return None + +def create_scorebug_image(game_details): + """Creates an image simulating the NHL score bug.""" + if not game_details: + # Create a blank or placeholder image if no game data + img = Image.new('RGB', (DISPLAY_WIDTH, DISPLAY_HEIGHT), color='black') + draw = ImageDraw.Draw(img) + try: + font = ImageFont.truetype("arial.ttf", 10) # Adjust font path/size + except IOError: + font = ImageFont.load_default() + draw.text((5, 10), "No game data", font=font, fill='white') + return img + + # --- Basic Layout --- + # This is highly dependent on your desired look and display size. + # Adjust positions, sizes, fonts accordingly. + img = Image.new('RGB', (DISPLAY_WIDTH, DISPLAY_HEIGHT), color='black') + draw = ImageDraw.Draw(img) + + try: + # Use a common font or specify path if needed + score_font = ImageFont.truetype("arial.ttf", 12) + time_font = ImageFont.truetype("arial.ttf", 10) + team_font = ImageFont.truetype("arial.ttf", 8) + status_font = ImageFont.truetype("arial.ttf", 9) # For Final/Upcoming status + except IOError: + logging.warning("Arial font not found, using default.") + score_font = ImageFont.load_default() + time_font = ImageFont.load_default() + team_font = ImageFont.load_default() + + + # --- Element Positions (Example - Needs heavy tuning) --- + away_logo_pos = (2, 2) + away_score_pos = (36, 2) # Right of away logo + home_logo_pos = (DISPLAY_WIDTH - 34, 2) # Positioned from the right + home_score_pos = (DISPLAY_WIDTH - 34 - 25, 2) # Left of home logo + + time_pos = (DISPLAY_WIDTH // 2, 2) # Centered top + period_pos = (DISPLAY_WIDTH // 2, 15) # Centered below time + + logo_size = (30, 30) # Max logo size + + # --- Draw Away Team --- + if game_details["away_logo_path"]: + try: + away_logo = Image.open(game_details["away_logo_path"]).convert("RGBA") + away_logo.thumbnail(logo_size, Image.Resampling.LANCZOS) + img.paste(away_logo, away_logo_pos, away_logo) # Use logo as mask for transparency + except Exception as e: + logging.error(f"Error loading/pasting away logo {game_details['away_logo_path']}: {e}") + # Draw placeholder text if logo fails + draw.text(away_logo_pos, game_details["away_abbr"], font=team_font, fill="white") + else: + # Draw abbreviation if no logo path + draw.text(away_logo_pos, game_details["away_abbr"], font=team_font, fill="white") + + draw.text(away_score_pos, str(game_details["away_score"]), font=score_font, fill='white') + + # --- Draw Home Team --- + if game_details["home_logo_path"]: + try: + home_logo = Image.open(game_details["home_logo_path"]).convert("RGBA") + home_logo.thumbnail(logo_size, Image.Resampling.LANCZOS) + img.paste(home_logo, home_logo_pos, home_logo) + except Exception as e: + logging.error(f"Error loading/pasting home logo {game_details['home_logo_path']}: {e}") + draw.text(home_logo_pos, game_details["home_abbr"], font=team_font, fill="white") + else: + draw.text((home_logo_pos[0] + 5, home_logo_pos[1] + 5), game_details["home_abbr"], font=team_font, fill="white", anchor="lt") + + + draw.text(home_score_pos, str(game_details["home_score"]), font=score_font, fill='white') + + # --- Draw Time and Period / Status --- + if game_details["is_live"]: + period_str = f"{game_details['period']}{'st' if game_details['period']==1 else 'nd' if game_details['period']==2 else 'rd' if game_details['period']==3 else 'th'}".upper() if game_details['period'] > 0 else "OT" if game_details['period'] > 3 else "" # Basic period formatting + # Check for Intermission specifically (adjust key if needed based on API) + status_name = game_details.get("status_type_name", "") # Need status name if possible + if status_name == "STATUS_HALFTIME": + # if "intermission" in game_details["status_text"].lower(): # Alternative check + period_str = "INTER" # Or "INT" + game_details["clock"] = "" # No clock during intermission + + draw.text(time_pos, game_details["clock"], font=time_font, fill='yellow', anchor="mt") # anchor middle-top + draw.text(period_pos, period_str, font=time_font, fill='yellow', anchor="mt") + + elif game_details["is_final"]: + # Display Final score status + draw.text(time_pos, "FINAL", font=status_font, fill='red', anchor="mt") + # Optionally add final period if available (e.g., "FINAL/OT") + period_str = f"/{game_details['period']}{'st' if game_details['period']==1 else 'nd' if game_details['period']==2 else 'rd' if game_details['period']==3 else 'th'}".upper() if game_details['period'] > 3 else "/OT" if game_details['period'] > 3 else "" + if game_details['period'] > 3: + draw.text(period_pos, f"OT{game_details['period'] - 3 if game_details['period'] < 7 else ''}", font=time_font, fill='red', anchor="mt") # Display OT period number + elif game_details['period'] == 0: # Check if shootout indicated differently? + draw.text(period_pos, "SO", font=time_font, fill='red', anchor="mt") + + elif game_details["is_upcoming"] and game_details["start_time_utc"]: + # Display Upcoming game time/date + start_local = game_details["start_time_utc"].astimezone(LOCAL_TIMEZONE) + now_local = datetime.now(LOCAL_TIMEZONE) + today_local = now_local.date() + start_date_local = start_local.date() + + if start_date_local == today_local: + date_str = "Today" + elif start_date_local == today_local + timedelta(days=1): + date_str = "Tomorrow" + else: + date_str = start_local.strftime("%a %b %d") # e.g., "Mon Jan 15" + + time_str = start_local.strftime("%I:%M %p").lstrip('0') # e.g., "7:30 PM" + + draw.text(time_pos, date_str, font=status_font, fill='cyan', anchor="mt") + draw.text(period_pos, time_str, font=time_font, fill='cyan', anchor="mt") + + else: + # Fallback for other statuses (Scheduled, Postponed etc.) + draw.text(time_pos, game_details["status_text"], font=time_font, fill='grey', anchor="mt") + + return img + +# --- Main Loop --- +def main(): + """Main execution loop.""" + load_config() # Load config first + + if not NHL_ENABLED: + logging.info("NHL Scoreboard is disabled in the configuration. Exiting.") + return + + logging.info("Starting NHL Scoreboard...") + # Logging moved to load_config + # logging.info(f"Favorite teams: {FAVORITE_TEAMS}") + logging.info(f"Checking logos in: {LOGO_DIR.resolve()}") + if not LOGO_DIR.is_dir(): + # Try creating the directory if it doesn't exist + logging.warning(f"Logo directory {LOGO_DIR} not found. Attempting to create it.") + try: + LOGO_DIR.mkdir(parents=True, exist_ok=True) + logging.info(f"Successfully created logo directory: {LOGO_DIR}") + except Exception as e: + logging.error(f"Failed to create logo directory {LOGO_DIR}: {e}. Please create it manually.") + return # Exit if we can't create it + + while True: + logging.debug("Fetching latest data...") + data = get_espn_data() + + game_event = None # Initialize game_event + if data: + # Find the most relevant game (Live > Recent Final > Upcoming) for favorites + game_event = find_relevant_favorite_event(data) + + # Fallback logic only if show_only_favorites is false + if not game_event and not SHOW_ONLY_FAVORITES and data.get("events"): + logging.debug("No relevant favorite game found, and show_only_favorites is false. Looking for any live/scheduled game.") + # Find *any* live game if no favorite is relevant + live_games = [e for e in data["events"] if e.get("competitions", [{}])[0].get("status", {}).get("type", {}).get("state") == "in"] + if live_games: + logging.info("No favorite game relevant, showing first available live game.") + game_event = live_games[0] + elif data["events"]: # Or just show the first game listed if none are live + logging.info("No favorite or live games, showing first scheduled/final game.") + game_event = data["events"][0] + elif not game_event and SHOW_ONLY_FAVORITES: + logging.info("No relevant favorite game found, and show_only_favorites is true. Skipping display.") + # game_event remains None + + # Proceed only if we found an event (either favorite or fallback) + if game_event: + game_details = extract_game_details(game_event) + scorebug_image = create_scorebug_image(game_details) + else: + # Handle case where no event should be shown (e.g., show_only_favorites is true and none found) + scorebug_image = create_scorebug_image(None) # Create the 'No game data' image + + # --- Display Output (Simulation) --- + try: + # Ensure OUTPUT_IMAGE_FILE is used + scorebug_image.save(OUTPUT_IMAGE_FILE) + logging.info(f"Scorebug image saved to {OUTPUT_IMAGE_FILE.name}") + except Exception as e: + logging.error(f"Failed to save scorebug image: {e}") + + # Add your actual display update logic here + # matrix.SetImage(scorebug_image.convert('RGB')) + + else: + logging.warning("No data received, skipping update cycle.") + # Optionally display an error message on the matrix + # You might want to create and display a specific error image here too + error_image = create_scorebug_image(None) # Or a custom error message + try: + error_image.save(OUTPUT_IMAGE_FILE) + except Exception as e: + logging.error(f"Failed to save error image: {e}") + + logging.debug(f"Sleeping for {UPDATE_INTERVAL_SECONDS} seconds...") + time.sleep(UPDATE_INTERVAL_SECONDS) + + +if __name__ == "__main__": + main() \ No newline at end of file