sportsball 0.3.18__tar.gz → 0.3.21__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.18/sportsball.egg-info → sportsball-0.3.21}/PKG-INFO +10 -1
- {sportsball-0.3.18 → sportsball-0.3.21}/README.md +6 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/requirements.txt +3 -1
- {sportsball-0.3.18 → sportsball-0.3.21}/setup.py +9 -6
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/__init__.py +1 -1
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/combined/afl_combined_league_model.py +2 -0
- sportsball-0.3.21/sportsball/data/afl/oddsportal/afl_oddsportal_league_model.py +15 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/aussportsbetting/aussportsbetting_odds_model.py +1 -1
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/espn/espn_odds_model.py +1 -1
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/google/google_address_model.py +105 -54
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/google/google_news_model.py +1 -1
- sportsball-0.3.21/sportsball/data/nba/oddsportal/nba_oddsportal_league_model.py +15 -0
- sportsball-0.3.21/sportsball/data/ncaab/oddsportal/ncaab_oddsportal_league_model.py +15 -0
- sportsball-0.3.21/sportsball/data/nfl/oddsportal/nfl_oddsportal_league_model.py +15 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/odds_model.py +9 -0
- sportsball-0.3.21/sportsball/data/oddsportal/oddsportal_bookie_model.py +10 -0
- sportsball-0.3.21/sportsball/data/oddsportal/oddsportal_game_model.py +148 -0
- sportsball-0.3.21/sportsball/data/oddsportal/oddsportal_league_model.py +98 -0
- sportsball-0.3.21/sportsball/data/oddsportal/oddsportal_odds_model.py +16 -0
- sportsball-0.3.21/sportsball/data/oddsportal/oddsportal_team_model.py +189 -0
- sportsball-0.3.21/sportsball/data/oddsportal/oddsportal_venue_model.py +59 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/sportsreference/sportsreference_game_model.py +132 -29
- sportsball-0.3.21/sportsball/vendor/pygooglenews/__init__.py +203 -0
- {sportsball-0.3.18 → sportsball-0.3.21/sportsball.egg-info}/PKG-INFO +10 -1
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball.egg-info/SOURCES.txt +17 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball.egg-info/requires.txt +3 -0
- sportsball-0.3.21/tests/data/ncaab/sportsreference/__init__.py +0 -0
- sportsball-0.3.21/tests/data/nfl/__init__.py +0 -0
- sportsball-0.3.21/tests/data/nfl/sportsdb/__init__.py +0 -0
- sportsball-0.3.21/tests/data/sportsdb/__init__.py +0 -0
- sportsball-0.3.21/tests/data/sportsreference/__init__.py +0 -0
- sportsball-0.3.21/tests/data/sportsreference/sportsreference_game_model_test.py +97 -0
- sportsball-0.3.21/tests/data/x/__init__.py +0 -0
- sportsball-0.3.18/tests/data/sportsreference/sportsreference_game_model_test.py +0 -30
- {sportsball-0.3.18 → sportsball-0.3.21}/LICENSE +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/MANIFEST.in +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/setup.cfg +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/__main__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/args.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/cache.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/address_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/afltables/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/afltables/afl_afltables_game_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/afltables/afl_afltables_league_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/afltables/afl_afltables_player_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/afltables/afl_afltables_team_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/afltables/afl_afltables_venue_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/aussportsbetting/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/aussportsbetting/afl_aussportsbetting_league_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/combined/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/espn/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/espn/afl_espn_league_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/aussportsbetting → sportsball-0.3.21/sportsball/data/afl/oddsportal}/__init__.py +0 -0
- {sportsball-0.3.18/sportsball/data/combined → sportsball-0.3.21/sportsball/data/aussportsbetting}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/aussportsbetting/aussportsbetting_bookie_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/aussportsbetting/aussportsbetting_game_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/aussportsbetting/aussportsbetting_league_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/aussportsbetting/aussportsbetting_team_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/aussportsbetting/aussportsbetting_venue_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/bookie_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/espn → sportsball-0.3.21/sportsball/data/combined}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/combined/combined_address_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/combined/combined_game_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/combined/combined_league_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/combined/combined_player_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/combined/combined_team_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/combined/combined_venue_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/combined/combined_weather_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/google → sportsball-0.3.21/sportsball/data/espn}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/espn/espn_bookie_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/espn/espn_game_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/espn/espn_league_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/espn/espn_player_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/espn/espn_team_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/espn/espn_venue_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/field_type.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/game_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/nba/combined → sportsball-0.3.21/sportsball/data/google}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/league.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/league_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nba/__init__.py +0 -0
- {sportsball-0.3.18/sportsball/data/nba/espn → sportsball-0.3.21/sportsball/data/nba/combined}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nba/combined/nba_combined_league_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/nba/nba → sportsball-0.3.21/sportsball/data/nba/espn}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nba/espn/nba_espn_league_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/nba/sportsdb → sportsball-0.3.21/sportsball/data/nba/nba}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nba/nba/nba_nba_game_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nba/nba/nba_nba_league_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nba/nba/nba_nba_player_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nba/nba/nba_nba_team_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/nba/sportsreference → sportsball-0.3.21/sportsball/data/nba/oddsportal}/__init__.py +0 -0
- {sportsball-0.3.18/sportsball/data/ncaab/combined → sportsball-0.3.21/sportsball/data/nba/sportsdb}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nba/sportsdb/nba_sportsdb_league_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/ncaab/espn → sportsball-0.3.21/sportsball/data/nba/sportsreference}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nba/sportsreference/nba_sportsreference_league_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/ncaab/__init__.py +0 -0
- {sportsball-0.3.18/sportsball/data/ncaab/sportsreference → sportsball-0.3.21/sportsball/data/ncaab/combined}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/ncaab/combined/ncaab_combined_league_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/ncaaf → sportsball-0.3.21/sportsball/data/ncaab}/espn/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/ncaab/espn/ncaab_espn_league_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/nfl/aussportsbetting → sportsball-0.3.21/sportsball/data/ncaab/oddsportal}/__init__.py +0 -0
- {sportsball-0.3.18/sportsball/data/nfl/combined → sportsball-0.3.21/sportsball/data/ncaab/sportsreference}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/ncaab/sportsreference/ncaab_sportsreference_league_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/ncaaf/__init__.py +0 -0
- {sportsball-0.3.18/sportsball/data/nfl/sportsdb → sportsball-0.3.21/sportsball/data/ncaaf/espn}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/ncaaf/espn/ncaaf_espn_league_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/news_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nfl/__init__.py +0 -0
- {sportsball-0.3.18/sportsball/data/sportsdb → sportsball-0.3.21/sportsball/data/nfl/aussportsbetting}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nfl/aussportsbetting/nfl_aussportsbetting_league_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/sportsreference → sportsball-0.3.21/sportsball/data/nfl/combined}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nfl/combined/nfl_combined_league_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nfl/espn/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nfl/espn/nfl_espn_league_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/weather → sportsball-0.3.21/sportsball/data/nfl/oddsportal}/__init__.py +0 -0
- {sportsball-0.3.18/sportsball/data/weather/gribstream → sportsball-0.3.21/sportsball/data/nfl/sportsdb}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/nfl/sportsdb/nfl_sportsdb_league_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/weather/openmeteo → sportsball-0.3.21/sportsball/data/oddsportal}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/player_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/season_type.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/social_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/wikipedia → sportsball-0.3.21/sportsball/data/sportsdb}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/sportsdb/sportsdb_game_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/sportsdb/sportsdb_league_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/sportsdb/sportsdb_team_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/sportsdb/sportsdb_venue_model.py +0 -0
- {sportsball-0.3.18/sportsball/data/x → sportsball-0.3.21/sportsball/data/sportsreference}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/sportsreference/sportsreference_league_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/sportsreference/sportsreference_player_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/sportsreference/sportsreference_team_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/sportsreference/sportsreference_venue_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/team_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/venue_model.py +0 -0
- {sportsball-0.3.18/tests → sportsball-0.3.21/sportsball/data/weather}/__init__.py +0 -0
- {sportsball-0.3.18/tests/data → sportsball-0.3.21/sportsball/data/weather/gribstream}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/weather/gribstream/gribstream_weather_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/weather/multi_weather_model.py +0 -0
- {sportsball-0.3.18/tests/data/afl → sportsball-0.3.21/sportsball/data/weather/openmeteo}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/weather/openmeteo/openmeteo_weather_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/weather_model.py +0 -0
- {sportsball-0.3.18/tests/data/afl/afltables → sportsball-0.3.21/sportsball/data/wikipedia}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/wikipedia/wikipedia_venue_model.py +0 -0
- {sportsball-0.3.18/tests/data/aussportsbetting → sportsball-0.3.21/sportsball/data/x}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/x/x_social_model.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/logger.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/loglevel.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/proxy_session.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/session.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball/sportsball.py +0 -0
- {sportsball-0.3.18/tests/data/combined → sportsball-0.3.21/sportsball/vendor}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball.egg-info/dependency_links.txt +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball.egg-info/entry_points.txt +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball.egg-info/not-zip-safe +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/sportsball.egg-info/top_level.txt +0 -0
- {sportsball-0.3.18/tests/data/espn → sportsball-0.3.21/tests}/__init__.py +0 -0
- {sportsball-0.3.18/tests/data/google → sportsball-0.3.21/tests/data}/__init__.py +0 -0
- {sportsball-0.3.18/tests/data/nba → sportsball-0.3.21/tests/data/afl}/__init__.py +0 -0
- {sportsball-0.3.18/tests/data/nba/nba → sportsball-0.3.21/tests/data/afl/afltables}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/afl/afltables/afl_afltables_player_model_test.py +0 -0
- {sportsball-0.3.18/tests/data/nba/sportsdb → sportsball-0.3.21/tests/data/aussportsbetting}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/aussportsbetting/aussportsbetting_game_model_test.py +0 -0
- {sportsball-0.3.18/tests/data/nba/sportsreference → sportsball-0.3.21/tests/data/combined}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/combined/combined_game_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/combined/combined_player_model_test.py +0 -0
- {sportsball-0.3.18/tests/data/ncaab → sportsball-0.3.21/tests/data/espn}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/espn/espn_game_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/espn/espn_player_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/game_model_test.py +0 -0
- {sportsball-0.3.18/tests/data/ncaab/sportsreference → sportsball-0.3.21/tests/data/google}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/google/google_address_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/google/google_news_model_test.py +0 -0
- {sportsball-0.3.18/tests/data/nfl → sportsball-0.3.21/tests/data/nba}/__init__.py +0 -0
- {sportsball-0.3.18/tests/data/nfl/sportsdb → sportsball-0.3.21/tests/data/nba/nba}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/nba/nba/nba_nba_game_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/nba/nba/nba_nba_league_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/nba/nba/nba_nba_player_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/nba/nba/nba_nba_team_model_test.py +0 -0
- {sportsball-0.3.18/tests/data → sportsball-0.3.21/tests/data/nba}/sportsdb/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/nba/sportsdb/nba_sportsdb_league_model_test.py +0 -0
- {sportsball-0.3.18/tests/data → sportsball-0.3.21/tests/data/nba}/sportsreference/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/nba/sportsreference/nba_sportsreference_league_model_test.py +0 -0
- {sportsball-0.3.18/tests/data/x → sportsball-0.3.21/tests/data/ncaab}/__init__.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/ncaab/sportsreference/ncaab_sportsreference_league_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/nfl/sportsdb/nfl_sportsdb_league_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/player_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/social_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/sportsdb/sportsdb_game_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/sportsdb/sportsdb_league_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/sportsdb/sportsdb_team_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/sportsdb/sportsdb_venue_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/sportsreference/sportsreference_league_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/sportsreference/sportsreference_player_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/sportsreference/sportsreference_team_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/sportsreference/sportsreference_venue_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/team_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/data/x/x_social_model_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/proxy_session_test.py +0 -0
- {sportsball-0.3.18 → sportsball-0.3.21}/tests/sportsball_test.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: sportsball
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.21
|
4
4
|
Summary: A library for pulling in and normalising sports stats.
|
5
5
|
Home-page: https://github.com/8W9aG/sportsball
|
6
6
|
Author: Will Sackfield
|
@@ -40,6 +40,9 @@ Requires-Dist: func-timeout>=4.3.5
|
|
40
40
|
Requires-Dist: tenacity>=9.0.0
|
41
41
|
Requires-Dist: random_user_agent>=1.0.1
|
42
42
|
Requires-Dist: wayback>=0.4.5
|
43
|
+
Requires-Dist: cryptography>=44.0.0
|
44
|
+
Requires-Dist: feedparser>=6.0.11
|
45
|
+
Requires-Dist: dateparser>=1.2.0
|
43
46
|
Dynamic: author
|
44
47
|
Dynamic: author-email
|
45
48
|
Dynamic: classifier
|
@@ -95,6 +98,9 @@ Python 3.11.6:
|
|
95
98
|
- [tenacity](https://github.com/jd/tenacity)
|
96
99
|
- [random_user_agent](https://github.com/Luqman-Ud-Din/random_user_agent)
|
97
100
|
- [wayback](https://github.com/edgi-govdata-archiving/wayback)
|
101
|
+
- [cryptography](https://cryptography.io/en/latest/)
|
102
|
+
- [feedparser](https://github.com/kurtmckee/feedparser)
|
103
|
+
- [dateparser](https://dateparser.readthedocs.io/en/latest/)
|
98
104
|
|
99
105
|
## Raison D'être :thought_balloon:
|
100
106
|
|
@@ -165,6 +171,7 @@ A representation of a team within a game.
|
|
165
171
|
* **field_goals_attempted**: The sum of the field goals attempted by the team in the game.
|
166
172
|
* **offensive_rebounds**: The number of rebounds during offense by the team in the game.
|
167
173
|
* **assists**: The number of times the player on the team made a pass that resulted in a field goal in the game.
|
174
|
+
* **turnovers**: The number of times a player on the team loses possession of the ball in the game.
|
168
175
|
|
169
176
|
#### Player
|
170
177
|
|
@@ -179,6 +186,7 @@ A representation of a player within a team within a game.
|
|
179
186
|
* **field_goals_attempted**: The number of field goal attempts the player made in the game.
|
180
187
|
* **offensive_rebounds**: The number of rebounds during offense by the player made in the game.
|
181
188
|
* **assists**: The number of times the player made a pass that resulted in a field goal in the game.
|
189
|
+
* **turnovers**: The number of times a player loses possession of the ball in the game.
|
182
190
|
|
183
191
|
#### Odds
|
184
192
|
|
@@ -186,6 +194,7 @@ A representation of the odds for a team to win within a game.
|
|
186
194
|
|
187
195
|
* **odds**: The decimal odds offered by a bookie for the team to win in the game.
|
188
196
|
* **bookie**: The bookie offering these odds.
|
197
|
+
* **dt**: When the odds were posted.
|
189
198
|
|
190
199
|
#### Venue
|
191
200
|
|
@@ -42,6 +42,9 @@ Python 3.11.6:
|
|
42
42
|
- [tenacity](https://github.com/jd/tenacity)
|
43
43
|
- [random_user_agent](https://github.com/Luqman-Ud-Din/random_user_agent)
|
44
44
|
- [wayback](https://github.com/edgi-govdata-archiving/wayback)
|
45
|
+
- [cryptography](https://cryptography.io/en/latest/)
|
46
|
+
- [feedparser](https://github.com/kurtmckee/feedparser)
|
47
|
+
- [dateparser](https://dateparser.readthedocs.io/en/latest/)
|
45
48
|
|
46
49
|
## Raison D'être :thought_balloon:
|
47
50
|
|
@@ -112,6 +115,7 @@ A representation of a team within a game.
|
|
112
115
|
* **field_goals_attempted**: The sum of the field goals attempted by the team in the game.
|
113
116
|
* **offensive_rebounds**: The number of rebounds during offense by the team in the game.
|
114
117
|
* **assists**: The number of times the player on the team made a pass that resulted in a field goal in the game.
|
118
|
+
* **turnovers**: The number of times a player on the team loses possession of the ball in the game.
|
115
119
|
|
116
120
|
#### Player
|
117
121
|
|
@@ -126,6 +130,7 @@ A representation of a player within a team within a game.
|
|
126
130
|
* **field_goals_attempted**: The number of field goal attempts the player made in the game.
|
127
131
|
* **offensive_rebounds**: The number of rebounds during offense by the player made in the game.
|
128
132
|
* **assists**: The number of times the player made a pass that resulted in a field goal in the game.
|
133
|
+
* **turnovers**: The number of times a player loses possession of the ball in the game.
|
129
134
|
|
130
135
|
#### Odds
|
131
136
|
|
@@ -133,6 +138,7 @@ A representation of the odds for a team to win within a game.
|
|
133
138
|
|
134
139
|
* **odds**: The decimal odds offered by a bookie for the team to win in the game.
|
135
140
|
* **bookie**: The bookie offering these odds.
|
141
|
+
* **dt**: When the odds were posted.
|
136
142
|
|
137
143
|
#### Venue
|
138
144
|
|
@@ -18,7 +18,6 @@ nba_api>=1.7.0
|
|
18
18
|
timezonefinder>=6.5.7
|
19
19
|
pydantic>=2.10.4
|
20
20
|
flatten_json>=0.1.14
|
21
|
-
-e git+https://github.com/8W9aG/pygooglenews@d40ad6f01cb661bbb1c4b4022896f93c83c88364#egg=pygooglenews
|
22
21
|
extruct>=0.18.0
|
23
22
|
wikipedia-api>=0.8.1
|
24
23
|
tweepy>=4.15.0
|
@@ -28,3 +27,6 @@ func-timeout>=4.3.5
|
|
28
27
|
tenacity>=9.0.0
|
29
28
|
random_user_agent>=1.0.1
|
30
29
|
wayback>=0.4.5
|
30
|
+
cryptography>=44.0.0
|
31
|
+
feedparser>=6.0.11
|
32
|
+
dateparser>=1.2.0
|
@@ -13,17 +13,20 @@ def install_requires() -> typing.List[str]:
|
|
13
13
|
with open(
|
14
14
|
Path(__file__).absolute().parent.joinpath('requirements.txt'), "r"
|
15
15
|
) as requirments_txt_handle:
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
for require in requirments_txt_handle:
|
17
|
+
if not require.startswith(".") and not require.startswith("-e"):
|
18
|
+
requires.append(require)
|
19
|
+
else:
|
20
|
+
require_file = require.split()[-1]
|
21
|
+
require_file = require_file.replace("git+", "")
|
22
|
+
package_name = require_file.split("#egg=")[-1]
|
23
|
+
requires.append(package_name + " @ " + require_file)
|
21
24
|
return requires
|
22
25
|
|
23
26
|
|
24
27
|
setup(
|
25
28
|
name='sportsball',
|
26
|
-
version='0.3.
|
29
|
+
version='0.3.21',
|
27
30
|
description='A library for pulling in and normalising sports stats.',
|
28
31
|
long_description=long_description,
|
29
32
|
long_description_content_type='text/markdown',
|
{sportsball-0.3.18 → sportsball-0.3.21}/sportsball/data/afl/combined/afl_combined_league_model.py
RENAMED
@@ -8,6 +8,7 @@ from ..afltables.afl_afltables_league_model import AFLAFLTablesLeagueModel
|
|
8
8
|
from ..aussportsbetting.afl_aussportsbetting_league_model import \
|
9
9
|
AFLAusSportsBettingLeagueModel
|
10
10
|
from ..espn.afl_espn_league_model import AFLESPNLeagueModel
|
11
|
+
from ..oddsportal.afl_oddsportal_league_model import AFLOddsPortalLeagueModel
|
11
12
|
|
12
13
|
FITZROY = "fitzroy_idx"
|
13
14
|
CARLTON = "carlton_idx"
|
@@ -212,6 +213,7 @@ class AFLCombinedLeagueModel(CombinedLeagueModel):
|
|
212
213
|
AFLAFLTablesLeagueModel(session),
|
213
214
|
AFLESPNLeagueModel(session),
|
214
215
|
AFLAusSportsBettingLeagueModel(session),
|
216
|
+
AFLOddsPortalLeagueModel(session),
|
215
217
|
],
|
216
218
|
)
|
217
219
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
"""AFL OddsPortal league model."""
|
2
|
+
|
3
|
+
# pylint: disable=line-too-long
|
4
|
+
|
5
|
+
import requests_cache
|
6
|
+
|
7
|
+
from ...league import League
|
8
|
+
from ...oddsportal.oddsportal_league_model import OddsPortalLeagueModel
|
9
|
+
|
10
|
+
|
11
|
+
class AFLOddsPortalLeagueModel(OddsPortalLeagueModel):
|
12
|
+
"""AFL OddsPortal implementation of the league model."""
|
13
|
+
|
14
|
+
def __init__(self, session: requests_cache.CachedSession) -> None:
|
15
|
+
super().__init__(League.AFL, session)
|
@@ -9,4 +9,4 @@ from .aussportsbetting_bookie_model import create_aussportsbetting_bookie_model
|
|
9
9
|
def create_aussportsbetting_odds_model(odds: float) -> OddsModel:
|
10
10
|
"""Create an odds model based off aus sports betting."""
|
11
11
|
bookie = create_aussportsbetting_bookie_model()
|
12
|
-
return OddsModel(odds=odds, bookie=bookie) # pyright: ignore
|
12
|
+
return OddsModel(odds=odds, bookie=bookie, dt=None) # pyright: ignore
|
@@ -18,4 +18,4 @@ def create_espn_odds_model(odds: dict[str, Any], bookie: BookieModel) -> OddsMod
|
|
18
18
|
odds_val = (float(moneyline) / 100.0) + 1.0
|
19
19
|
elif moneyline < 0:
|
20
20
|
odds_val = (100.0 / float(abs(moneyline))) + 1.0
|
21
|
-
return OddsModel(odds=odds_val, bookie=bookie)
|
21
|
+
return OddsModel(odds=odds_val, bookie=bookie, dt=None)
|
@@ -1054,6 +1054,60 @@ DUNN_OLIVER_ACADOME = SportsballGeocodeTuple(
|
|
1054
1054
|
housenumber="",
|
1055
1055
|
country="USA",
|
1056
1056
|
)
|
1057
|
+
OAKLAND_ARENA = SportsballGeocodeTuple(
|
1058
|
+
city="Oakland",
|
1059
|
+
state="CA",
|
1060
|
+
postal="",
|
1061
|
+
lat=37.750278,
|
1062
|
+
lng=-122.203056,
|
1063
|
+
housenumber="7000",
|
1064
|
+
country="USA",
|
1065
|
+
)
|
1066
|
+
SCOTIABANK_ARENA = SportsballGeocodeTuple(
|
1067
|
+
city="Toronto",
|
1068
|
+
state="ON",
|
1069
|
+
postal="",
|
1070
|
+
lat=43.643333,
|
1071
|
+
lng=-79.379167,
|
1072
|
+
housenumber="40",
|
1073
|
+
country="Canada",
|
1074
|
+
)
|
1075
|
+
BRADLEY_CENTER = SportsballGeocodeTuple(
|
1076
|
+
city="Milwaukee",
|
1077
|
+
state="WI",
|
1078
|
+
postal="",
|
1079
|
+
lat=43.043611,
|
1080
|
+
lng=-87.916944,
|
1081
|
+
housenumber="1001",
|
1082
|
+
country="USA",
|
1083
|
+
)
|
1084
|
+
THE_PIT = SportsballGeocodeTuple(
|
1085
|
+
city="Albuquerque",
|
1086
|
+
state="NM",
|
1087
|
+
postal="",
|
1088
|
+
lat=35.067,
|
1089
|
+
lng=-106.632,
|
1090
|
+
housenumber="",
|
1091
|
+
country="USA",
|
1092
|
+
)
|
1093
|
+
JOHN_GLASER_ARENA = SportsballGeocodeTuple(
|
1094
|
+
city="Philadelphia",
|
1095
|
+
state="PA",
|
1096
|
+
postal="19141",
|
1097
|
+
lat=40.039993,
|
1098
|
+
lng=-75.15654,
|
1099
|
+
housenumber="15",
|
1100
|
+
country="USA",
|
1101
|
+
)
|
1102
|
+
TEXAS_AM_COMMERCE_FIELD_HOUSE = SportsballGeocodeTuple(
|
1103
|
+
city="Commerce",
|
1104
|
+
state="TX",
|
1105
|
+
postal="75428",
|
1106
|
+
lat=33.245337,
|
1107
|
+
lng=-95.907619,
|
1108
|
+
housenumber="2600",
|
1109
|
+
country="USA",
|
1110
|
+
)
|
1057
1111
|
_CACHED_GEOCODES: dict[str, Any] = {
|
1058
1112
|
"S.C.G. - Australia": SCG,
|
1059
1113
|
"Victoria Park - Australia": SportsballGeocodeTuple(
|
@@ -3077,15 +3131,7 @@ _CACHED_GEOCODES: dict[str, Any] = {
|
|
3077
3131
|
housenumber="2650",
|
3078
3132
|
country="USA",
|
3079
3133
|
),
|
3080
|
-
"The Pit, Albuquerque, New Mexico":
|
3081
|
-
city="Albuquerque",
|
3082
|
-
state="NM",
|
3083
|
-
postal="",
|
3084
|
-
lat=35.067,
|
3085
|
-
lng=-106.632,
|
3086
|
-
housenumber="",
|
3087
|
-
country="USA",
|
3088
|
-
),
|
3134
|
+
"The Pit, Albuquerque, New Mexico": THE_PIT,
|
3089
3135
|
"Gill Coliseum, Corvallis, Oregon": SportsballGeocodeTuple(
|
3090
3136
|
city="Corvallis",
|
3091
3137
|
state="OR",
|
@@ -3681,15 +3727,7 @@ _CACHED_GEOCODES: dict[str, Any] = {
|
|
3681
3727
|
housenumber="1801",
|
3682
3728
|
country="USA",
|
3683
3729
|
),
|
3684
|
-
"John Glaser Arena, Philadelphia, Pennsylvania":
|
3685
|
-
city="Philadelphia",
|
3686
|
-
state="PA",
|
3687
|
-
postal="19141",
|
3688
|
-
lat=40.039993,
|
3689
|
-
lng=-75.15654,
|
3690
|
-
housenumber="15",
|
3691
|
-
country="USA",
|
3692
|
-
),
|
3730
|
+
"John Glaser Arena, Philadelphia, Pennsylvania": JOHN_GLASER_ARENA,
|
3693
3731
|
"University Center, Hammond, Louisiana": SportsballGeocodeTuple(
|
3694
3732
|
city="Hammond",
|
3695
3733
|
state="LA",
|
@@ -5908,15 +5946,7 @@ _CACHED_GEOCODES: dict[str, Any] = {
|
|
5908
5946
|
housenumber="",
|
5909
5947
|
country="USA",
|
5910
5948
|
),
|
5911
|
-
"Texas A&MâCommerce Field House, Commerce, Texas":
|
5912
|
-
city="Commerce",
|
5913
|
-
state="TX",
|
5914
|
-
postal="75428",
|
5915
|
-
lat=33.245337,
|
5916
|
-
lng=-95.907619,
|
5917
|
-
housenumber="2600",
|
5918
|
-
country="USA",
|
5919
|
-
),
|
5949
|
+
"Texas A&MâCommerce Field House, Commerce, Texas": TEXAS_AM_COMMERCE_FIELD_HOUSE,
|
5920
5950
|
"William J. Nicks Building, Prairie View, Texas": SportsballGeocodeTuple(
|
5921
5951
|
city="Prairie View",
|
5922
5952
|
state="TX",
|
@@ -6546,15 +6576,7 @@ _CACHED_GEOCODES: dict[str, Any] = {
|
|
6546
6576
|
"American Airlines Arena": AMERICAN_AIRLINES_ARENA,
|
6547
6577
|
"Chesapeake Energy Arena - Oklahoma City, Oklahoma - United States": CHESAPEAKE_ENERGY_ARENA,
|
6548
6578
|
"AT&T Center - San Antonio, Texas - United States": ATT_CENTER,
|
6549
|
-
"Oakland Arena - Oakland, California - United States":
|
6550
|
-
city="Oakland",
|
6551
|
-
state="CA",
|
6552
|
-
postal="",
|
6553
|
-
lat=37.750278,
|
6554
|
-
lng=-122.203056,
|
6555
|
-
housenumber="7000",
|
6556
|
-
country="USA",
|
6557
|
-
),
|
6579
|
+
"Oakland Arena - Oakland, California - United States": OAKLAND_ARENA,
|
6558
6580
|
"ESPN Wide World of Sports Complex": ESPN_WIDE_WORLD_OF_SPORTS_COMPLEX,
|
6559
6581
|
"International Amphitheatre": SportsballGeocodeTuple(
|
6560
6582
|
city="Chicago",
|
@@ -6773,15 +6795,7 @@ _CACHED_GEOCODES: dict[str, Any] = {
|
|
6773
6795
|
housenumber="1255",
|
6774
6796
|
country="USA",
|
6775
6797
|
),
|
6776
|
-
"Bradley Center":
|
6777
|
-
city="Milwaukee",
|
6778
|
-
state="WI",
|
6779
|
-
postal="",
|
6780
|
-
lat=43.043611,
|
6781
|
-
lng=-87.916944,
|
6782
|
-
housenumber="1001",
|
6783
|
-
country="USA",
|
6784
|
-
),
|
6798
|
+
"Bradley Center": BRADLEY_CENTER,
|
6785
6799
|
"Charlotte Coliseum": SportsballGeocodeTuple(
|
6786
6800
|
city="Charlotte",
|
6787
6801
|
state="NC",
|
@@ -6961,15 +6975,7 @@ _CACHED_GEOCODES: dict[str, Any] = {
|
|
6961
6975
|
),
|
6962
6976
|
"Golden 1 Center, Sacramento, California": GOLDEN_1_CENTER,
|
6963
6977
|
"Kaseya Center, Miami, Florida": KASEYA_CENTER,
|
6964
|
-
"Scotiabank Arena, Toronto, Canada":
|
6965
|
-
city="Toronto",
|
6966
|
-
state="ON",
|
6967
|
-
postal="",
|
6968
|
-
lat=43.643333,
|
6969
|
-
lng=-79.379167,
|
6970
|
-
housenumber="40",
|
6971
|
-
country="Canada",
|
6972
|
-
),
|
6978
|
+
"Scotiabank Arena, Toronto, Canada": SCOTIABANK_ARENA,
|
6973
6979
|
"Smoothie King Center, New Orleans, Louisiana": CAESARS_SUPERDOME,
|
6974
6980
|
"TD Garden, Boston, Massachusetts": TD_GARDEN,
|
6975
6981
|
"Frost Bank Center, San Antonio, Texas": SportsballGeocodeTuple(
|
@@ -7024,6 +7030,51 @@ _CACHED_GEOCODES: dict[str, Any] = {
|
|
7024
7030
|
"Pepsi Center, Denver, Colorado": PEPSI_CENTRE,
|
7025
7031
|
"Visa Athletic Center, Bay Lake, Florida": ESPN_WIDE_WORLD_OF_SPORTS_COMPLEX,
|
7026
7032
|
"Dunn–Oliver Acadome, Montgomery, Alabama": DUNN_OLIVER_ACADOME,
|
7033
|
+
"Talking Stick Resort Arena, Phoenix, Arizona": AMERICA_WEST_ARENA,
|
7034
|
+
"Oracle Arena, Oakland, California": OAKLAND_ARENA,
|
7035
|
+
"The O2 Arena, London, United Kingdom": SportsballGeocodeTuple(
|
7036
|
+
city="London",
|
7037
|
+
state="",
|
7038
|
+
postal="SE10",
|
7039
|
+
lat=51.5029,
|
7040
|
+
lng=0.0032,
|
7041
|
+
housenumber="",
|
7042
|
+
country="UK",
|
7043
|
+
),
|
7044
|
+
"Air Canada Centre, Toronto, Canada": SCOTIABANK_ARENA,
|
7045
|
+
"BMO Harris Bradley Center, Milwaukee, Wisconsin": BRADLEY_CENTER,
|
7046
|
+
"Philips Arena, Atlanta, Georgia": STATE_FARM_ARENA,
|
7047
|
+
"UW–Milwaukee Panther Arena, Milwaukee, Wisconsin": MILWAUKEE_ARENA,
|
7048
|
+
"Dreamstyle Arena, Albuquerque, New Mexico": THE_PIT,
|
7049
|
+
"Tom Gola Arena, Philadelphia, Pennsylvania": JOHN_GLASER_ARENA,
|
7050
|
+
"Texas A&M–Commerce Field House, Commerce, Texas": TEXAS_AM_COMMERCE_FIELD_HOUSE,
|
7051
|
+
"Detroit, Michigan": SportsballGeocodeTuple(
|
7052
|
+
city="Detroit",
|
7053
|
+
state="MI",
|
7054
|
+
postal="",
|
7055
|
+
lat=42.333333,
|
7056
|
+
lng=-83.05,
|
7057
|
+
housenumber="",
|
7058
|
+
country="USA",
|
7059
|
+
),
|
7060
|
+
"Rec Hall, University Park, Pennsylvania": SportsballGeocodeTuple(
|
7061
|
+
city="University Park",
|
7062
|
+
state="PA",
|
7063
|
+
postal="16802",
|
7064
|
+
lat=40.79578,
|
7065
|
+
lng=-77.869399,
|
7066
|
+
housenumber="",
|
7067
|
+
country="USA",
|
7068
|
+
),
|
7069
|
+
"Dallas, Texas": SportsballGeocodeTuple(
|
7070
|
+
city="Dallas",
|
7071
|
+
state="TX",
|
7072
|
+
postal="",
|
7073
|
+
lat=32.779167,
|
7074
|
+
lng=-96.808889,
|
7075
|
+
housenumber="",
|
7076
|
+
country="USA",
|
7077
|
+
),
|
7027
7078
|
}
|
7028
7079
|
|
7029
7080
|
|
@@ -7,9 +7,9 @@ import pytest_is_running
|
|
7
7
|
import requests_cache
|
8
8
|
from bs4 import BeautifulSoup
|
9
9
|
from dateutil import parser
|
10
|
-
from pygooglenews import GoogleNews # type: ignore
|
11
10
|
|
12
11
|
from ...cache import MEMORY
|
12
|
+
from ...vendor.pygooglenews import GoogleNews # type: ignore
|
13
13
|
from ..league import League, long_name
|
14
14
|
from ..news_model import NewsModel
|
15
15
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
"""NBA OddsPortal league model."""
|
2
|
+
|
3
|
+
# pylint: disable=line-too-long
|
4
|
+
|
5
|
+
import requests_cache
|
6
|
+
|
7
|
+
from ...league import League
|
8
|
+
from ...oddsportal.oddsportal_league_model import OddsPortalLeagueModel
|
9
|
+
|
10
|
+
|
11
|
+
class NBAOddsPortalLeagueModel(OddsPortalLeagueModel):
|
12
|
+
"""NBA OddsPortal implementation of the league model."""
|
13
|
+
|
14
|
+
def __init__(self, session: requests_cache.CachedSession) -> None:
|
15
|
+
super().__init__(League.NBA, session)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
"""NCAAB OddsPortal league model."""
|
2
|
+
|
3
|
+
# pylint: disable=line-too-long
|
4
|
+
|
5
|
+
import requests_cache
|
6
|
+
|
7
|
+
from ...league import League
|
8
|
+
from ...oddsportal.oddsportal_league_model import OddsPortalLeagueModel
|
9
|
+
|
10
|
+
|
11
|
+
class NCAABOddsPortalLeagueModel(OddsPortalLeagueModel):
|
12
|
+
"""NCAAB OddsPortal implementation of the league model."""
|
13
|
+
|
14
|
+
def __init__(self, session: requests_cache.CachedSession) -> None:
|
15
|
+
super().__init__(League.NCAAB, session)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
"""NFL OddsPortal league model."""
|
2
|
+
|
3
|
+
# pylint: disable=line-too-long
|
4
|
+
|
5
|
+
import requests_cache
|
6
|
+
|
7
|
+
from ...league import League
|
8
|
+
from ...oddsportal.oddsportal_league_model import OddsPortalLeagueModel
|
9
|
+
|
10
|
+
|
11
|
+
class NFLOddsPortalLeagueModel(OddsPortalLeagueModel):
|
12
|
+
"""NFL OddsPortal implementation of the league model."""
|
13
|
+
|
14
|
+
def __init__(self, session: requests_cache.CachedSession) -> None:
|
15
|
+
super().__init__(League.NFL, session)
|
@@ -1,13 +1,22 @@
|
|
1
1
|
"""The prototype class for odds."""
|
2
2
|
|
3
|
+
import datetime
|
4
|
+
from typing import Literal
|
5
|
+
|
3
6
|
from pydantic import BaseModel, Field
|
4
7
|
|
5
8
|
from .bookie_model import BookieModel
|
6
9
|
from .field_type import TYPE_KEY, FieldType
|
7
10
|
|
11
|
+
DT_COLUMN: Literal["dt"] = "dt"
|
12
|
+
|
8
13
|
|
9
14
|
class OddsModel(BaseModel):
|
10
15
|
"""The serialisable odds class."""
|
11
16
|
|
12
17
|
odds: float = Field(..., json_schema_extra={TYPE_KEY: FieldType.ODDS})
|
13
18
|
bookie: BookieModel
|
19
|
+
dt: datetime.datetime | None = Field(
|
20
|
+
...,
|
21
|
+
alias=DT_COLUMN,
|
22
|
+
)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
"""OddsPortal bookie model."""
|
2
|
+
|
3
|
+
from ...cache import MEMORY
|
4
|
+
from ..bookie_model import BookieModel
|
5
|
+
|
6
|
+
|
7
|
+
@MEMORY.cache
|
8
|
+
def create_oddsportal_bookie_model(bookie_name: str, bookie_id: str) -> BookieModel:
|
9
|
+
"""Create bookie model from odds portal."""
|
10
|
+
return BookieModel(identifier=bookie_id, name=bookie_name)
|
@@ -0,0 +1,148 @@
|
|
1
|
+
"""OddsPortal game model."""
|
2
|
+
|
3
|
+
# pylint: disable=too-many-locals
|
4
|
+
import datetime
|
5
|
+
import json
|
6
|
+
import urllib.parse
|
7
|
+
|
8
|
+
import pytest_is_running
|
9
|
+
import requests_cache
|
10
|
+
from bs4 import BeautifulSoup, Tag
|
11
|
+
|
12
|
+
from ...cache import MEMORY
|
13
|
+
from ..game_model import GameModel
|
14
|
+
from ..league import League
|
15
|
+
from .oddsportal_team_model import create_oddsportal_team_model
|
16
|
+
from .oddsportal_venue_model import create_oddsportal_venue_model
|
17
|
+
|
18
|
+
|
19
|
+
def _create_oddsportal_game_model(
|
20
|
+
session: requests_cache.CachedSession,
|
21
|
+
url: str,
|
22
|
+
league: League,
|
23
|
+
) -> GameModel:
|
24
|
+
response = session.get(url)
|
25
|
+
response.raise_for_status()
|
26
|
+
|
27
|
+
soup = BeautifulSoup(url, "html.parser")
|
28
|
+
event_tag = soup.find("Event")
|
29
|
+
if not isinstance(event_tag, Tag):
|
30
|
+
raise ValueError("event_tag is not a tag.")
|
31
|
+
event = json.loads(str(event_tag[":data"]))
|
32
|
+
|
33
|
+
event_body = event["eventBody"]
|
34
|
+
event_data = event["eventData"]
|
35
|
+
dt = datetime.datetime.fromtimestamp(event_body["startDate"])
|
36
|
+
end_dt = None
|
37
|
+
if event_data["endDate"] is not False:
|
38
|
+
end_dt = datetime.datetime.fromtimestamp(event_body["endDate"])
|
39
|
+
version_id = str(event_data["versionId"])
|
40
|
+
sport_id = str(event_data["sportId"])
|
41
|
+
unique_id = event_data["id"]
|
42
|
+
default_bet_id = str(event_data["defaultBetId"])
|
43
|
+
default_scope_id = str(event_data["defaultScopeId"])
|
44
|
+
xhash = urllib.parse.unquote(event_data["xhash"])
|
45
|
+
|
46
|
+
salt: bytes | None = None
|
47
|
+
password: bytes | None = None
|
48
|
+
for script in soup.find_all("script"):
|
49
|
+
src = script.get("src")
|
50
|
+
if src is None:
|
51
|
+
continue
|
52
|
+
if "/app.js" in src:
|
53
|
+
src_url = urllib.parse.urljoin(url, src)
|
54
|
+
src_response = session.get(src_url)
|
55
|
+
src_response.raise_for_status()
|
56
|
+
variables = src_response.text
|
57
|
+
variables = variables[variables.find('break}return e.next=9,g(r.data,"') :]
|
58
|
+
variables = variables[
|
59
|
+
: variables.find('");case 9:return s=e.sent,l=JSON.parse(s),e.abrupt')
|
60
|
+
]
|
61
|
+
salt_str, password_str = variables.split('","')
|
62
|
+
salt = str.encode(salt_str)
|
63
|
+
password = str.encode(password_str)
|
64
|
+
break
|
65
|
+
if salt is None:
|
66
|
+
raise ValueError("salt is null.")
|
67
|
+
if password is None:
|
68
|
+
raise ValueError("password is null.")
|
69
|
+
|
70
|
+
bookie_names = event_body["providersNames"]
|
71
|
+
|
72
|
+
return GameModel(
|
73
|
+
dt=dt,
|
74
|
+
week=None,
|
75
|
+
game_number=None,
|
76
|
+
venue=create_oddsportal_venue_model(
|
77
|
+
session,
|
78
|
+
dt,
|
79
|
+
event_body["venue"],
|
80
|
+
event_body["venueTown"],
|
81
|
+
event_body["venueCountry"],
|
82
|
+
),
|
83
|
+
teams=[
|
84
|
+
create_oddsportal_team_model(
|
85
|
+
session,
|
86
|
+
dt,
|
87
|
+
event_data["home"],
|
88
|
+
league,
|
89
|
+
float(event_body["homeResult"]),
|
90
|
+
version_id,
|
91
|
+
sport_id,
|
92
|
+
unique_id,
|
93
|
+
default_bet_id,
|
94
|
+
default_scope_id,
|
95
|
+
xhash,
|
96
|
+
salt,
|
97
|
+
password,
|
98
|
+
bookie_names,
|
99
|
+
0,
|
100
|
+
),
|
101
|
+
create_oddsportal_team_model(
|
102
|
+
session,
|
103
|
+
dt,
|
104
|
+
event_data["away"],
|
105
|
+
league,
|
106
|
+
float(event_body["awayResult"]),
|
107
|
+
version_id,
|
108
|
+
sport_id,
|
109
|
+
unique_id,
|
110
|
+
default_bet_id,
|
111
|
+
default_scope_id,
|
112
|
+
xhash,
|
113
|
+
salt,
|
114
|
+
password,
|
115
|
+
bookie_names,
|
116
|
+
1,
|
117
|
+
),
|
118
|
+
],
|
119
|
+
end_dt=end_dt,
|
120
|
+
attendance=None,
|
121
|
+
league=league,
|
122
|
+
year=dt.year,
|
123
|
+
season_type=None,
|
124
|
+
postponed=event_data["isPostponed"],
|
125
|
+
play_off=None,
|
126
|
+
)
|
127
|
+
|
128
|
+
|
129
|
+
@MEMORY.cache(ignore=["session"])
|
130
|
+
def _cached_create_oddsportal_game_model(
|
131
|
+
session: requests_cache.CachedSession,
|
132
|
+
url: str,
|
133
|
+
league: League,
|
134
|
+
) -> GameModel:
|
135
|
+
return _create_oddsportal_game_model(session, url, league)
|
136
|
+
|
137
|
+
|
138
|
+
def create_oddsportal_game_model(
|
139
|
+
session: requests_cache.CachedSession,
|
140
|
+
url: str,
|
141
|
+
league: League,
|
142
|
+
is_next: bool,
|
143
|
+
) -> GameModel:
|
144
|
+
"""Create a OddsPortal game model."""
|
145
|
+
if not pytest_is_running.is_running() and not is_next:
|
146
|
+
return _cached_create_oddsportal_game_model(session, url, league)
|
147
|
+
with session.cache_disabled():
|
148
|
+
return _create_oddsportal_game_model(session, url, league)
|