sportsball 0.3.55__tar.gz → 0.3.57__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.
Files changed (225) hide show
  1. {sportsball-0.3.55/sportsball.egg-info → sportsball-0.3.57}/PKG-INFO +5 -1
  2. {sportsball-0.3.55 → sportsball-0.3.57}/README.md +2 -0
  3. sportsball-0.3.55/sportsball.egg-info/requires.txt → sportsball-0.3.57/requirements.txt +2 -0
  4. {sportsball-0.3.55 → sportsball-0.3.57}/setup.py +1 -1
  5. sportsball-0.3.57/sportsball/__init__.py +7 -0
  6. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/afl/afl_afl_league_model.py +1 -1
  7. sportsball-0.3.57/sportsball/data/afl/afl/afl_afl_player_model.py +46 -0
  8. sportsball-0.3.57/sportsball/data/afl/afltables/afl_afltables_game_model.py +534 -0
  9. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/afltables/afl_afltables_league_model.py +2 -2
  10. sportsball-0.3.57/sportsball/data/afl/afltables/afl_afltables_player_model.py +234 -0
  11. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/afltables/afl_afltables_team_model.py +128 -8
  12. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/afltables/afl_afltables_venue_model.py +1 -1
  13. sportsball-0.3.57/sportsball/data/combined/combined_player_model.py +176 -0
  14. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/espn/espn_player_model.py +22 -0
  15. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/google/google_address_model.py +37 -0
  16. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/oddsportal/oddsportal_game_model.py +1 -1
  17. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/oddsportal/oddsportal_league_model.py +1 -1
  18. sportsball-0.3.57/sportsball/data/player_model.py +205 -0
  19. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/sportsreference/sportsreference_game_model.py +8 -5
  20. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/sportsreference/sportsreference_league_model.py +1 -1
  21. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/sportsreference/sportsreference_player_model.py +24 -2
  22. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/sportsreference/sportsreference_team_model.py +1 -1
  23. sportsball-0.3.57/sportsball/data/team_model.py +586 -0
  24. sportsball-0.3.57/sportsball/logger.py +41 -0
  25. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/vendor/pygooglenews/__init__.py +1 -1
  26. {sportsball-0.3.55 → sportsball-0.3.57/sportsball.egg-info}/PKG-INFO +5 -1
  27. sportsball-0.3.55/requirements.txt → sportsball-0.3.57/sportsball.egg-info/requires.txt +3 -1
  28. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/afl/afltables/afl_afltables_player_model_test.py +22 -0
  29. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/combined/combined_player_model_test.py +22 -0
  30. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/oddsportal/decrypt_test.py +1 -1
  31. sportsball-0.3.57/tests/data/player_model_test.py +47 -0
  32. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/sportsreference/sportsreference_game_model_test.py +14 -0
  33. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/sportsreference/sportsreference_league_model_test.py +1 -1
  34. sportsball-0.3.55/sportsball/__init__.py +0 -3
  35. sportsball-0.3.55/sportsball/data/afl/afl/afl_afl_player_model.py +0 -24
  36. sportsball-0.3.55/sportsball/data/afl/afltables/afl_afltables_game_model.py +0 -298
  37. sportsball-0.3.55/sportsball/data/afl/afltables/afl_afltables_player_model.py +0 -64
  38. sportsball-0.3.55/sportsball/data/combined/combined_player_model.py +0 -66
  39. sportsball-0.3.55/sportsball/data/player_model.py +0 -69
  40. sportsball-0.3.55/sportsball/data/team_model.py +0 -162
  41. sportsball-0.3.55/sportsball/logger.py +0 -31
  42. sportsball-0.3.55/tests/data/player_model_test.py +0 -25
  43. {sportsball-0.3.55 → sportsball-0.3.57}/LICENSE +0 -0
  44. {sportsball-0.3.55 → sportsball-0.3.57}/MANIFEST.in +0 -0
  45. {sportsball-0.3.55 → sportsball-0.3.57}/setup.cfg +0 -0
  46. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/__main__.py +0 -0
  47. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/args.py +0 -0
  48. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/cache.py +0 -0
  49. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/__init__.py +0 -0
  50. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/address_model.py +0 -0
  51. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/__init__.py +0 -0
  52. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/afl/__init__.py +0 -0
  53. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/afl/afl_afl_game_model.py +0 -0
  54. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/afl/afl_afl_team_model.py +0 -0
  55. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/afl/afl_afl_venue_model.py +0 -0
  56. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/afltables/__init__.py +0 -0
  57. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/aussportsbetting/__init__.py +0 -0
  58. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/aussportsbetting/afl_aussportsbetting_league_model.py +0 -0
  59. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/combined/__init__.py +0 -0
  60. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/combined/afl_combined_league_model.py +0 -0
  61. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/espn/__init__.py +0 -0
  62. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/espn/afl_espn_league_model.py +0 -0
  63. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/oddsportal/__init__.py +0 -0
  64. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/afl/oddsportal/afl_oddsportal_league_model.py +0 -0
  65. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/aussportsbetting/__init__.py +0 -0
  66. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/aussportsbetting/aussportsbetting_bookie_model.py +0 -0
  67. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/aussportsbetting/aussportsbetting_game_model.py +0 -0
  68. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/aussportsbetting/aussportsbetting_league_model.py +0 -0
  69. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/aussportsbetting/aussportsbetting_odds_model.py +0 -0
  70. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/aussportsbetting/aussportsbetting_team_model.py +0 -0
  71. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/aussportsbetting/aussportsbetting_venue_model.py +0 -0
  72. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/bookie_model.py +0 -0
  73. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/combined/__init__.py +0 -0
  74. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/combined/combined_address_model.py +0 -0
  75. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/combined/combined_game_model.py +0 -0
  76. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/combined/combined_league_model.py +0 -0
  77. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/combined/combined_team_model.py +0 -0
  78. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/combined/combined_venue_model.py +0 -0
  79. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/combined/combined_weather_model.py +0 -0
  80. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/espn/__init__.py +0 -0
  81. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/espn/espn_bookie_model.py +0 -0
  82. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/espn/espn_game_model.py +0 -0
  83. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/espn/espn_league_model.py +0 -0
  84. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/espn/espn_odds_model.py +0 -0
  85. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/espn/espn_team_model.py +0 -0
  86. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/espn/espn_venue_model.py +0 -0
  87. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/field_type.py +0 -0
  88. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/game_model.py +0 -0
  89. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/google/__init__.py +0 -0
  90. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/google/google_news_model.py +0 -0
  91. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/league.py +0 -0
  92. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/league_model.py +0 -0
  93. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/model.py +0 -0
  94. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/__init__.py +0 -0
  95. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/combined/__init__.py +0 -0
  96. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/combined/nba_combined_league_model.py +0 -0
  97. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/espn/__init__.py +0 -0
  98. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/espn/nba_espn_league_model.py +0 -0
  99. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/nba/__init__.py +0 -0
  100. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/nba/nba_nba_game_model.py +0 -0
  101. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/nba/nba_nba_league_model.py +0 -0
  102. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/nba/nba_nba_team_model.py +0 -0
  103. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/oddsportal/__init__.py +0 -0
  104. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/oddsportal/nba_oddsportal_league_model.py +0 -0
  105. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/sportsdb/__init__.py +0 -0
  106. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/sportsdb/nba_sportsdb_league_model.py +0 -0
  107. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/sportsreference/__init__.py +0 -0
  108. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nba/sportsreference/nba_sportsreference_league_model.py +0 -0
  109. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaab/__init__.py +0 -0
  110. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaab/combined/__init__.py +0 -0
  111. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaab/combined/ncaab_combined_league_model.py +0 -0
  112. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaab/espn/__init__.py +0 -0
  113. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaab/espn/ncaab_espn_league_model.py +0 -0
  114. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaab/oddsportal/__init__.py +0 -0
  115. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaab/oddsportal/ncaab_oddsportal_league_model.py +0 -0
  116. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaab/sportsreference/__init__.py +0 -0
  117. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaab/sportsreference/ncaab_sportsreference_league_model.py +0 -0
  118. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaaf/__init__.py +0 -0
  119. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaaf/combined/__init__.py +0 -0
  120. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaaf/combined/ncaaf_combined_league_model.py +0 -0
  121. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaaf/espn/__init__.py +0 -0
  122. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaaf/espn/ncaaf_espn_league_model.py +0 -0
  123. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaaf/oddsportal/__init__.py +0 -0
  124. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/ncaaf/oddsportal/ncaaf_oddsportal_league_model.py +0 -0
  125. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/news_model.py +0 -0
  126. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nfl/__init__.py +0 -0
  127. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nfl/aussportsbetting/__init__.py +0 -0
  128. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nfl/aussportsbetting/nfl_aussportsbetting_league_model.py +0 -0
  129. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nfl/combined/__init__.py +0 -0
  130. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nfl/combined/nfl_combined_league_model.py +0 -0
  131. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nfl/espn/__init__.py +0 -0
  132. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nfl/espn/nfl_espn_league_model.py +0 -0
  133. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nfl/oddsportal/__init__.py +0 -0
  134. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nfl/oddsportal/nfl_oddsportal_league_model.py +0 -0
  135. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nfl/sportsdb/__init__.py +0 -0
  136. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/nfl/sportsdb/nfl_sportsdb_league_model.py +0 -0
  137. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/odds_model.py +0 -0
  138. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/oddsportal/__init__.py +0 -0
  139. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/oddsportal/decrypt.py +0 -0
  140. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/oddsportal/oddsportal_bookie_model.py +0 -0
  141. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/oddsportal/oddsportal_odds_model.py +0 -0
  142. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/oddsportal/oddsportal_team_model.py +0 -0
  143. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/oddsportal/oddsportal_venue_model.py +0 -0
  144. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/season_type.py +0 -0
  145. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/social_model.py +0 -0
  146. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/sportsdb/__init__.py +0 -0
  147. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/sportsdb/sportsdb_game_model.py +0 -0
  148. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/sportsdb/sportsdb_league_model.py +0 -0
  149. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/sportsdb/sportsdb_team_model.py +0 -0
  150. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/sportsdb/sportsdb_venue_model.py +0 -0
  151. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/sportsreference/__init__.py +0 -0
  152. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/sportsreference/sportsreference_venue_model.py +0 -0
  153. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/venue_model.py +0 -0
  154. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/weather/__init__.py +0 -0
  155. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/weather/gribstream/__init__.py +0 -0
  156. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/weather/gribstream/gribstream_weather_model.py +0 -0
  157. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/weather/multi_weather_model.py +0 -0
  158. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/weather/openmeteo/__init__.py +0 -0
  159. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/weather/openmeteo/openmeteo_weather_model.py +0 -0
  160. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/weather_model.py +0 -0
  161. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/wikipedia/__init__.py +0 -0
  162. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/wikipedia/wikipedia_venue_model.py +0 -0
  163. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/x/__init__.py +0 -0
  164. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/data/x/x_social_model.py +0 -0
  165. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/loglevel.py +0 -0
  166. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/playwright.py +0 -0
  167. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/proxy_session.py +0 -0
  168. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/session.py +0 -0
  169. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/sportsball.py +0 -0
  170. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball/vendor/__init__.py +0 -0
  171. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball.egg-info/SOURCES.txt +0 -0
  172. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball.egg-info/dependency_links.txt +0 -0
  173. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball.egg-info/entry_points.txt +0 -0
  174. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball.egg-info/not-zip-safe +0 -0
  175. {sportsball-0.3.55 → sportsball-0.3.57}/sportsball.egg-info/top_level.txt +0 -0
  176. {sportsball-0.3.55 → sportsball-0.3.57}/tests/__init__.py +0 -0
  177. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/__init__.py +0 -0
  178. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/afl/__init__.py +0 -0
  179. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/afl/afltables/__init__.py +0 -0
  180. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/afl/afltables/afl_afltables_game_model_test.py +0 -0
  181. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/afl/afltables/afl_afltables_league_model_test.py +0 -0
  182. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/aussportsbetting/__init__.py +0 -0
  183. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/aussportsbetting/aussportsbetting_game_model_test.py +0 -0
  184. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/combined/__init__.py +0 -0
  185. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/combined/combined_game_model_test.py +0 -0
  186. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/espn/__init__.py +0 -0
  187. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/espn/espn_game_model_test.py +0 -0
  188. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/espn/espn_player_model_test.py +0 -0
  189. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/game_model_test.py +0 -0
  190. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/google/__init__.py +0 -0
  191. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/google/google_address_model_test.py +0 -0
  192. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/google/google_news_model_test.py +0 -0
  193. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/nba/__init__.py +0 -0
  194. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/nba/nba/__init__.py +0 -0
  195. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/nba/nba/nba_nba_game_model_test.py +0 -0
  196. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/nba/nba/nba_nba_league_model_test.py +0 -0
  197. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/nba/nba/nba_nba_team_model_test.py +0 -0
  198. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/nba/sportsdb/__init__.py +0 -0
  199. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/nba/sportsdb/nba_sportsdb_league_model_test.py +0 -0
  200. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/nba/sportsreference/__init__.py +0 -0
  201. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/nba/sportsreference/nba_sportsreference_league_model_test.py +0 -0
  202. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/ncaab/__init__.py +0 -0
  203. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/ncaab/sportsreference/__init__.py +0 -0
  204. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/ncaab/sportsreference/ncaab_sportsreference_league_model_test.py +0 -0
  205. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/nfl/__init__.py +0 -0
  206. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/nfl/sportsdb/__init__.py +0 -0
  207. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/nfl/sportsdb/nfl_sportsdb_league_model_test.py +0 -0
  208. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/oddsportal/__init__.py +0 -0
  209. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/oddsportal/oddsportal_game_model_test.py +0 -0
  210. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/oddsportal/oddsportal_league_model_test.py +0 -0
  211. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/social_model_test.py +0 -0
  212. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/sportsdb/__init__.py +0 -0
  213. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/sportsdb/sportsdb_game_model_test.py +0 -0
  214. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/sportsdb/sportsdb_league_model_test.py +0 -0
  215. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/sportsdb/sportsdb_team_model_test.py +0 -0
  216. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/sportsdb/sportsdb_venue_model_test.py +0 -0
  217. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/sportsreference/__init__.py +0 -0
  218. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/sportsreference/sportsreference_player_model_test.py +0 -0
  219. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/sportsreference/sportsreference_team_model_test.py +0 -0
  220. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/sportsreference/sportsreference_venue_model_test.py +0 -0
  221. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/team_model_test.py +0 -0
  222. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/x/__init__.py +0 -0
  223. {sportsball-0.3.55 → sportsball-0.3.57}/tests/data/x/x_social_model_test.py +0 -0
  224. {sportsball-0.3.55 → sportsball-0.3.57}/tests/proxy_session_test.py +0 -0
  225. {sportsball-0.3.55 → sportsball-0.3.57}/tests/sportsball_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: sportsball
3
- Version: 0.3.55
3
+ Version: 0.3.57
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
@@ -44,6 +44,8 @@ Requires-Dist: cryptography>=44.0.0
44
44
  Requires-Dist: feedparser>=6.0.11
45
45
  Requires-Dist: dateparser>=1.2.0
46
46
  Requires-Dist: playwright>=1.51.0
47
+ Requires-Dist: cchardet>=2.2.0a2
48
+ Requires-Dist: lxml>=5.3.0
47
49
  Dynamic: author
48
50
  Dynamic: author-email
49
51
  Dynamic: classifier
@@ -103,6 +105,8 @@ Python 3.11.6:
103
105
  - [feedparser](https://github.com/kurtmckee/feedparser)
104
106
  - [dateparser](https://dateparser.readthedocs.io/en/latest/)
105
107
  - [playwright](https://playwright.dev/)
108
+ - [cchardet](https://github.com/PyYoshi/cChardet)
109
+ - [lxml](https://lxml.de/)
106
110
 
107
111
  ## Raison D'être :thought_balloon:
108
112
 
@@ -46,6 +46,8 @@ Python 3.11.6:
46
46
  - [feedparser](https://github.com/kurtmckee/feedparser)
47
47
  - [dateparser](https://dateparser.readthedocs.io/en/latest/)
48
48
  - [playwright](https://playwright.dev/)
49
+ - [cchardet](https://github.com/PyYoshi/cChardet)
50
+ - [lxml](https://lxml.de/)
49
51
 
50
52
  ## Raison D'être :thought_balloon:
51
53
 
@@ -31,3 +31,5 @@ cryptography>=44.0.0
31
31
  feedparser>=6.0.11
32
32
  dateparser>=1.2.0
33
33
  playwright>=1.51.0
34
+ cchardet>=2.2.0a2
35
+ lxml>=5.3.0
@@ -26,7 +26,7 @@ def install_requires() -> typing.List[str]:
26
26
 
27
27
  setup(
28
28
  name='sportsball',
29
- version='0.3.55',
29
+ version='0.3.57',
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',
@@ -0,0 +1,7 @@
1
+ """The main module for sportsball."""
2
+
3
+ # flake8: noqa
4
+ import cchardet # type: ignore
5
+ import lxml # noqa: ignore
6
+
7
+ __VERSION__ = "0.3.57"
@@ -35,7 +35,7 @@ class AFLAFLLeagueModel(LeagueModel):
35
35
  page.goto(
36
36
  "https://www.afl.com.au/matches/team-lineups", wait_until="networkidle"
37
37
  )
38
- soup = BeautifulSoup(page.content(), "html.parser")
38
+ soup = BeautifulSoup(page.content(), "lxml")
39
39
  for div in soup.find_all(
40
40
  "div", {"class": re.compile(".*js-match-list-item.*")}
41
41
  ):
@@ -0,0 +1,46 @@
1
+ """AFL AFL player model."""
2
+
3
+ from ...player_model import PlayerModel
4
+
5
+
6
+ def create_afl_afl_player_model(
7
+ identifier: str,
8
+ player_number: str,
9
+ name: str,
10
+ ) -> PlayerModel:
11
+ """Create a player model from AFL AFL."""
12
+ return PlayerModel(
13
+ identifier=identifier,
14
+ jersey=player_number,
15
+ kicks=None,
16
+ fumbles=None,
17
+ fumbles_lost=None,
18
+ field_goals=None,
19
+ field_goals_attempted=None,
20
+ offensive_rebounds=None,
21
+ assists=None,
22
+ turnovers=None,
23
+ name=name,
24
+ marks=None,
25
+ handballs=None,
26
+ disposals=None,
27
+ goals=None,
28
+ behinds=None,
29
+ hit_outs=None,
30
+ tackles=None,
31
+ rebounds=None,
32
+ insides=None,
33
+ clearances=None,
34
+ clangers=None,
35
+ free_kicks_for=None,
36
+ free_kicks_against=None,
37
+ brownlow_votes=None,
38
+ contested_possessions=None,
39
+ uncontested_possessions=None,
40
+ contested_marks=None,
41
+ marks_inside=None,
42
+ one_percenters=None,
43
+ bounces=None,
44
+ goal_assists=None,
45
+ percentage_played=None,
46
+ )
@@ -0,0 +1,534 @@
1
+ """AFL AFLTables game model."""
2
+
3
+ # pylint: disable=too-many-arguments,too-many-branches,too-many-statements
4
+ import datetime
5
+ import urllib.parse
6
+ from urllib.parse import urlparse
7
+
8
+ import pytest_is_running
9
+ import requests_cache
10
+ from bs4 import BeautifulSoup, Tag
11
+ from dateutil.parser import parse
12
+
13
+ from ....cache import MEMORY
14
+ from ...game_model import GameModel
15
+ from ...league import League
16
+ from ...season_type import SeasonType
17
+ from .afl_afltables_team_model import create_afl_afltables_team_model
18
+ from .afl_afltables_venue_model import create_afl_afltables_venue_model
19
+
20
+ _FINALS_WEEK_ADDITION_MAP = {
21
+ "Qualifying Final": 1,
22
+ "Elimination Final": 1,
23
+ "Semi Final": 2,
24
+ "Preliminary Final": 3,
25
+ "Grand Final": 4,
26
+ }
27
+
28
+
29
+ def _find_end_dt(
30
+ soup: BeautifulSoup, dt: datetime.datetime
31
+ ) -> datetime.datetime | None:
32
+ end_dt = None
33
+ for b in soup.find_all("b"):
34
+ b_text = b.get_text().strip()
35
+ if "Game time:" in b_text:
36
+ b_text = b_text[b_text.find("Game time:") :]
37
+ b_text = b_text.replace("Game time:", "")
38
+ if ")" in b_text:
39
+ b_text = b_text[: b_text.find(")")]
40
+ b_text = b_text[: b_text.find("s")]
41
+ min_text, sec_text = b_text.split(" ")[-2:]
42
+ end_dt = dt + datetime.timedelta(
43
+ minutes=int(min_text.replace("m", "")),
44
+ seconds=int(sec_text.replace("s", "").replace(")", "")),
45
+ )
46
+ break
47
+ return end_dt
48
+
49
+
50
+ def _find_team_info(tr: Tag, url: str) -> tuple[str, str, int] | None:
51
+ team_url = None
52
+ team_name = None
53
+ team_points = None
54
+ for a in tr.find_all("a", href=True):
55
+ team_url = urllib.parse.urljoin(url, a.get("href"))
56
+ team_name = a.get_text().strip()
57
+ for b in tr.find_all("b"):
58
+ try:
59
+ team_points = int(b.get_text().strip())
60
+ except ValueError:
61
+ pass
62
+ if team_url is None or team_name is None or team_points is None:
63
+ return None
64
+ return team_url, team_name, team_points
65
+
66
+
67
+ def _find_season_metadata(
68
+ soup: BeautifulSoup,
69
+ url: str,
70
+ last_round_number: int,
71
+ ) -> tuple[
72
+ datetime.datetime,
73
+ str,
74
+ int,
75
+ list[tuple[str, str, int]],
76
+ datetime.datetime | None,
77
+ int | None,
78
+ ]:
79
+ # pylint: disable=too-many-locals,too-many-branches
80
+ def _parse_date_text(date_text: str) -> datetime.datetime:
81
+ date_text = td_text[td_text.find("Date:") + 5 :]
82
+ date_text = date_text[: date_text.find("Attendance:")]
83
+ if "(" in date_text:
84
+ date_text = date_text[: date_text.find("(") - 1]
85
+ date_text = date_text.strip()
86
+ return parse(date_text)
87
+
88
+ dt = None
89
+ venue_url = None
90
+ week = None
91
+ team_infos: dict[str, tuple[str, int]] = {}
92
+ attendance = None
93
+ for table in soup.find_all("table"):
94
+ for tr in table.find_all("tr"):
95
+ for td in tr.find_all("td"):
96
+ td_text = td.get_text()
97
+ if "Date:" in td_text:
98
+ dt = _parse_date_text(td_text)
99
+ if "Venue:" in td_text:
100
+ for a in td.find_all("a", href=True):
101
+ venue_url = urllib.parse.urljoin(url, a.get("href"))
102
+ if "Round:" in td_text:
103
+ round_text = td_text[td_text.find("Round:") + 6 :]
104
+ round_text = round_text[: round_text.find("Venue:")]
105
+ round_text = round_text.strip()
106
+ week_addition = _FINALS_WEEK_ADDITION_MAP.get(round_text)
107
+ if week_addition is None:
108
+ week = int(round_text)
109
+ else:
110
+ week = last_round_number + week_addition
111
+ if "Attendance:" in td_text:
112
+ attendance_text = td_text[
113
+ td_text.find("Attendance:") + 11 :
114
+ ].strip()
115
+ attendance = int(attendance_text)
116
+ team_info = _find_team_info(tr, url)
117
+ if team_info is not None:
118
+ team_infos[team_info[0]] = (team_info[1], team_info[2])
119
+
120
+ if dt is None:
121
+ raise ValueError("dt is null.")
122
+ if venue_url is None:
123
+ raise ValueError("venue_url is null.")
124
+ if week is None:
125
+ raise ValueError("week is null.")
126
+ dt = dt.replace(tzinfo=None)
127
+
128
+ return (
129
+ dt,
130
+ venue_url,
131
+ week,
132
+ [(k, v[0], v[1]) for k, v in team_infos.items()],
133
+ _find_end_dt(soup, dt),
134
+ attendance,
135
+ )
136
+
137
+
138
+ def _create_afl_afltables_game_model(
139
+ game_number: int,
140
+ session: requests_cache.CachedSession,
141
+ url: str,
142
+ last_round_number: int,
143
+ last_ladder_ranks: dict[str, int] | None,
144
+ league: League,
145
+ season_year: int | None,
146
+ season_type: SeasonType | None,
147
+ ) -> GameModel:
148
+ # pylint: disable=too-many-locals
149
+ response = session.get(url)
150
+ response.raise_for_status()
151
+ soup = BeautifulSoup(response.text, "lxml")
152
+
153
+ def _find_teams_metadata(
154
+ soup: BeautifulSoup, team_infos: list[tuple[str, str, int]]
155
+ ) -> list[
156
+ tuple[
157
+ str,
158
+ list[
159
+ tuple[
160
+ str,
161
+ str,
162
+ int | None,
163
+ str,
164
+ int | None,
165
+ int | None,
166
+ int | None,
167
+ int | None,
168
+ int | None,
169
+ int | None,
170
+ int | None,
171
+ int | None,
172
+ int | None,
173
+ int | None,
174
+ int | None,
175
+ int | None,
176
+ int | None,
177
+ int | None,
178
+ int | None,
179
+ int | None,
180
+ int | None,
181
+ int | None,
182
+ int | None,
183
+ int | None,
184
+ int | None,
185
+ float | None,
186
+ ]
187
+ ],
188
+ int,
189
+ ]
190
+ ]:
191
+ def _is_correct_table(table: Tag, name: str) -> bool:
192
+ for th in table.find_all("th"):
193
+ header_text = th.get_text().strip()
194
+ if name + " Match Statistics" in header_text:
195
+ return True
196
+ return False
197
+
198
+ def _find_players(
199
+ table: Tag,
200
+ ) -> list[
201
+ tuple[
202
+ str,
203
+ str,
204
+ int | None,
205
+ str,
206
+ int | None,
207
+ int | None,
208
+ int | None,
209
+ int | None,
210
+ int | None,
211
+ int | None,
212
+ int | None,
213
+ int | None,
214
+ int | None,
215
+ int | None,
216
+ int | None,
217
+ int | None,
218
+ int | None,
219
+ int | None,
220
+ int | None,
221
+ int | None,
222
+ int | None,
223
+ int | None,
224
+ int | None,
225
+ int | None,
226
+ int | None,
227
+ float | None,
228
+ ]
229
+ ]:
230
+ players: list[
231
+ tuple[
232
+ str,
233
+ str,
234
+ int | None,
235
+ str,
236
+ int | None,
237
+ int | None,
238
+ int | None,
239
+ int | None,
240
+ int | None,
241
+ int | None,
242
+ int | None,
243
+ int | None,
244
+ int | None,
245
+ int | None,
246
+ int | None,
247
+ int | None,
248
+ int | None,
249
+ int | None,
250
+ int | None,
251
+ int | None,
252
+ int | None,
253
+ int | None,
254
+ int | None,
255
+ int | None,
256
+ int | None,
257
+ float | None,
258
+ ]
259
+ ] = []
260
+ for tr in table.find_all("tr"):
261
+ player_row = False
262
+ player_url = None
263
+ for a in tr.find_all("a", href=True):
264
+ player_url = urllib.parse.urljoin(url, a.get("href"))
265
+ o = urlparse(player_url)
266
+ if "players" in o.path.split("/"):
267
+ player_row = True
268
+ if player_row and player_url is not None:
269
+ jersey = None
270
+ name = None
271
+ kicks = None
272
+ marks = None
273
+ handballs = None
274
+ disposals = None
275
+ goals: int | None = None
276
+ behinds = None
277
+ hit_outs = None
278
+ tackles = None
279
+ rebounds = None
280
+ insides = None
281
+ clearances = None
282
+ clangers = None
283
+ free_kicks_for = None
284
+ free_kicks_against = None
285
+ brownlow_votes = None
286
+ contested_possessions = None
287
+ uncontested_possessions = None
288
+ contested_marks = None
289
+ marks_inside = None
290
+ one_percenters = None
291
+ bounces = None
292
+ goal_assists = None
293
+ percentage_played = None
294
+ for count, td in enumerate(tr.find_all("td")):
295
+ if count == 0:
296
+ jersey = td.get_text().strip()
297
+ elif count == 1:
298
+ name = " ".join(
299
+ [
300
+ x.strip()
301
+ for x in reversed(td.get_text().strip().split(","))
302
+ ]
303
+ )
304
+ elif count == 2:
305
+ kicks_text = td.get_text().strip()
306
+ if kicks_text:
307
+ kicks = int(kicks_text)
308
+ elif count == 3:
309
+ marks_text = td.get_text().strip()
310
+ if marks_text:
311
+ marks = int(marks_text)
312
+ elif count == 4:
313
+ handballs_text = td.get_text().strip()
314
+ if handballs_text:
315
+ handballs = int(handballs_text)
316
+ elif count == 5:
317
+ disposals_text = td.get_text().strip()
318
+ if disposals_text:
319
+ disposals = int(disposals_text)
320
+ elif count == 6:
321
+ goals_text = td.get_text().strip()
322
+ if goals_text:
323
+ goals = int(goals_text)
324
+ elif count == 7:
325
+ behinds_text = td.get_text().strip()
326
+ if behinds_text:
327
+ behinds = int(behinds_text)
328
+ elif count == 8:
329
+ hit_outs_text = td.get_text().strip()
330
+ if hit_outs_text:
331
+ hit_outs = int(hit_outs_text)
332
+ elif count == 9:
333
+ tackles_text = td.get_text().strip()
334
+ if tackles_text:
335
+ tackles = int(tackles_text)
336
+ elif count == 10:
337
+ rebounds_text = td.get_text().strip()
338
+ if rebounds_text:
339
+ rebounds = int(rebounds_text)
340
+ elif count == 11:
341
+ insides_text = td.get_text().strip()
342
+ if insides_text:
343
+ insides = int(insides_text)
344
+ elif count == 12:
345
+ clearances_text = td.get_text().strip()
346
+ if clearances_text:
347
+ clearances = int(clearances_text)
348
+ elif count == 13:
349
+ clangers_text = td.get_text().strip()
350
+ if clangers_text:
351
+ clangers = int(clangers_text)
352
+ elif count == 14:
353
+ free_kicks_for_text = td.get_text().strip()
354
+ if free_kicks_for_text:
355
+ free_kicks_for = int(free_kicks_for_text)
356
+ elif count == 15:
357
+ free_kicks_against_text = td.get_text().strip()
358
+ if free_kicks_against_text:
359
+ free_kicks_against = int(free_kicks_against_text)
360
+ elif count == 16:
361
+ brownlow_votes_text = td.get_text().strip()
362
+ if brownlow_votes_text:
363
+ brownlow_votes = int(brownlow_votes_text)
364
+ elif count == 17:
365
+ contested_possessions_text = td.get_text().strip()
366
+ if contested_possessions_text:
367
+ contested_possessions = int(contested_possessions_text)
368
+ elif count == 18:
369
+ uncontested_possessions_text = td.get_text().strip()
370
+ if uncontested_possessions_text:
371
+ uncontested_possessions = int(
372
+ uncontested_possessions_text
373
+ )
374
+ elif count == 19:
375
+ contested_marks_text = td.get_text().strip()
376
+ if contested_marks_text:
377
+ contested_marks = int(contested_marks_text)
378
+ elif count == 20:
379
+ marks_inside_text = td.get_text().strip()
380
+ if marks_inside_text:
381
+ marks_inside = int(marks_inside_text)
382
+ elif count == 21:
383
+ one_percenters_text = td.get_text().strip()
384
+ if one_percenters_text:
385
+ one_percenters = int(one_percenters_text)
386
+ elif count == 22:
387
+ bounces_text = td.get_text().strip()
388
+ if bounces_text:
389
+ bounces = int(bounces_text)
390
+ elif count == 23:
391
+ goal_assists_text = td.get_text().strip()
392
+ if goal_assists_text:
393
+ goal_assists = int(goal_assists_text)
394
+ elif count == 24:
395
+ percentage_played_text = td.get_text().strip()
396
+ if percentage_played_text:
397
+ percentage_played = float(percentage_played_text)
398
+
399
+ if jersey is None:
400
+ raise ValueError("jersey is null.")
401
+ if name is None:
402
+ raise ValueError("name is null")
403
+
404
+ players.append(
405
+ (
406
+ player_url,
407
+ jersey,
408
+ kicks,
409
+ name,
410
+ marks,
411
+ handballs,
412
+ disposals,
413
+ goals,
414
+ behinds,
415
+ hit_outs,
416
+ tackles,
417
+ rebounds,
418
+ insides,
419
+ clearances,
420
+ clangers,
421
+ free_kicks_for,
422
+ free_kicks_against,
423
+ brownlow_votes,
424
+ contested_possessions,
425
+ uncontested_possessions,
426
+ contested_marks,
427
+ marks_inside,
428
+ one_percenters,
429
+ bounces,
430
+ goal_assists,
431
+ percentage_played,
432
+ )
433
+ )
434
+ return players
435
+
436
+ team_metadata = []
437
+ for team_url, name, points in team_infos:
438
+ for table in soup.find_all("table"):
439
+ if _is_correct_table(table, name):
440
+ players = _find_players(table)
441
+ team_metadata.append((team_url, players, points))
442
+ break
443
+ return team_metadata
444
+
445
+ dt, venue_url, week, team_infos, end_dt, attendance = _find_season_metadata(
446
+ soup, url, last_round_number
447
+ )
448
+ return GameModel(
449
+ dt=dt,
450
+ week=week,
451
+ game_number=game_number,
452
+ venue=create_afl_afltables_venue_model(venue_url, session, dt),
453
+ teams=[
454
+ create_afl_afltables_team_model(
455
+ team_url,
456
+ players,
457
+ float(points),
458
+ session, # pyright: ignore
459
+ last_ladder_ranks,
460
+ dt,
461
+ league,
462
+ )
463
+ for team_url, players, points in _find_teams_metadata(soup, team_infos)
464
+ ],
465
+ end_dt=end_dt,
466
+ attendance=attendance,
467
+ league=str(league),
468
+ year=season_year,
469
+ season_type=season_type,
470
+ postponed=None,
471
+ play_off=None,
472
+ )
473
+
474
+
475
+ @MEMORY.cache(ignore=["session"])
476
+ def _cached_create_afl_afltables_game_model(
477
+ game_number: int,
478
+ session: requests_cache.CachedSession,
479
+ url: str,
480
+ last_round_number: int,
481
+ last_ladder_ranks: dict[str, int] | None,
482
+ league: League,
483
+ season_year: int | None,
484
+ season_type: SeasonType | None,
485
+ ) -> GameModel:
486
+ return _create_afl_afltables_game_model(
487
+ game_number,
488
+ session,
489
+ url,
490
+ last_round_number,
491
+ last_ladder_ranks,
492
+ league,
493
+ season_year,
494
+ season_type,
495
+ )
496
+
497
+
498
+ def create_afl_afltables_game_model(
499
+ game_number: int,
500
+ session: requests_cache.CachedSession,
501
+ url: str,
502
+ last_round_number: int,
503
+ last_ladder_ranks: dict[str, int] | None,
504
+ league: League,
505
+ season_year: int | None,
506
+ season_type: SeasonType | None,
507
+ dt: datetime.datetime,
508
+ ) -> GameModel:
509
+ """Create a game model from AFL Tables."""
510
+ if (
511
+ not pytest_is_running.is_running()
512
+ and dt < datetime.datetime.now() - datetime.timedelta(days=7)
513
+ ):
514
+ return _cached_create_afl_afltables_game_model(
515
+ game_number,
516
+ session,
517
+ url,
518
+ last_round_number,
519
+ last_ladder_ranks,
520
+ league,
521
+ season_year,
522
+ season_type,
523
+ )
524
+ with session.cache_disabled():
525
+ return _create_afl_afltables_game_model(
526
+ game_number,
527
+ session,
528
+ url,
529
+ last_round_number,
530
+ last_ladder_ranks,
531
+ league,
532
+ season_year,
533
+ season_type,
534
+ )
@@ -62,7 +62,7 @@ class AFLAFLTablesLeagueModel(LeagueModel):
62
62
  else:
63
63
  response = self.session.get(season_url)
64
64
 
65
- soup = BeautifulSoup(response.text, "html.parser")
65
+ soup = BeautifulSoup(response.text, "lxml")
66
66
  in_finals = False
67
67
  game_number = 0
68
68
  last_round_number = 0
@@ -151,7 +151,7 @@ class AFLAFLTablesLeagueModel(LeagueModel):
151
151
  with self.session.cache_disabled():
152
152
  response = self.session.get(_SEASON_URL)
153
153
  response.raise_for_status()
154
- soup = BeautifulSoup(response.text, "html.parser")
154
+ soup = BeautifulSoup(response.text, "lxml")
155
155
  with tqdm.tqdm(position=self.position) as pbar:
156
156
  for table in soup.find_all("table"):
157
157
  for tr in table.find_all("tr"):