sportsball 0.3.108__tar.gz → 0.3.110__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sportsball-0.3.108/sportsball.egg-info → sportsball-0.3.110}/PKG-INFO +1 -1
- {sportsball-0.3.108 → sportsball-0.3.110}/setup.py +1 -1
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/__init__.py +1 -1
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/__main__.py +1 -1
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/args.py +5 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/afl/afl_afl_league_model.py +10 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/afltables/afl_afltables_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/aussportsbetting/afl_aussportsbetting_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/combined/afl_combined_league_model.py +8 -1
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/oddsportal/afl_oddsportal_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/aussportsbetting/aussportsbetting_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/combined/combined_address_model.py +6 -5
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/combined/combined_game_model.py +15 -10
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/combined/combined_league_model.py +5 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/combined/combined_player_model.py +33 -32
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/combined/combined_team_model.py +4 -3
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/combined/combined_venue_model.py +5 -4
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/combined/combined_weather_model.py +3 -2
- sportsball-0.3.110/sportsball/data/combined/null_check.py +22 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/espn/espn_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/google/google_address_model.py +28 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/league_model.py +19 -5
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/combined/nba_combined_league_model.py +8 -1
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/nba/nba_nba_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/sportsreference/nba_sportsreference_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaab/combined/ncaab_combined_league_model.py +8 -1
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaab/oddsportal/ncaab_oddsportal_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaab/sportsreference/ncaab_sportsreference_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaaf/combined/ncaaf_combined_league_model.py +8 -1
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nfl/aussportsbetting/nfl_aussportsbetting_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nfl/combined/nfl_combined_league_model.py +8 -1
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nfl/espn/nfl_espn_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nfl/oddsportal/nfl_oddsportal_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nfl/sportsdb/nfl_sportsdb_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/oddsportal/oddsportal_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/sportsdb/sportsdb_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/sportsreference/sportsreference_game_model.py +2 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/sportsreference/sportsreference_league_model.py +4 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/sportsball.py +6 -6
- {sportsball-0.3.108 → sportsball-0.3.110/sportsball.egg-info}/PKG-INFO +1 -1
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball.egg-info/SOURCES.txt +1 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/afl/afltables/afl_afltables_game_model_test.py +2 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/sportsball_test.py +1 -1
- {sportsball-0.3.108 → sportsball-0.3.110}/LICENSE +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/MANIFEST.in +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/README.md +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/requirements.txt +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/setup.cfg +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/cache.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/address_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/afl/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/afl/afl_afl_game_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/afl/afl_afl_player_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/afl/afl_afl_team_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/afl/afl_afl_venue_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/afltables/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/afltables/afl_afltables_game_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/afltables/afl_afltables_player_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/afltables/afl_afltables_team_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/afltables/afl_afltables_venue_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/aussportsbetting/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/combined/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/espn/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/espn/afl_espn_league_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/oddsportal/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/aussportsbetting/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/aussportsbetting/aussportsbetting_bookie_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/aussportsbetting/aussportsbetting_game_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/aussportsbetting/aussportsbetting_odds_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/aussportsbetting/aussportsbetting_team_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/aussportsbetting/aussportsbetting_venue_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/bookie_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/combined/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/espn/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/espn/espn_bookie_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/espn/espn_game_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/espn/espn_odds_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/espn/espn_player_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/espn/espn_team_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/espn/espn_venue_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/field_type.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/game_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/google/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/google/google_news_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/league.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/combined/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/espn/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/espn/nba_espn_league_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/nba/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/nba/nba_nba_game_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/nba/nba_nba_team_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/oddsportal/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/oddsportal/nba_oddsportal_league_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/sportsdb/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/sportsdb/nba_sportsdb_league_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/sportsreference/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaab/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaab/combined/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaab/espn/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaab/espn/ncaab_espn_league_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaab/oddsportal/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaab/sportsreference/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaaf/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaaf/combined/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaaf/espn/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaaf/espn/ncaaf_espn_league_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaaf/oddsportal/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/ncaaf/oddsportal/ncaaf_oddsportal_league_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/news_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nfl/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nfl/aussportsbetting/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nfl/combined/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nfl/espn/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nfl/oddsportal/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nfl/sportsdb/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/odds_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/oddsportal/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/oddsportal/decrypt.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/oddsportal/oddsportal_bookie_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/oddsportal/oddsportal_game_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/oddsportal/oddsportal_odds_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/oddsportal/oddsportal_team_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/oddsportal/oddsportal_venue_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/player_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/season_type.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/social_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/sportsdb/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/sportsdb/sportsdb_game_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/sportsdb/sportsdb_team_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/sportsdb/sportsdb_venue_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/sportsreference/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/sportsreference/sportsreference_player_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/sportsreference/sportsreference_team_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/sportsreference/sportsreference_venue_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/team_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/venue_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/weather/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/weather/gribstream/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/weather/gribstream/gribstream_weather_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/weather/multi_weather_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/weather/openmeteo/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/weather/openmeteo/openmeteo_weather_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/weather_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/wikipedia/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/wikipedia/wikipedia_venue_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/x/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/x/x_social_model.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/logger.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/loglevel.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/playwright.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/proxy_session.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/session.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/vendor/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball/vendor/pygooglenews/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball.egg-info/dependency_links.txt +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball.egg-info/entry_points.txt +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball.egg-info/not-zip-safe +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball.egg-info/requires.txt +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/sportsball.egg-info/top_level.txt +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/afl/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/afl/afl/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/afl/afl/afl_afl_league_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/afl/afltables/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/afl/afltables/afl_afltables_league_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/afl/afltables/afl_afltables_player_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/aussportsbetting/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/aussportsbetting/aussportsbetting_game_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/combined/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/combined/combined_game_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/combined/combined_player_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/combined/combined_team_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/espn/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/espn/espn_game_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/espn/espn_player_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/game_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/google/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/google/google_address_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/google/google_news_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/nba/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/nba/nba/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/nba/nba/nba_nba_game_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/nba/nba/nba_nba_league_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/nba/nba/nba_nba_team_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/nba/sportsdb/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/nba/sportsdb/nba_sportsdb_league_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/nba/sportsreference/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/nba/sportsreference/nba_sportsreference_league_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/ncaab/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/ncaab/sportsreference/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/ncaab/sportsreference/ncaab_sportsreference_league_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/nfl/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/nfl/sportsdb/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/nfl/sportsdb/nfl_sportsdb_league_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/oddsportal/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/oddsportal/decrypt_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/oddsportal/oddsportal_game_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/oddsportal/oddsportal_league_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/player_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/social_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/sportsdb/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/sportsdb/sportsdb_game_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/sportsdb/sportsdb_league_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/sportsdb/sportsdb_team_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/sportsdb/sportsdb_venue_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/sportsreference/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/sportsreference/sportsreference_game_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/sportsreference/sportsreference_league_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/sportsreference/sportsreference_player_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/sportsreference/sportsreference_team_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/sportsreference/sportsreference_venue_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/team_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/x/__init__.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/data/x/x_social_model_test.py +0 -0
- {sportsball-0.3.108 → sportsball-0.3.110}/tests/proxy_session_test.py +0 -0
@@ -26,7 +26,7 @@ def install_requires() -> typing.List[str]:
|
|
26
26
|
|
27
27
|
setup(
|
28
28
|
name='sportsball',
|
29
|
-
version='0.3.
|
29
|
+
version='0.3.110',
|
30
30
|
description='A library for pulling in and normalising sports stats.',
|
31
31
|
long_description=long_description,
|
32
32
|
long_description_content_type='text/markdown',
|
@@ -21,7 +21,7 @@ def main() -> None:
|
|
21
21
|
logging.info("--- sportsball %s ---", __VERSION__)
|
22
22
|
|
23
23
|
ball = SportsBall()
|
24
|
-
league = ball.league(league_from_str(args.league))
|
24
|
+
league = ball.league(league_from_str(args.league), args.leaguemodel)
|
25
25
|
df = league.to_frame()
|
26
26
|
handle = io.BytesIO()
|
27
27
|
df.to_parquet(handle, compression="gzip")
|
@@ -23,6 +23,11 @@ def parse_args() -> argparse.Namespace:
|
|
23
23
|
help="The loglevel to display logs at..",
|
24
24
|
required=False,
|
25
25
|
)
|
26
|
+
parser.add_argument(
|
27
|
+
"--leaguemodel",
|
28
|
+
required=False,
|
29
|
+
help="The league model to use.",
|
30
|
+
)
|
26
31
|
parser.add_argument(
|
27
32
|
"file",
|
28
33
|
default=STDOUT_FILE,
|
@@ -8,6 +8,7 @@ from typing import Iterator
|
|
8
8
|
|
9
9
|
import requests_cache
|
10
10
|
from bs4 import BeautifulSoup
|
11
|
+
from dateutil.parser import parse
|
11
12
|
from playwright.sync_api import sync_playwright
|
12
13
|
|
13
14
|
from ....playwright import ensure_install
|
@@ -73,6 +74,11 @@ def _parse_game_info(
|
|
73
74
|
"time", {"class": re.compile(".*match-list-alt__header-time.*")}
|
74
75
|
):
|
75
76
|
dt = datetime.datetime.fromtimestamp(float(time.get("data-date")) / 1000.0)
|
77
|
+
for span_tz in div.find_all(
|
78
|
+
"span", {"class": re.compile(".*match-list-alt__header-timezone.*")}
|
79
|
+
):
|
80
|
+
tz_text = span_tz.get_text().strip().replace("(", "").replace(")", "")
|
81
|
+
dt = parse(" ".join([str(dt), tz_text]))
|
76
82
|
venue_name: str | None = None
|
77
83
|
for span in div.find_all(
|
78
84
|
"span", {"class": re.compile(".*match-list-alt__header-venue.*")}
|
@@ -95,6 +101,10 @@ class AFLAFLLeagueModel(LeagueModel):
|
|
95
101
|
) -> None:
|
96
102
|
super().__init__(League.AFL, session)
|
97
103
|
|
104
|
+
@classmethod
|
105
|
+
def name(cls) -> str:
|
106
|
+
return "afl-afl-league-model"
|
107
|
+
|
98
108
|
@property
|
99
109
|
def _ladder(self) -> list[str]:
|
100
110
|
ladder = []
|
@@ -47,6 +47,10 @@ class AFLAFLTablesLeagueModel(LeagueModel):
|
|
47
47
|
) -> None:
|
48
48
|
super().__init__(League.AFL, session)
|
49
49
|
|
50
|
+
@classmethod
|
51
|
+
def name(cls) -> str:
|
52
|
+
return "afl-afltables-league-model"
|
53
|
+
|
50
54
|
def _produce_games(
|
51
55
|
self, season_url: str, season_type: SeasonType, pbar: tqdm.tqdm
|
52
56
|
) -> Iterator[GameModel]:
|
@@ -14,3 +14,7 @@ class AFLAusSportsBettingLeagueModel(AusSportsBettingLeagueModel):
|
|
14
14
|
self, session: requests_cache.CachedSession, position: int | None = None
|
15
15
|
) -> None:
|
16
16
|
super().__init__(League.AFL, session, position=position)
|
17
|
+
|
18
|
+
@classmethod
|
19
|
+
def name(cls) -> str:
|
20
|
+
return "afl-aussportsbetting-league-model"
|
{sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/afl/combined/afl_combined_league_model.py
RENAMED
@@ -251,7 +251,9 @@ AFL_VENUE_IDENTITY_MAP = {
|
|
251
251
|
class AFLCombinedLeagueModel(CombinedLeagueModel):
|
252
252
|
"""AFL combined implementation of the league model."""
|
253
253
|
|
254
|
-
def __init__(
|
254
|
+
def __init__(
|
255
|
+
self, session: requests_cache.CachedSession, league_filter: str | None
|
256
|
+
) -> None:
|
255
257
|
super().__init__(
|
256
258
|
session,
|
257
259
|
League.AFL,
|
@@ -262,6 +264,7 @@ class AFLCombinedLeagueModel(CombinedLeagueModel):
|
|
262
264
|
AFLOddsPortalLeagueModel(session, position=3),
|
263
265
|
AFLAFLLeagueModel(session, position=4),
|
264
266
|
],
|
267
|
+
league_filter,
|
265
268
|
)
|
266
269
|
|
267
270
|
@classmethod
|
@@ -271,3 +274,7 @@ class AFLCombinedLeagueModel(CombinedLeagueModel):
|
|
271
274
|
@classmethod
|
272
275
|
def venue_identity_map(cls) -> dict[str, str]:
|
273
276
|
return AFL_VENUE_IDENTITY_MAP
|
277
|
+
|
278
|
+
@classmethod
|
279
|
+
def name(cls) -> str:
|
280
|
+
return "afl-combined-league-model"
|
@@ -15,3 +15,7 @@ class AFLOddsPortalLeagueModel(OddsPortalLeagueModel):
|
|
15
15
|
self, session: requests_cache.CachedSession, position: int | None = None
|
16
16
|
) -> None:
|
17
17
|
super().__init__(League.AFL, session, position=position)
|
18
|
+
|
19
|
+
@classmethod
|
20
|
+
def name(cls) -> str:
|
21
|
+
return "afl-oddsportal-league-model"
|
@@ -39,6 +39,10 @@ class AusSportsBettingLeagueModel(LeagueModel):
|
|
39
39
|
f"League {league} not supported by aus sports betting."
|
40
40
|
)
|
41
41
|
|
42
|
+
@classmethod
|
43
|
+
def name(cls) -> str:
|
44
|
+
return "aussportsbetting-league-model"
|
45
|
+
|
42
46
|
def _row_to_game(self, row: Any) -> GameModel | None:
|
43
47
|
current_cell_idx = 0
|
44
48
|
date_cell = str(row[0].value)
|
{sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/combined/combined_address_model.py
RENAMED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
from ..address_model import AddressModel
|
4
4
|
from .combined_weather_model import create_combined_weather_model
|
5
|
+
from .null_check import is_null
|
5
6
|
|
6
7
|
|
7
8
|
def create_combined_address_model(
|
@@ -16,16 +17,16 @@ def create_combined_address_model(
|
|
16
17
|
weather_models = []
|
17
18
|
for address_model in address_models:
|
18
19
|
address_model_latitude = address_model.latitude
|
19
|
-
if
|
20
|
+
if not is_null(address_model_latitude):
|
20
21
|
latitude = address_model_latitude
|
21
22
|
address_model_longitude = address_model.longitude
|
22
|
-
if
|
23
|
+
if not is_null(address_model_longitude):
|
23
24
|
longitude = address_model_longitude
|
24
25
|
address_model_housenumber = address_model.housenumber
|
25
|
-
if
|
26
|
+
if not is_null(address_model_housenumber):
|
26
27
|
housenumber = address_model_housenumber
|
27
28
|
address_model_weather = address_model.weather
|
28
|
-
if
|
29
|
+
if not is_null(address_model_weather):
|
29
30
|
weather_models.append(address_model_weather)
|
30
31
|
return AddressModel(
|
31
32
|
city=address_models[0].city,
|
@@ -34,7 +35,7 @@ def create_combined_address_model(
|
|
34
35
|
latitude=latitude,
|
35
36
|
longitude=longitude,
|
36
37
|
housenumber=housenumber,
|
37
|
-
weather=create_combined_weather_model(weather_models), #
|
38
|
+
weather=create_combined_weather_model(weather_models), # type: ignore
|
38
39
|
timezone=address_models[0].timezone,
|
39
40
|
country=address_models[0].country,
|
40
41
|
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
"""Combined game model."""
|
2
2
|
|
3
|
-
# pylint: disable=too-many-locals,line-too-long,too-many-arguments
|
3
|
+
# pylint: disable=too-many-locals,line-too-long,too-many-arguments,too-many-branches
|
4
4
|
import logging
|
5
5
|
|
6
6
|
import requests
|
@@ -10,6 +10,7 @@ from ..team_model import TeamModel
|
|
10
10
|
from ..venue_model import VenueModel
|
11
11
|
from .combined_team_model import create_combined_team_model
|
12
12
|
from .combined_venue_model import create_combined_venue_model
|
13
|
+
from .null_check import is_null
|
13
14
|
|
14
15
|
|
15
16
|
def _venue_models(
|
@@ -78,30 +79,34 @@ def create_combined_game_model(
|
|
78
79
|
game_number = None
|
79
80
|
postponed = None
|
80
81
|
play_off = None
|
82
|
+
dt = game_models[0].dt
|
81
83
|
for game_model in game_models:
|
84
|
+
game_model_dt = game_model.dt
|
85
|
+
if game_model_dt.tzinfo is not None and dt.tzinfo is None:
|
86
|
+
dt = game_model_dt
|
82
87
|
game_model_attendance = game_model.attendance
|
83
|
-
if
|
88
|
+
if not is_null(game_model_attendance):
|
84
89
|
attendance = game_model_attendance
|
85
90
|
game_model_end_dt = game_model.end_dt
|
86
|
-
if
|
91
|
+
if not is_null(game_model_end_dt):
|
87
92
|
end_dt = game_model_end_dt
|
88
93
|
game_model_year = game_model.year
|
89
|
-
if
|
94
|
+
if not is_null(game_model_year):
|
90
95
|
year = game_model_year
|
91
96
|
game_model_season_type = game_model.season_type
|
92
|
-
if
|
97
|
+
if not is_null(game_model_season_type):
|
93
98
|
season_type = game_model_season_type
|
94
99
|
game_model_week = game_model.week
|
95
|
-
if
|
100
|
+
if not is_null(game_model_week):
|
96
101
|
week = game_model_week
|
97
102
|
game_model_game_number = game_model.game_number
|
98
|
-
if
|
103
|
+
if not is_null(game_model_game_number):
|
99
104
|
game_number = game_model_game_number
|
100
105
|
game_model_postponed = game_model.postponed
|
101
|
-
if
|
106
|
+
if not is_null(game_model_postponed):
|
102
107
|
postponed = game_model_postponed
|
103
108
|
game_model_play_off = game_model.play_off
|
104
|
-
if
|
109
|
+
if not is_null(game_model_play_off):
|
105
110
|
play_off = game_model_play_off
|
106
111
|
|
107
112
|
if full_venue_identity is None and venue_models:
|
@@ -111,7 +116,7 @@ def create_combined_game_model(
|
|
111
116
|
full_venue_identity = venue_model_identifier
|
112
117
|
|
113
118
|
return GameModel(
|
114
|
-
dt=
|
119
|
+
dt=dt,
|
115
120
|
week=week,
|
116
121
|
game_number=game_number,
|
117
122
|
venue=create_combined_venue_model(venue_models, full_venue_identity, session), # pyright: ignore
|
@@ -26,8 +26,13 @@ class CombinedLeagueModel(LeagueModel):
|
|
26
26
|
session: requests_cache.CachedSession,
|
27
27
|
league: League,
|
28
28
|
league_models: list[LeagueModel],
|
29
|
+
league_filter: str | None,
|
29
30
|
) -> None:
|
30
31
|
super().__init__(league, session)
|
32
|
+
if league_filter is not None:
|
33
|
+
league_models = [x for x in league_models if x.name() == league_filter]
|
34
|
+
if not league_models:
|
35
|
+
raise ValueError("No league models to run")
|
31
36
|
self._league_models = league_models
|
32
37
|
|
33
38
|
@classmethod
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
# pylint: disable=too-many-locals,too-many-branches,too-many-statements,duplicate-code
|
4
4
|
from ..player_model import PlayerModel
|
5
|
+
from .null_check import is_null
|
5
6
|
|
6
7
|
|
7
8
|
def create_combined_player_model(
|
@@ -42,100 +43,100 @@ def create_combined_player_model(
|
|
42
43
|
percentage_played = None
|
43
44
|
for player_model in player_models:
|
44
45
|
player_model_jersey = player_model.jersey
|
45
|
-
if
|
46
|
+
if not is_null(player_model_jersey):
|
46
47
|
jersey = player_model_jersey
|
47
48
|
player_model_kicks = player_model.kicks
|
48
|
-
if
|
49
|
+
if not is_null(player_model_kicks):
|
49
50
|
kicks = player_model_kicks
|
50
51
|
player_model_fumbles = player_model.fumbles
|
51
|
-
if
|
52
|
+
if not is_null(player_model_fumbles):
|
52
53
|
fumbles = player_model_fumbles
|
53
54
|
player_model_fumbles_lost = player_model.fumbles_lost
|
54
|
-
if
|
55
|
+
if not is_null(player_model_fumbles_lost):
|
55
56
|
fumbles_lost = player_model_fumbles_lost
|
56
57
|
player_model_field_goals = player_model.field_goals
|
57
|
-
if
|
58
|
+
if not is_null(player_model_field_goals):
|
58
59
|
field_goals = player_model_field_goals
|
59
60
|
player_model_field_goals_attempted = player_model.field_goals_attempted
|
60
|
-
if
|
61
|
+
if not is_null(player_model_field_goals_attempted):
|
61
62
|
field_goals_attempted = player_model_field_goals_attempted
|
62
63
|
player_model_offensive_rebounds = player_model.offensive_rebounds
|
63
|
-
if
|
64
|
+
if not is_null(player_model_offensive_rebounds):
|
64
65
|
offensive_rebounds = player_model_offensive_rebounds
|
65
66
|
player_model_assists = player_model.assists
|
66
|
-
if
|
67
|
+
if not is_null(player_model_assists):
|
67
68
|
assists = player_model_assists
|
68
69
|
player_model_turnovers = player_model.turnovers
|
69
|
-
if
|
70
|
+
if not is_null(player_model_turnovers):
|
70
71
|
turnovers = player_model_turnovers
|
71
72
|
player_model_name = player_model.name
|
72
|
-
if
|
73
|
+
if not is_null(player_model_name):
|
73
74
|
name = player_model_name
|
74
75
|
player_model_marks = player_model.marks
|
75
|
-
if
|
76
|
+
if not is_null(player_model_marks):
|
76
77
|
marks = player_model_marks
|
77
78
|
player_model_handballs = player_model.handballs
|
78
|
-
if
|
79
|
+
if not is_null(player_model_handballs):
|
79
80
|
handballs = player_model_handballs
|
80
81
|
player_model_disposals = player_model.disposals
|
81
|
-
if
|
82
|
+
if not is_null(player_model_disposals):
|
82
83
|
disposals = player_model_disposals
|
83
84
|
player_model_goals = player_model.goals
|
84
|
-
if
|
85
|
+
if not is_null(player_model_goals):
|
85
86
|
goals = player_model_goals
|
86
87
|
player_model_behinds = player_model.behinds
|
87
|
-
if
|
88
|
+
if not is_null(player_model_behinds):
|
88
89
|
behinds = player_model_behinds
|
89
90
|
player_model_hit_outs = player_model.hit_outs
|
90
|
-
if
|
91
|
+
if not is_null(player_model_hit_outs):
|
91
92
|
hit_outs = player_model_hit_outs
|
92
93
|
player_model_tackles = player_model.tackles
|
93
|
-
if
|
94
|
+
if not is_null(player_model_tackles):
|
94
95
|
tackles = player_model_tackles
|
95
96
|
player_model_rebounds = player_model.rebounds
|
96
|
-
if
|
97
|
+
if not is_null(player_model_rebounds):
|
97
98
|
rebounds = player_model_rebounds
|
98
99
|
player_model_insides = player_model.insides
|
99
|
-
if
|
100
|
+
if not is_null(player_model_insides):
|
100
101
|
insides = player_model_insides
|
101
102
|
player_model_clearances = player_model.clearances
|
102
|
-
if
|
103
|
+
if not is_null(player_model_clearances):
|
103
104
|
clearances = player_model_clearances
|
104
105
|
player_model_clangers = player_model.clangers
|
105
|
-
if
|
106
|
+
if not is_null(player_model_clangers):
|
106
107
|
clangers = player_model_clangers
|
107
108
|
player_model_free_kicks_for = player_model.free_kicks_for
|
108
|
-
if
|
109
|
+
if not is_null(player_model_free_kicks_for):
|
109
110
|
free_kicks_for = player_model_free_kicks_for
|
110
111
|
player_model_free_kicks_against = player_model.free_kicks_against
|
111
|
-
if
|
112
|
+
if not is_null(player_model_free_kicks_against):
|
112
113
|
free_kicks_against = player_model_free_kicks_against
|
113
114
|
player_model_brownlow_votes = player_model.brownlow_votes
|
114
|
-
if
|
115
|
+
if not is_null(player_model_brownlow_votes):
|
115
116
|
brownlow_votes = player_model_brownlow_votes
|
116
117
|
player_model_contested_possessions = player_model.contested_possessions
|
117
|
-
if
|
118
|
+
if not is_null(player_model_contested_possessions):
|
118
119
|
contested_possessions = player_model_contested_possessions
|
119
120
|
player_model_uncontested_possessions = player_model.uncontested_possessions
|
120
|
-
if
|
121
|
+
if not is_null(player_model_uncontested_possessions):
|
121
122
|
uncontested_possessions = player_model_uncontested_possessions
|
122
123
|
player_model_contested_marks = player_model.contested_marks
|
123
|
-
if
|
124
|
+
if not is_null(player_model_contested_marks):
|
124
125
|
contested_marks = player_model_contested_marks
|
125
126
|
player_model_marks_inside = player_model.marks_inside
|
126
|
-
if
|
127
|
+
if not is_null(player_model_marks_inside):
|
127
128
|
marks_inside = player_model_marks_inside
|
128
129
|
player_model_one_percenters = player_model.one_percenters
|
129
|
-
if
|
130
|
+
if not is_null(player_model_one_percenters):
|
130
131
|
one_percenters = player_model_one_percenters
|
131
132
|
player_model_bounces = player_model.bounces
|
132
|
-
if
|
133
|
+
if not is_null(player_model_bounces):
|
133
134
|
bounces = player_model_bounces
|
134
135
|
player_model_goal_assists = player_model.goal_assists
|
135
|
-
if
|
136
|
+
if not is_null(player_model_goal_assists):
|
136
137
|
goal_assists = player_model_goal_assists
|
137
138
|
player_model_percentage_played = player_model.percentage_played
|
138
|
-
if
|
139
|
+
if not is_null(player_model_percentage_played):
|
139
140
|
percentage_played = player_model_percentage_played
|
140
141
|
if name is None:
|
141
142
|
raise ValueError("name is null.")
|
@@ -10,6 +10,7 @@ from ..player_model import PlayerModel
|
|
10
10
|
from ..social_model import SocialModel
|
11
11
|
from ..team_model import TeamModel
|
12
12
|
from .combined_player_model import create_combined_player_model
|
13
|
+
from .null_check import is_null
|
13
14
|
|
14
15
|
REGEX = re.compile("[^a-zA-Z]")
|
15
16
|
|
@@ -54,10 +55,10 @@ def create_combined_team_model(
|
|
54
55
|
key = f"{odds_model.bookie.identifier}-{odds_model.odds}"
|
55
56
|
odds[key] = odds.get(key, []) + [odds_model]
|
56
57
|
team_model_points = team_model.points
|
57
|
-
if
|
58
|
+
if not is_null(team_model_points):
|
58
59
|
points = team_model_points
|
59
60
|
team_model_ladder_rank = team_model.ladder_rank
|
60
|
-
if
|
61
|
+
if not is_null(team_model_ladder_rank):
|
61
62
|
ladder_rank = team_model_ladder_rank
|
62
63
|
for news_model in team_model.news:
|
63
64
|
news_key = "-".join(
|
@@ -75,7 +76,7 @@ def create_combined_team_model(
|
|
75
76
|
)
|
76
77
|
social[social_key] = social_model
|
77
78
|
team_model_field_goals = team_model.field_goals
|
78
|
-
if
|
79
|
+
if not is_null(team_model_field_goals):
|
79
80
|
field_goals = team_model_field_goals
|
80
81
|
|
81
82
|
return TeamModel(
|
@@ -5,6 +5,7 @@ import requests
|
|
5
5
|
from ..venue_model import VenueModel
|
6
6
|
from ..wikipedia.wikipedia_venue_model import create_wikipedia_venue_model
|
7
7
|
from .combined_address_model import create_combined_address_model
|
8
|
+
from .null_check import is_null
|
8
9
|
|
9
10
|
|
10
11
|
def create_combined_venue_model(
|
@@ -24,18 +25,18 @@ def create_combined_venue_model(
|
|
24
25
|
is_indoor = None
|
25
26
|
for venue_model in venue_models:
|
26
27
|
venue_model_address = venue_model.address
|
27
|
-
if
|
28
|
+
if not is_null(venue_model_address):
|
28
29
|
address_models.append(venue_model_address)
|
29
30
|
venue_model_is_grass = venue_model.is_grass
|
30
|
-
if
|
31
|
+
if not is_null(venue_model_is_grass):
|
31
32
|
is_grass = venue_model_is_grass
|
32
33
|
venue_model_is_indoor = venue_model.is_indoor
|
33
|
-
if
|
34
|
+
if not is_null(venue_model_is_indoor):
|
34
35
|
is_indoor = venue_model_is_indoor
|
35
36
|
return VenueModel(
|
36
37
|
identifier=identifier,
|
37
38
|
name=venue_models[0].name,
|
38
|
-
address=create_combined_address_model(address_models), #
|
39
|
+
address=create_combined_address_model(address_models), # type: ignore
|
39
40
|
is_grass=is_grass,
|
40
41
|
is_indoor=is_indoor,
|
41
42
|
)
|
{sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/combined/combined_weather_model.py
RENAMED
@@ -1,6 +1,7 @@
|
|
1
1
|
"""Combined weather model."""
|
2
2
|
|
3
3
|
from ..weather_model import WeatherModel
|
4
|
+
from .null_check import is_null
|
4
5
|
|
5
6
|
|
6
7
|
def create_combined_weather_model(
|
@@ -13,9 +14,9 @@ def create_combined_weather_model(
|
|
13
14
|
relative_humidity = None
|
14
15
|
for weather_model in weather_models:
|
15
16
|
weather_model_temperature = weather_model.temperature
|
16
|
-
if
|
17
|
+
if not is_null(weather_model_temperature):
|
17
18
|
temperature = weather_model_temperature
|
18
19
|
weather_model_relative_humidity = weather_model.relative_humidity
|
19
|
-
if
|
20
|
+
if not is_null(weather_model_relative_humidity):
|
20
21
|
relative_humidity = weather_model_relative_humidity
|
21
22
|
return WeatherModel(temperature=temperature, relative_humidity=relative_humidity)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
"""A function for checking whether an object is null."""
|
2
|
+
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
import numpy as np
|
6
|
+
|
7
|
+
|
8
|
+
def is_null(obj: Any) -> bool:
|
9
|
+
"""Whether the object is a null type object."""
|
10
|
+
if obj is None:
|
11
|
+
return True
|
12
|
+
try:
|
13
|
+
if np.isnan(obj):
|
14
|
+
return True
|
15
|
+
except TypeError:
|
16
|
+
pass
|
17
|
+
try:
|
18
|
+
if np.isnat(obj):
|
19
|
+
return True
|
20
|
+
except TypeError:
|
21
|
+
pass
|
22
|
+
return False
|
@@ -38,6 +38,10 @@ class ESPNLeagueModel(LeagueModel):
|
|
38
38
|
super().__init__(league, session, position=position)
|
39
39
|
self._start_url = start_url
|
40
40
|
|
41
|
+
@classmethod
|
42
|
+
def name(cls) -> str:
|
43
|
+
return "espn-league-model"
|
44
|
+
|
41
45
|
def _produce_games(
|
42
46
|
self,
|
43
47
|
week: dict[str, Any],
|
@@ -13721,6 +13721,34 @@ _CACHED_GEOCODES: dict[str, Any] = {
|
|
13721
13721
|
housenumber="1201",
|
13722
13722
|
country="USA",
|
13723
13723
|
),
|
13724
|
+
"Ninja Stadium": BLUNDSTONE_ARENA,
|
13725
|
+
"Summit Arena, Rapid City, South Dakota": SportsballGeocodeTuple(
|
13726
|
+
city="Rapid City",
|
13727
|
+
state="SD",
|
13728
|
+
postal="",
|
13729
|
+
lat=44.08854,
|
13730
|
+
lng=-103.225816,
|
13731
|
+
housenumber="444",
|
13732
|
+
country="USA",
|
13733
|
+
),
|
13734
|
+
"Charleston, West Virginia": SportsballGeocodeTuple(
|
13735
|
+
city="Charleston",
|
13736
|
+
state="WV",
|
13737
|
+
postal="",
|
13738
|
+
lat=38.349819,
|
13739
|
+
lng=-81.632622,
|
13740
|
+
housenumber="",
|
13741
|
+
country="USA",
|
13742
|
+
),
|
13743
|
+
"Shreveport, Louisiana": SportsballGeocodeTuple(
|
13744
|
+
city="Shreveport",
|
13745
|
+
state="LA",
|
13746
|
+
postal="",
|
13747
|
+
lat=32.463889,
|
13748
|
+
lng=-93.794444,
|
13749
|
+
housenumber="",
|
13750
|
+
country="USA",
|
13751
|
+
),
|
13724
13752
|
}
|
13725
13753
|
|
13726
13754
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
"""The prototype class defining how to interface to the league."""
|
2
2
|
|
3
3
|
# pylint: disable=line-too-long
|
4
|
+
import datetime
|
4
5
|
from typing import Iterator, get_args, get_origin
|
5
6
|
|
6
7
|
import pandas as pd
|
@@ -35,6 +36,7 @@ def _normalize_tz(df: pd.DataFrame) -> pd.DataFrame:
|
|
35
36
|
)
|
36
37
|
if tz_column not in df.columns.values.tolist():
|
37
38
|
return df
|
39
|
+
df = df.dropna(subset=tz_column)
|
38
40
|
|
39
41
|
tqdm.tqdm.pandas(desc="Timezone Conversions")
|
40
42
|
|
@@ -46,10 +48,14 @@ def _normalize_tz(df: pd.DataFrame) -> pd.DataFrame:
|
|
46
48
|
if pd.isnull(tz):
|
47
49
|
return row
|
48
50
|
|
49
|
-
|
50
|
-
col
|
51
|
+
datetime_cols = {
|
52
|
+
col for col, val in row.items() if isinstance(val, pd.Timestamp)
|
51
53
|
}
|
52
|
-
|
54
|
+
datetime_cols.add(GAME_DT_COLUMN)
|
55
|
+
for col in datetime_cols:
|
56
|
+
dt = row[col] # type: ignore
|
57
|
+
if isinstance(dt, datetime.datetime):
|
58
|
+
dt = pd.to_datetime(dt)
|
53
59
|
if dt.tz is None:
|
54
60
|
row[col] = dt.tz_localize(tz, ambiguous=True)
|
55
61
|
elif str(dt.tz) != str(tz):
|
@@ -57,7 +63,7 @@ def _normalize_tz(df: pd.DataFrame) -> pd.DataFrame:
|
|
57
63
|
|
58
64
|
return row
|
59
65
|
|
60
|
-
return df.
|
66
|
+
return df.progress_apply(apply_tz, axis=1) # type: ignore
|
61
67
|
|
62
68
|
|
63
69
|
class LeagueModel(Model):
|
@@ -76,6 +82,11 @@ class LeagueModel(Model):
|
|
76
82
|
self._df = None
|
77
83
|
self.position = position
|
78
84
|
|
85
|
+
@classmethod
|
86
|
+
def name(cls) -> str:
|
87
|
+
"""The name of the league model."""
|
88
|
+
raise NotImplementedError("name is not implemented by parent class.")
|
89
|
+
|
79
90
|
@property
|
80
91
|
def games(self) -> Iterator[GameModel]:
|
81
92
|
"""Find all the games in this league."""
|
@@ -180,7 +191,10 @@ class LeagueModel(Model):
|
|
180
191
|
df = _normalize_tz(df)
|
181
192
|
|
182
193
|
if GAME_DT_COLUMN in df.columns.values:
|
183
|
-
df[GAME_DT_COLUMN] = pd.to_datetime(df[GAME_DT_COLUMN]
|
194
|
+
# df[GAME_DT_COLUMN] = pd.to_datetime(df[GAME_DT_COLUMN])
|
195
|
+
# naive_times = df[df[GAME_DT_COLUMN].dt.tz.isna()]
|
196
|
+
# print("naive_times:")
|
197
|
+
# print(naive_times)
|
184
198
|
df = df.sort_values(
|
185
199
|
by=GAME_DT_COLUMN,
|
186
200
|
ascending=True,
|
{sportsball-0.3.108 → sportsball-0.3.110}/sportsball/data/nba/combined/nba_combined_league_model.py
RENAMED
@@ -891,7 +891,9 @@ NBA_PLAYER_IDENTITY_MAP: dict[str, str] = {}
|
|
891
891
|
class NBACombinedLeagueModel(CombinedLeagueModel):
|
892
892
|
"""NBA combined implementation of the league model."""
|
893
893
|
|
894
|
-
def __init__(
|
894
|
+
def __init__(
|
895
|
+
self, session: requests_cache.CachedSession, league_filter: str | None
|
896
|
+
) -> None:
|
895
897
|
super().__init__(
|
896
898
|
session,
|
897
899
|
League.NBA,
|
@@ -902,6 +904,7 @@ class NBACombinedLeagueModel(CombinedLeagueModel):
|
|
902
904
|
NBASportsReferenceLeagueModel(session, position=3),
|
903
905
|
NBAOddsPortalLeagueModel(session, position=4),
|
904
906
|
],
|
907
|
+
league_filter,
|
905
908
|
)
|
906
909
|
|
907
910
|
@classmethod
|
@@ -915,3 +918,7 @@ class NBACombinedLeagueModel(CombinedLeagueModel):
|
|
915
918
|
@classmethod
|
916
919
|
def player_identity_map(cls) -> dict[str, str]:
|
917
920
|
return NBA_PLAYER_IDENTITY_MAP
|
921
|
+
|
922
|
+
@classmethod
|
923
|
+
def name(cls) -> str:
|
924
|
+
return "nba-combined-league-model"
|