sportsball 0.3.29__tar.gz → 0.3.30__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.29/sportsball.egg-info → sportsball-0.3.30}/PKG-INFO +1 -1
- {sportsball-0.3.29 → sportsball-0.3.30}/setup.py +1 -1
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/__init__.py +1 -1
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/afltables/afl_afltables_league_model.py +3 -1
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/combined/afl_combined_league_model.py +18 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/google/google_address_model.py +9 -0
- sportsball-0.3.30/sportsball/data/oddsportal/decrypt.py +98 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/oddsportal/oddsportal_game_model.py +7 -38
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/oddsportal/oddsportal_league_model.py +48 -64
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/oddsportal/oddsportal_team_model.py +7 -71
- {sportsball-0.3.29 → sportsball-0.3.30/sportsball.egg-info}/PKG-INFO +1 -1
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball.egg-info/SOURCES.txt +1 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/LICENSE +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/MANIFEST.in +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/README.md +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/requirements.txt +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/setup.cfg +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/__main__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/args.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/cache.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/address_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/afltables/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/afltables/afl_afltables_game_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/afltables/afl_afltables_player_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/afltables/afl_afltables_team_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/afltables/afl_afltables_venue_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/aussportsbetting/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/aussportsbetting/afl_aussportsbetting_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/combined/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/espn/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/espn/afl_espn_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/oddsportal/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/oddsportal/afl_oddsportal_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/aussportsbetting/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/aussportsbetting/aussportsbetting_bookie_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/aussportsbetting/aussportsbetting_game_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/aussportsbetting/aussportsbetting_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/aussportsbetting/aussportsbetting_odds_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/aussportsbetting/aussportsbetting_team_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/aussportsbetting/aussportsbetting_venue_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/bookie_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/combined/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/combined/combined_address_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/combined/combined_game_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/combined/combined_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/combined/combined_player_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/combined/combined_team_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/combined/combined_venue_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/combined/combined_weather_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/espn/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/espn/espn_bookie_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/espn/espn_game_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/espn/espn_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/espn/espn_odds_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/espn/espn_player_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/espn/espn_team_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/espn/espn_venue_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/field_type.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/game_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/google/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/google/google_news_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/league.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/combined/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/combined/nba_combined_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/espn/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/espn/nba_espn_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/nba/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/nba/nba_nba_game_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/nba/nba_nba_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/nba/nba_nba_player_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/nba/nba_nba_team_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/oddsportal/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/oddsportal/nba_oddsportal_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/sportsdb/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/sportsdb/nba_sportsdb_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/sportsreference/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nba/sportsreference/nba_sportsreference_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaab/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaab/combined/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaab/combined/ncaab_combined_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaab/espn/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaab/espn/ncaab_espn_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaab/oddsportal/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaab/oddsportal/ncaab_oddsportal_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaab/sportsreference/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaab/sportsreference/ncaab_sportsreference_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaaf/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaaf/combined/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaaf/combined/ncaaf_combined_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaaf/espn/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaaf/espn/ncaaf_espn_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaaf/oddsportal/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/ncaaf/oddsportal/ncaaf_oddsportal_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/news_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nfl/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nfl/aussportsbetting/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nfl/aussportsbetting/nfl_aussportsbetting_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nfl/combined/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nfl/combined/nfl_combined_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nfl/espn/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nfl/espn/nfl_espn_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nfl/oddsportal/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nfl/oddsportal/nfl_oddsportal_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nfl/sportsdb/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/nfl/sportsdb/nfl_sportsdb_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/odds_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/oddsportal/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/oddsportal/oddsportal_bookie_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/oddsportal/oddsportal_odds_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/oddsportal/oddsportal_venue_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/player_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/season_type.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/social_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/sportsdb/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/sportsdb/sportsdb_game_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/sportsdb/sportsdb_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/sportsdb/sportsdb_team_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/sportsdb/sportsdb_venue_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/sportsreference/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/sportsreference/sportsreference_game_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/sportsreference/sportsreference_league_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/sportsreference/sportsreference_player_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/sportsreference/sportsreference_team_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/sportsreference/sportsreference_venue_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/team_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/venue_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/weather/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/weather/gribstream/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/weather/gribstream/gribstream_weather_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/weather/multi_weather_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/weather/openmeteo/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/weather/openmeteo/openmeteo_weather_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/weather_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/wikipedia/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/wikipedia/wikipedia_venue_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/x/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/x/x_social_model.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/logger.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/loglevel.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/proxy_session.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/session.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/sportsball.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/vendor/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball/vendor/pygooglenews/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball.egg-info/dependency_links.txt +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball.egg-info/entry_points.txt +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball.egg-info/not-zip-safe +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball.egg-info/requires.txt +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/sportsball.egg-info/top_level.txt +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/afl/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/afl/afltables/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/afl/afltables/afl_afltables_league_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/afl/afltables/afl_afltables_player_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/aussportsbetting/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/aussportsbetting/aussportsbetting_game_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/combined/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/combined/combined_game_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/combined/combined_player_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/espn/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/espn/espn_game_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/espn/espn_player_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/game_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/google/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/google/google_address_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/google/google_news_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/nba/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/nba/nba/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/nba/nba/nba_nba_game_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/nba/nba/nba_nba_league_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/nba/nba/nba_nba_player_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/nba/nba/nba_nba_team_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/nba/sportsdb/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/nba/sportsdb/nba_sportsdb_league_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/nba/sportsreference/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/nba/sportsreference/nba_sportsreference_league_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/ncaab/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/ncaab/sportsreference/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/ncaab/sportsreference/ncaab_sportsreference_league_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/nfl/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/nfl/sportsdb/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/nfl/sportsdb/nfl_sportsdb_league_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/oddsportal/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/oddsportal/oddsportal_game_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/player_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/social_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/sportsdb/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/sportsdb/sportsdb_game_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/sportsdb/sportsdb_league_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/sportsdb/sportsdb_team_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/sportsdb/sportsdb_venue_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/sportsreference/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/sportsreference/sportsreference_game_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/sportsreference/sportsreference_league_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/sportsreference/sportsreference_player_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/sportsreference/sportsreference_team_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/sportsreference/sportsreference_venue_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/team_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/x/__init__.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/data/x/x_social_model_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/proxy_session_test.py +0 -0
- {sportsball-0.3.29 → sportsball-0.3.30}/tests/sportsball_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.30',
|
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',
|
{sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/afltables/afl_afltables_league_model.py
RENAMED
@@ -145,7 +145,9 @@ class AFLAFLTablesLeagueModel(LeagueModel):
|
|
145
145
|
|
146
146
|
@property
|
147
147
|
def games(self) -> Iterator[GameModel]:
|
148
|
-
|
148
|
+
with self.session.cache_disabled():
|
149
|
+
response = self.session.get(_SEASON_URL)
|
150
|
+
response.raise_for_status()
|
149
151
|
soup = BeautifulSoup(response.text, "html.parser")
|
150
152
|
with tqdm.tqdm(position=self.position) as pbar:
|
151
153
|
for table in soup.find_all("table"):
|
{sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/combined/afl_combined_league_model.py
RENAMED
@@ -71,6 +71,22 @@ AFL_TEAM_IDENTITY_MAP = {
|
|
71
71
|
"North Melbourne": KANGAROOS,
|
72
72
|
"Melbourne": MELBOURNE,
|
73
73
|
"Collingwood": COLLINGWOOD,
|
74
|
+
# OddsPortal
|
75
|
+
"Collingwood Magpies": COLLINGWOOD,
|
76
|
+
"Port Adelaide Power": PORT_ADELAIDE,
|
77
|
+
"Richmond Tigers": RICHMOND,
|
78
|
+
"Carlton Blues": CARLTON,
|
79
|
+
"Hawthorn Hawks": HAWTHORN,
|
80
|
+
"Essendon Bombers": ESSENDON,
|
81
|
+
"Sydney Swans": SWANS,
|
82
|
+
"Adelaide Crows": ADELAIDE,
|
83
|
+
"St Kilda Saints": STKILDA,
|
84
|
+
"Brisbane Lions": BRISBANE_LIONS,
|
85
|
+
"Melbourne Demons": MELBOURNE,
|
86
|
+
"Geelong Cats": GEELONG,
|
87
|
+
"Fremantle Dockers": FREMANTLE,
|
88
|
+
"West Coast Eagles": WESTCOAST,
|
89
|
+
"Gold Coast Suns": GOLDCOAST,
|
74
90
|
}
|
75
91
|
BRUNSWICK_ST = "brunswick_st"
|
76
92
|
VICTORIA_PARK = "victoria_park"
|
@@ -199,6 +215,8 @@ AFL_VENUE_IDENTITY_MAP = {
|
|
199
215
|
"Westpac Stadium": WELLINGTON,
|
200
216
|
"AAMI Stadium": FOOTBALL_PARK,
|
201
217
|
"Blacktown Park": BLACKTOWN,
|
218
|
+
# OddsPortal
|
219
|
+
"Melbourne Cricket Ground": MCG,
|
202
220
|
}
|
203
221
|
|
204
222
|
|
@@ -7825,6 +7825,15 @@ _CACHED_GEOCODES: dict[str, Any] = {
|
|
7825
7825
|
housenumber="35",
|
7826
7826
|
country="USA",
|
7827
7827
|
),
|
7828
|
+
"Corpus Christi, Texas": SportsballGeocodeTuple(
|
7829
|
+
city="Corpus Christi",
|
7830
|
+
state="TX",
|
7831
|
+
postal="",
|
7832
|
+
lat=27.742778,
|
7833
|
+
lng=-97.401944,
|
7834
|
+
housenumber="",
|
7835
|
+
country="USA",
|
7836
|
+
),
|
7828
7837
|
}
|
7829
7838
|
|
7830
7839
|
|
@@ -0,0 +1,98 @@
|
|
1
|
+
"""A function for decrypting an odds portal dat file."""
|
2
|
+
|
3
|
+
# pylint: disable=too-many-locals
|
4
|
+
import base64
|
5
|
+
import json
|
6
|
+
import urllib.parse
|
7
|
+
from typing import Any
|
8
|
+
|
9
|
+
import requests_cache
|
10
|
+
from bs4 import BeautifulSoup
|
11
|
+
from cryptography.hazmat.backends import default_backend
|
12
|
+
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
13
|
+
from cryptography.hazmat.primitives.hashes import SHA256
|
14
|
+
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
15
|
+
|
16
|
+
from ...proxy_session import X_NO_WAYBACK
|
17
|
+
|
18
|
+
|
19
|
+
def _find_decryption_data(
|
20
|
+
session: requests_cache.CachedSession,
|
21
|
+
soup: BeautifulSoup,
|
22
|
+
referer_url: str,
|
23
|
+
user_agent: str | None = None,
|
24
|
+
) -> tuple[bytes, bytes]:
|
25
|
+
salt: bytes | None = None
|
26
|
+
password: bytes | None = None
|
27
|
+
for script in soup.find_all("script"):
|
28
|
+
src = script.get("src")
|
29
|
+
if src is None:
|
30
|
+
continue
|
31
|
+
if "/app.js" in src:
|
32
|
+
src_url = urllib.parse.urljoin(referer_url, src)
|
33
|
+
headers = {X_NO_WAYBACK: "1"}
|
34
|
+
if user_agent is not None:
|
35
|
+
headers["User-Agent"] = user_agent
|
36
|
+
src_response = session.get(src_url, headers=headers)
|
37
|
+
src_response.raise_for_status()
|
38
|
+
variables = src_response.text
|
39
|
+
sentinel = 'break}return e.next=9,g(r.data,"'
|
40
|
+
variables = variables[variables.find(sentinel) + len(sentinel) :]
|
41
|
+
variables = variables[
|
42
|
+
: variables.find('");case 9:return s=e.sent,l=JSON.parse(s),e.abrupt')
|
43
|
+
]
|
44
|
+
password_str, salt_str = variables.split('","')
|
45
|
+
salt = str.encode(salt_str)
|
46
|
+
password = str.encode(password_str)
|
47
|
+
break
|
48
|
+
if salt is None:
|
49
|
+
raise ValueError("salt is null.")
|
50
|
+
if password is None:
|
51
|
+
raise ValueError("password is null.")
|
52
|
+
return salt, password
|
53
|
+
|
54
|
+
|
55
|
+
def fetch_data(
|
56
|
+
url: str,
|
57
|
+
session: requests_cache.CachedSession,
|
58
|
+
referer_url: str,
|
59
|
+
soup: BeautifulSoup,
|
60
|
+
user_agent: str | None = None,
|
61
|
+
) -> dict[str, Any]:
|
62
|
+
"""Fetch the data from the URL and decrypt it."""
|
63
|
+
salt, password = _find_decryption_data(
|
64
|
+
session, soup, referer_url, user_agent=user_agent
|
65
|
+
)
|
66
|
+
headers = {
|
67
|
+
"X-Requested-With": "XMLHttpRequest",
|
68
|
+
"Referer": referer_url,
|
69
|
+
}
|
70
|
+
if user_agent is not None:
|
71
|
+
headers["User-Agent"] = user_agent
|
72
|
+
response = session.get(
|
73
|
+
url,
|
74
|
+
headers=headers,
|
75
|
+
)
|
76
|
+
response.raise_for_status()
|
77
|
+
decoded_data = base64.b64decode(response.content).decode()
|
78
|
+
encrypted, key = decoded_data.split(":")
|
79
|
+
encrypted_bytes = base64.urlsafe_b64decode(encrypted)
|
80
|
+
key_bytes = bytes.fromhex(key)
|
81
|
+
kdf = PBKDF2HMAC(
|
82
|
+
algorithm=SHA256(),
|
83
|
+
length=32,
|
84
|
+
salt=salt,
|
85
|
+
iterations=1000,
|
86
|
+
backend=default_backend(),
|
87
|
+
)
|
88
|
+
aes_key = kdf.derive(password)
|
89
|
+
cipher = Cipher(
|
90
|
+
algorithms.AES(aes_key), modes.CBC(key_bytes), backend=default_backend()
|
91
|
+
)
|
92
|
+
decryptor = cipher.decryptor()
|
93
|
+
decrypted_bytes = decryptor.update(encrypted_bytes) + decryptor.finalize()
|
94
|
+
decrypted_data = decrypted_bytes.decode("utf-8")
|
95
|
+
end_of_json = decrypted_data.rfind("}")
|
96
|
+
if end_of_json != -1:
|
97
|
+
decrypted_data = decrypted_data[: end_of_json + 1]
|
98
|
+
return json.loads(decrypted_data)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
"""OddsPortal game model."""
|
2
2
|
|
3
|
-
# pylint: disable=too-many-locals,too-many-statements
|
3
|
+
# pylint: disable=too-many-locals,too-many-statements,line-too-long
|
4
4
|
import datetime
|
5
5
|
import json
|
6
6
|
import urllib.parse
|
@@ -13,6 +13,7 @@ from ...cache import MEMORY
|
|
13
13
|
from ...proxy_session import X_NO_WAYBACK
|
14
14
|
from ..game_model import GameModel
|
15
15
|
from ..league import League
|
16
|
+
from .decrypt import fetch_data
|
16
17
|
from .oddsportal_team_model import create_oddsportal_team_model
|
17
18
|
from .oddsportal_venue_model import create_oddsportal_venue_model
|
18
19
|
|
@@ -49,31 +50,6 @@ def _create_oddsportal_game_model(
|
|
49
50
|
default_scope_id = str(event_data["defaultScopeId"])
|
50
51
|
xhash = urllib.parse.unquote(event_data["xhash"])
|
51
52
|
|
52
|
-
salt: bytes | None = None
|
53
|
-
password: bytes | None = None
|
54
|
-
for script in soup.find_all("script"):
|
55
|
-
src = script.get("src")
|
56
|
-
if src is None:
|
57
|
-
continue
|
58
|
-
if "/app.js" in src:
|
59
|
-
src_url = urllib.parse.urljoin(url, src)
|
60
|
-
src_response = session.get(src_url, headers={X_NO_WAYBACK: "1"})
|
61
|
-
src_response.raise_for_status()
|
62
|
-
variables = src_response.text
|
63
|
-
sentinel = 'break}return e.next=9,g(r.data,"'
|
64
|
-
variables = variables[variables.find(sentinel) + len(sentinel) :]
|
65
|
-
variables = variables[
|
66
|
-
: variables.find('");case 9:return s=e.sent,l=JSON.parse(s),e.abrupt')
|
67
|
-
]
|
68
|
-
password_str, salt_str = variables.split('","')
|
69
|
-
salt = str.encode(salt_str)
|
70
|
-
password = str.encode(password_str)
|
71
|
-
break
|
72
|
-
if salt is None:
|
73
|
-
raise ValueError("salt is null.")
|
74
|
-
if password is None:
|
75
|
-
raise ValueError("password is null.")
|
76
|
-
|
77
53
|
bookie_names = event_body["providersNames"]
|
78
54
|
home_points = None
|
79
55
|
if event_body["homeResult"] != "":
|
@@ -96,6 +72,9 @@ def _create_oddsportal_game_model(
|
|
96
72
|
event_body["venueCountry"],
|
97
73
|
)
|
98
74
|
|
75
|
+
url = f"https://www.oddsportal.com/match-event/{version_id}-{sport_id}-{unique_id}-{default_bet_id}-{default_scope_id}-{xhash}.dat"
|
76
|
+
parsed_data = fetch_data(url, session, url, soup)
|
77
|
+
|
99
78
|
return GameModel(
|
100
79
|
dt=dt,
|
101
80
|
week=None,
|
@@ -108,16 +87,11 @@ def _create_oddsportal_game_model(
|
|
108
87
|
event_data["home"],
|
109
88
|
league,
|
110
89
|
home_points,
|
111
|
-
version_id,
|
112
|
-
sport_id,
|
113
|
-
unique_id,
|
114
90
|
default_bet_id,
|
115
91
|
default_scope_id,
|
116
|
-
xhash,
|
117
|
-
salt,
|
118
|
-
password,
|
119
92
|
bookie_names,
|
120
93
|
0,
|
94
|
+
parsed_data,
|
121
95
|
),
|
122
96
|
create_oddsportal_team_model(
|
123
97
|
session,
|
@@ -125,16 +99,11 @@ def _create_oddsportal_game_model(
|
|
125
99
|
event_data["away"],
|
126
100
|
league,
|
127
101
|
away_points,
|
128
|
-
version_id,
|
129
|
-
sport_id,
|
130
|
-
unique_id,
|
131
102
|
default_bet_id,
|
132
103
|
default_scope_id,
|
133
|
-
xhash,
|
134
|
-
salt,
|
135
|
-
password,
|
136
104
|
bookie_names,
|
137
105
|
1,
|
106
|
+
parsed_data,
|
138
107
|
),
|
139
108
|
],
|
140
109
|
end_dt=end_dt,
|
{sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/oddsportal/oddsportal_league_model.py
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
"""Odds Portal league model."""
|
2
2
|
|
3
|
-
# pylint: disable=too-many-locals,too-many-branches,too-many-statements,protected-access
|
3
|
+
# pylint: disable=too-many-locals,too-many-branches,too-many-statements,protected-access,too-many-arguments,line-too-long
|
4
4
|
import http
|
5
5
|
import json
|
6
6
|
import logging
|
@@ -9,12 +9,14 @@ from typing import Iterator
|
|
9
9
|
|
10
10
|
import extruct # type: ignore
|
11
11
|
import requests
|
12
|
+
import requests_cache
|
12
13
|
import tqdm
|
13
|
-
from bs4 import BeautifulSoup
|
14
|
+
from bs4 import BeautifulSoup
|
14
15
|
|
15
16
|
from ..game_model import GameModel
|
16
17
|
from ..league import League
|
17
18
|
from ..league_model import LeagueModel
|
19
|
+
from .decrypt import fetch_data
|
18
20
|
from .oddsportal_game_model import create_oddsportal_game_model
|
19
21
|
|
20
22
|
# Sports
|
@@ -28,6 +30,40 @@ USA = "usa"
|
|
28
30
|
NCAA = "ncaa"
|
29
31
|
|
30
32
|
|
33
|
+
def _process_results_pages(
|
34
|
+
url: str,
|
35
|
+
session: requests_cache.CachedSession,
|
36
|
+
soup: BeautifulSoup,
|
37
|
+
league: League,
|
38
|
+
pbar: tqdm.tqdm,
|
39
|
+
response: requests.Response,
|
40
|
+
) -> Iterator[GameModel]:
|
41
|
+
# Fetch first page
|
42
|
+
sanitised_text = response.text[response.text.find("var pageOutrightsVar = '") :]
|
43
|
+
sanitised_text = sanitised_text[: sanitised_text.find("'")]
|
44
|
+
page_outrights = json.loads(sanitised_text)
|
45
|
+
sports_id = page_outrights["sid"]
|
46
|
+
oddsportal_id = page_outrights["id"]
|
47
|
+
|
48
|
+
current_page = 1
|
49
|
+
total_pages = None
|
50
|
+
while (current_page == 1 and total_pages is None) or (
|
51
|
+
current_page <= 0 if total_pages is None else total_pages
|
52
|
+
):
|
53
|
+
dat_url = f"https://www.oddsportal.com/ajax-sport-country-tournament-archive_/{sports_id}/{oddsportal_id}/X134529032X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X512X32X0X0X0X0X0X0X131072X0X2048/1/-5/page/{current_page}//"
|
54
|
+
parsed_data = fetch_data(dat_url, session, url, soup)
|
55
|
+
d = parsed_data["d"]
|
56
|
+
for row in d["rows"]:
|
57
|
+
game_model = create_oddsportal_game_model(
|
58
|
+
session, urllib.parse.urljoin(url, row["url"]), league, False
|
59
|
+
)
|
60
|
+
pbar.update(1)
|
61
|
+
pbar.set_description(f"OddsPortal {game_model.dt}")
|
62
|
+
yield game_model
|
63
|
+
total_pages = d["pagination"]["pages"]
|
64
|
+
current_page += 1
|
65
|
+
|
66
|
+
|
31
67
|
class OddsPortalLeagueModel(LeagueModel):
|
32
68
|
"""Odds Portal implementation of the league model."""
|
33
69
|
|
@@ -92,7 +128,7 @@ class OddsPortalLeagueModel(LeagueModel):
|
|
92
128
|
response = self.session.get(url)
|
93
129
|
response.raise_for_status()
|
94
130
|
|
95
|
-
soup = BeautifulSoup(response.text, "
|
131
|
+
soup = BeautifulSoup(response.text, "xml")
|
96
132
|
|
97
133
|
# Find next URLs
|
98
134
|
for option in soup.find_all("option"):
|
@@ -100,69 +136,17 @@ class OddsPortalLeagueModel(LeagueModel):
|
|
100
136
|
if next_url.endswith("/results/") and self._path[:-1] in next_url:
|
101
137
|
queued_urls.add(next_url)
|
102
138
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
component = matches.get(
|
112
|
-
"tournamentGamesComponent", matches.get("d")
|
113
|
-
)
|
114
|
-
if component.get("total") != 0:
|
115
|
-
game_urls = {
|
116
|
-
urllib.parse.urljoin(url, x["url"])
|
117
|
-
for x in component.get("rows", [])
|
118
|
-
}
|
119
|
-
if not game_urls:
|
120
|
-
for a in soup.find_all("a", href=True):
|
121
|
-
game_url = urllib.parse.urljoin(url, a.get("href"))
|
122
|
-
if (
|
123
|
-
game_url.endswith("results/")
|
124
|
-
or game_url.endswith("standings/")
|
125
|
-
or game_url.endswith(self._path)
|
126
|
-
or game_url.endswith("outrights/")
|
127
|
-
):
|
128
|
-
continue
|
129
|
-
if self._path[:-1] in game_url:
|
130
|
-
game_urls.add(game_url)
|
131
|
-
|
132
|
-
for game_url in game_urls:
|
133
|
-
if "#" in game_url:
|
134
|
-
continue
|
135
|
-
if (
|
136
|
-
game_url.replace("results/", "") == url
|
137
|
-
or game_url.replace("results/", "") in queued_urls
|
138
|
-
):
|
139
|
-
continue
|
140
|
-
if game_url.endswith("/archive/"):
|
141
|
-
continue
|
142
|
-
if len(game_url.split("/")) != 8:
|
143
|
-
continue
|
144
|
-
game_model = create_oddsportal_game_model(
|
145
|
-
self.session,
|
146
|
-
game_url,
|
147
|
-
self.league,
|
148
|
-
False,
|
149
|
-
)
|
150
|
-
pbar.update(1)
|
151
|
-
pbar.set_description(f"OddsPortal {game_model.dt}")
|
152
|
-
yield game_model
|
153
|
-
|
154
|
-
next_a = soup.find("a", text="Next", href=True)
|
155
|
-
if next_a is None:
|
156
|
-
break
|
157
|
-
if not isinstance(next_a, Tag):
|
158
|
-
raise ValueError("next_a is not a tag.")
|
159
|
-
next_url = urllib.parse.urljoin(url, str(next_a.get("href")))
|
160
|
-
response = self.session.get(next_url)
|
161
|
-
response.raise_for_status()
|
162
|
-
soup = BeautifulSoup(response.text, "html.parser")
|
139
|
+
yield from _process_results_pages(
|
140
|
+
url,
|
141
|
+
self.session,
|
142
|
+
soup,
|
143
|
+
self.league,
|
144
|
+
pbar,
|
145
|
+
response,
|
146
|
+
)
|
163
147
|
|
164
148
|
@property
|
165
149
|
def games(self) -> Iterator[GameModel]:
|
166
150
|
with tqdm.tqdm(position=self.position) as pbar:
|
167
|
-
|
151
|
+
yield from self._find_next(pbar)
|
168
152
|
yield from self._find_previous(pbar)
|
@@ -1,16 +1,11 @@
|
|
1
1
|
"""Odds Portal team model."""
|
2
2
|
|
3
3
|
# pylint: disable=too-many-arguments,duplicate-code,line-too-long,too-many-locals
|
4
|
-
import base64
|
5
4
|
import datetime
|
6
|
-
import
|
5
|
+
from typing import Any
|
7
6
|
|
8
7
|
import pytest_is_running
|
9
8
|
import requests_cache
|
10
|
-
from cryptography.hazmat.backends import default_backend
|
11
|
-
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
12
|
-
from cryptography.hazmat.primitives.hashes import SHA256
|
13
|
-
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
14
9
|
|
15
10
|
from ...cache import MEMORY
|
16
11
|
from ..google.google_news_model import create_google_news_models
|
@@ -26,46 +21,12 @@ def _create_oddsportal_team_model(
|
|
26
21
|
team_name: str,
|
27
22
|
league: League,
|
28
23
|
points: float | None,
|
29
|
-
version_id: str,
|
30
|
-
sport_id: str,
|
31
|
-
unique_id: str,
|
32
24
|
default_bet_id: str,
|
33
25
|
default_scope_id: str,
|
34
|
-
xhash: str,
|
35
|
-
salt: bytes,
|
36
|
-
password: bytes,
|
37
26
|
bookie_names: dict[str, str],
|
38
27
|
team_idx: int,
|
28
|
+
parsed_data: dict[str, Any],
|
39
29
|
) -> TeamModel:
|
40
|
-
response = session.get(
|
41
|
-
f"https://www.oddsportal.com/match-event/{version_id}-{sport_id}-{unique_id}-{default_bet_id}-{default_scope_id}-{xhash}.dat",
|
42
|
-
headers={
|
43
|
-
"X-Requested-With": "XMLHttpRequest",
|
44
|
-
},
|
45
|
-
)
|
46
|
-
response.raise_for_status()
|
47
|
-
decoded_data = base64.b64decode(response.content).decode()
|
48
|
-
encrypted, key = decoded_data.split(":")
|
49
|
-
encrypted_bytes = base64.urlsafe_b64decode(encrypted)
|
50
|
-
key_bytes = bytes.fromhex(key)
|
51
|
-
kdf = PBKDF2HMAC(
|
52
|
-
algorithm=SHA256(),
|
53
|
-
length=32,
|
54
|
-
salt=salt,
|
55
|
-
iterations=1000,
|
56
|
-
backend=default_backend(),
|
57
|
-
)
|
58
|
-
aes_key = kdf.derive(password)
|
59
|
-
cipher = Cipher(
|
60
|
-
algorithms.AES(aes_key), modes.CBC(key_bytes), backend=default_backend()
|
61
|
-
)
|
62
|
-
decryptor = cipher.decryptor()
|
63
|
-
decrypted_bytes = decryptor.update(encrypted_bytes) + decryptor.finalize()
|
64
|
-
decrypted_data = decrypted_bytes.decode("utf-8")
|
65
|
-
end_of_json = decrypted_data.rfind("}")
|
66
|
-
if end_of_json != -1:
|
67
|
-
decrypted_data = decrypted_data[: end_of_json + 1]
|
68
|
-
parsed_data = json.loads(decrypted_data)
|
69
30
|
try:
|
70
31
|
odds_data = parsed_data["d"]["oddsdata"]["back"][
|
71
32
|
f"E-{default_bet_id}-{default_scope_id}-0-0-0"
|
@@ -111,16 +72,11 @@ def _cached_create_oddsportal_team_model(
|
|
111
72
|
team_name: str,
|
112
73
|
league: League,
|
113
74
|
points: float | None,
|
114
|
-
version_id: str,
|
115
|
-
sport_id: str,
|
116
|
-
unique_id: str,
|
117
75
|
default_bet_id: str,
|
118
76
|
default_scope_id: str,
|
119
|
-
xhash: str,
|
120
|
-
salt: bytes,
|
121
|
-
password: bytes,
|
122
77
|
bookie_names: dict[str, str],
|
123
78
|
team_idx: int,
|
79
|
+
parsed_data: dict[str, Any],
|
124
80
|
) -> TeamModel:
|
125
81
|
return _create_oddsportal_team_model(
|
126
82
|
session,
|
@@ -128,16 +84,11 @@ def _cached_create_oddsportal_team_model(
|
|
128
84
|
team_name,
|
129
85
|
league,
|
130
86
|
points,
|
131
|
-
version_id,
|
132
|
-
sport_id,
|
133
|
-
unique_id,
|
134
87
|
default_bet_id,
|
135
88
|
default_scope_id,
|
136
|
-
xhash,
|
137
|
-
salt,
|
138
|
-
password,
|
139
89
|
bookie_names,
|
140
90
|
team_idx,
|
91
|
+
parsed_data,
|
141
92
|
)
|
142
93
|
|
143
94
|
|
@@ -147,16 +98,11 @@ def create_oddsportal_team_model(
|
|
147
98
|
team_name: str,
|
148
99
|
league: League,
|
149
100
|
points: float | None,
|
150
|
-
version_id: str,
|
151
|
-
sport_id: str,
|
152
|
-
unique_id: str,
|
153
101
|
default_bet_id: str,
|
154
102
|
default_scope_id: str,
|
155
|
-
xhash: str,
|
156
|
-
salt: bytes,
|
157
|
-
password: bytes,
|
158
103
|
bookie_names: dict[str, str],
|
159
104
|
team_idx: int,
|
105
|
+
parsed_data: dict[str, Any],
|
160
106
|
) -> TeamModel:
|
161
107
|
"""Create a team model based off the odds portal response."""
|
162
108
|
if not pytest_is_running.is_running() and dt < datetime.datetime.now().replace(
|
@@ -168,16 +114,11 @@ def create_oddsportal_team_model(
|
|
168
114
|
team_name,
|
169
115
|
league,
|
170
116
|
points,
|
171
|
-
version_id,
|
172
|
-
sport_id,
|
173
|
-
unique_id,
|
174
117
|
default_bet_id,
|
175
118
|
default_scope_id,
|
176
|
-
xhash,
|
177
|
-
salt,
|
178
|
-
password,
|
179
119
|
bookie_names,
|
180
120
|
team_idx,
|
121
|
+
parsed_data,
|
181
122
|
)
|
182
123
|
with session.cache_disabled():
|
183
124
|
return _create_oddsportal_team_model(
|
@@ -186,14 +127,9 @@ def create_oddsportal_team_model(
|
|
186
127
|
team_name,
|
187
128
|
league,
|
188
129
|
points,
|
189
|
-
version_id,
|
190
|
-
sport_id,
|
191
|
-
unique_id,
|
192
130
|
default_bet_id,
|
193
131
|
default_scope_id,
|
194
|
-
xhash,
|
195
|
-
salt,
|
196
|
-
password,
|
197
132
|
bookie_names,
|
198
133
|
team_idx,
|
134
|
+
parsed_data,
|
199
135
|
)
|
@@ -120,6 +120,7 @@ sportsball/data/nfl/oddsportal/nfl_oddsportal_league_model.py
|
|
120
120
|
sportsball/data/nfl/sportsdb/__init__.py
|
121
121
|
sportsball/data/nfl/sportsdb/nfl_sportsdb_league_model.py
|
122
122
|
sportsball/data/oddsportal/__init__.py
|
123
|
+
sportsball/data/oddsportal/decrypt.py
|
123
124
|
sportsball/data/oddsportal/oddsportal_bookie_model.py
|
124
125
|
sportsball/data/oddsportal/oddsportal_game_model.py
|
125
126
|
sportsball/data/oddsportal/oddsportal_league_model.py
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/afltables/afl_afltables_game_model.py
RENAMED
File without changes
|
{sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/afltables/afl_afltables_player_model.py
RENAMED
File without changes
|
{sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/afltables/afl_afltables_team_model.py
RENAMED
File without changes
|
{sportsball-0.3.29 → sportsball-0.3.30}/sportsball/data/afl/afltables/afl_afltables_venue_model.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|