wsba-hockey 1.1.9__py3-none-any.whl → 1.2.1__py3-none-any.whl

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 (144) hide show
  1. wsba_hockey/tools/scraping.py +146 -170
  2. wsba_hockey/tools/utils/__init__.py +0 -1
  3. wsba_hockey/tools/utils/shared.py +14 -389
  4. wsba_hockey/tools/xg_model.py +6 -1
  5. wsba_hockey/wsba_main.py +47 -14
  6. {wsba_hockey-1.1.9.dist-info → wsba_hockey-1.2.1.dist-info}/METADATA +16 -15
  7. wsba_hockey-1.2.1.dist-info/RECORD +15 -0
  8. wsba_hockey/api/api/index.py +0 -162
  9. wsba_hockey/data_pipelines.py +0 -247
  10. wsba_hockey/evidence/weakside-breakout/node_modules/duckdb/vendor.py +0 -146
  11. wsba_hockey/evidence/weakside-breakout/node_modules/flatted/python/flatted.py +0 -149
  12. wsba_hockey/evidence/weakside-breakout/node_modules/flatted/python/test.py +0 -63
  13. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/gyp_main.py +0 -45
  14. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py +0 -367
  15. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py +0 -206
  16. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py +0 -1270
  17. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py +0 -1547
  18. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py +0 -59
  19. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py +0 -153
  20. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py +0 -271
  21. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py +0 -574
  22. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/__init__.py +0 -690
  23. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/common.py +0 -661
  24. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/common_test.py +0 -78
  25. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py +0 -165
  26. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py +0 -109
  27. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py +0 -55
  28. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/__init__.py +0 -0
  29. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py +0 -808
  30. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py +0 -1173
  31. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py +0 -1321
  32. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py +0 -120
  33. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py +0 -103
  34. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py +0 -464
  35. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py +0 -89
  36. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py +0 -58
  37. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py +0 -2714
  38. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py +0 -3981
  39. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py +0 -44
  40. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py +0 -2936
  41. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py +0 -55
  42. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py +0 -1394
  43. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py +0 -25
  44. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/input.py +0 -3130
  45. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/input_test.py +0 -98
  46. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py +0 -771
  47. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py +0 -1271
  48. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/ninja_syntax.py +0 -174
  49. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py +0 -61
  50. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py +0 -374
  51. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py +0 -1939
  52. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py +0 -302
  53. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py +0 -3197
  54. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py +0 -65
  55. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/test_gyp.py +0 -261
  56. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/graphviz.py +0 -102
  57. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/pretty_gyp.py +0 -156
  58. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/pretty_sln.py +0 -181
  59. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/pretty_vcproj.py +0 -339
  60. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/test/fixtures/test-charmap.py +0 -31
  61. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/update-gyp.py +0 -64
  62. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/gyp_main.py +0 -45
  63. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py +0 -367
  64. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py +0 -206
  65. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py +0 -1270
  66. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py +0 -1547
  67. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py +0 -59
  68. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py +0 -153
  69. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py +0 -271
  70. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py +0 -574
  71. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/__init__.py +0 -666
  72. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/common.py +0 -654
  73. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/common_test.py +0 -78
  74. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py +0 -165
  75. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py +0 -109
  76. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py +0 -55
  77. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/__init__.py +0 -0
  78. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py +0 -808
  79. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py +0 -1173
  80. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py +0 -1321
  81. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py +0 -120
  82. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py +0 -103
  83. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py +0 -464
  84. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py +0 -89
  85. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py +0 -58
  86. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py +0 -2518
  87. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py +0 -3978
  88. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py +0 -44
  89. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py +0 -2936
  90. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py +0 -55
  91. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py +0 -1394
  92. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py +0 -25
  93. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/input.py +0 -3137
  94. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/input_test.py +0 -98
  95. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py +0 -771
  96. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py +0 -1271
  97. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/ninja_syntax.py +0 -174
  98. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py +0 -61
  99. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py +0 -374
  100. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py +0 -1939
  101. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py +0 -302
  102. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py +0 -3197
  103. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py +0 -65
  104. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/setup.py +0 -42
  105. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/test_gyp.py +0 -260
  106. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/graphviz.py +0 -102
  107. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_gyp.py +0 -156
  108. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_sln.py +0 -181
  109. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_vcproj.py +0 -339
  110. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/test/fixtures/test-charmap.py +0 -31
  111. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/update-gyp.py +0 -46
  112. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/duos/app.py +0 -210
  113. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/duos/calc.py +0 -163
  114. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/game_stats/app.py +0 -401
  115. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/game_stats/name_fix.py +0 -47
  116. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/goalie/app.py +0 -101
  117. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/goalie/plot.py +0 -71
  118. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/goalie/rink_plot.py +0 -245
  119. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/app.py +0 -108
  120. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/plot.py +0 -95
  121. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/rink_plot.py +0 -245
  122. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/line-combos/app.py +0 -245
  123. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/line-combos/plot.py +0 -275
  124. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/line-combos/rink_plot.py +0 -245
  125. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/app.py +0 -145
  126. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/plot.py +0 -79
  127. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/rink_plot.py +0 -245
  128. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/app.py +0 -406
  129. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/plot.py +0 -79
  130. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/rink_plot.py +0 -245
  131. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/skater/app.py +0 -110
  132. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/skater/plot.py +0 -59
  133. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/skater/rink_plot.py +0 -245
  134. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/team_heatmaps/app.py +0 -103
  135. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/team_heatmaps/plot.py +0 -95
  136. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/team_heatmaps/rink_plot.py +0 -245
  137. wsba_hockey/flask/app.py +0 -77
  138. wsba_hockey/tools/utils/config.py +0 -14
  139. wsba_hockey/tools/utils/save_pages.py +0 -133
  140. wsba_hockey/workspace.py +0 -28
  141. wsba_hockey-1.1.9.dist-info/RECORD +0 -148
  142. {wsba_hockey-1.1.9.dist-info → wsba_hockey-1.2.1.dist-info}/WHEEL +0 -0
  143. {wsba_hockey-1.1.9.dist-info → wsba_hockey-1.2.1.dist-info}/licenses/LICENSE +0 -0
  144. {wsba_hockey-1.1.9.dist-info → wsba_hockey-1.2.1.dist-info}/top_level.txt +0 -0
@@ -1,103 +0,0 @@
1
- import pandas as pd
2
- import plot as wsba_plt
3
- import numpy as np
4
- from urllib.parse import *
5
- from shiny import *
6
- from shinywidgets import output_widget, render_widget
7
-
8
- app_ui = ui.page_fluid(
9
- ui.tags.style(
10
- "body {background:#09090b"
11
- "}"
12
- ),
13
- output_widget("plot_skater"),
14
- )
15
-
16
- def server(input, output, session):
17
- @output()
18
- @render_widget
19
- def plot_skater():
20
- #Retreive query parameters
21
- search = session.input[".clientdata_url_search"]()
22
- query = parse_qs(urlparse(search).query)
23
-
24
- print(query)
25
- #If no input data is provided automatically provide a select skater and plot all 5v5 fenwick shots
26
- defaults = {
27
- 'team':['BOS'],
28
- 'season':['20222023'],
29
- 'strength_state':['5v5'],
30
- 'season_type':['2']
31
- }
32
-
33
- for key in defaults.keys():
34
- if key not in query.keys():
35
- query.update({key:defaults[key]})
36
-
37
- #Iterate through query and parse params with multiple selections
38
- for param in query.keys():
39
- q_string = query[param][0]
40
- query[param] = q_string.split(',')
41
-
42
- print(query)
43
- #Determine which season to load based on the input
44
- season = query['season'][0]
45
- #Load appropriate dataframe
46
- df = pd.read_parquet(f'https://weakside-breakout.s3.us-east-2.amazonaws.com/pbp/{season}.parquet')
47
-
48
- #Prepare dataframe for plotting based on URL parameters
49
- df = df.loc[(df['season'].astype(str).isin(query['season']))&(df['season_type'].astype(str).isin(query['season_type']))].replace({np.nan: None})
50
- #Return empty rink if no data exists else continue
51
- if df.empty:
52
- return wsba_plt.wsba_rink()
53
- else:
54
- rink = wsba_plt.wsba_rink()
55
-
56
- try:
57
- for_plot = wsba_plt.heatmap(df,team=query['team'][0],events=['missed-shot','shot-on-goal','goal'],strengths=query['strength_state'],onice='for')
58
- against_plot = wsba_plt.heatmap(df,team=query['team'][0],events=['missed-shot','shot-on-goal','goal'],strengths=query['strength_state'],onice='against')
59
-
60
- for trace in for_plot.data:
61
- rink.add_trace(trace)
62
-
63
- for trace in against_plot.data:
64
- rink.add_trace(trace)
65
-
66
- season = int(season[0:4])
67
- team = query['team'][0]
68
- strengths = 'All Situations' if len(query['strength_state']) == 4 else query['strength_state']
69
- span = 'Regular Season' if query['season_type'][0]=='2' else 'Playoffs'
70
-
71
- return rink.update_layout(
72
- title=dict(
73
- text=f'{team} On-Ice xG at {strengths}; {season}-{season+1}, {span}',
74
- x=0.5, y=0.96,
75
- xanchor='center',
76
- yanchor='top',
77
- font=dict(color='white')
78
- ),
79
- ).add_annotation(
80
- text='Lower xG',
81
- xref="paper",
82
- yref="paper",
83
- xanchor='right',
84
- yanchor='top',
85
- font=dict(color='white'),
86
- x=0.3,
87
- y=0.04,
88
- showarrow=False
89
- ).add_annotation(
90
- text='Higher xG',
91
- xref="paper",
92
- yref="paper",
93
- xanchor='right',
94
- yanchor='top',
95
- font=dict(color='white'),
96
- x=0.76,
97
- y=0.04,
98
- showarrow=False
99
- )
100
- except:
101
- return wsba_plt.wsba_rink()
102
-
103
- app = App(app_ui, server)
@@ -1,95 +0,0 @@
1
- import pandas as pd
2
- import numpy as np
3
- import plotly.graph_objects as go
4
- import matplotlib.pyplot as plt
5
- import rink_plot
6
- from scipy.interpolate import griddata
7
- from scipy.ndimage import gaussian_filter
8
-
9
- def wsba_rink(setting='full', vertical=False):
10
- return rink_plot.rink(setting=setting, vertical=vertical)
11
-
12
- def heatmap(df,team,events,strengths,onice):
13
- df['event_team_abbr_2'] = np.where(df['home_team_abbr']==df['event_team_abbr'],df['away_team_abbr'],df['home_team_abbr'])
14
- df['strength_state_2'] = df['strength_state'].str[::-1]
15
-
16
- df = df.fillna(0)
17
- df = df.loc[(df['event_type'].isin(events))&(df['x_adj'].notna())&(df['y_adj'].notna())]
18
- if onice == 'for':
19
- df['x'] = abs(df['x_adj'])
20
- df['y'] = np.where(df['x_adj']<0,-df['y_adj'],df['y_adj'])
21
- df['event_distance'] = abs(df['event_distance'].fillna(0))
22
- df = df.loc[(df['event_distance']<=89)&(df['x']<=89)&(df['empty_net']==0)]
23
-
24
- x_min = 0
25
- x_max = 100
26
- else:
27
- df['x'] = -abs(df['x_adj'])
28
- df['y'] = np.where(df['x_adj']>0,-df['y_adj'],df['y_adj'])
29
- df['event_distance'] = -abs(df['event_distance'])
30
- df = df.loc[(df['event_distance']>-89)&(df['x']>-89)&(df['empty_net']==0)]
31
-
32
- x_min = -100
33
- x_max = 0
34
-
35
- df['home_on_ice'] = df['home_on_1_id'].astype(str) + ";" + df['home_on_2_id'].astype(str) + ";" + df['home_on_3_id'].astype(str) + ";" + df['home_on_4_id'].astype(str) + ";" + df['home_on_5_id'].astype(str) + ";" + df['home_on_6_id'].astype(str)
36
- df['away_on_ice'] = df['away_on_1_id'].astype(str) + ";" + df['away_on_2_id'].astype(str) + ";" + df['away_on_3_id'].astype(str) + ";" + df['away_on_4_id'].astype(str) + ";" + df['away_on_5_id'].astype(str) + ";" + df['away_on_6_id'].astype(str)
37
-
38
- df['onice_for'] = np.where(df['home_team_abbr']==df['event_team_abbr'],df['home_on_ice'],df['away_on_ice'])
39
- df['onice_against'] = np.where(df['away_team_abbr']==df['event_team_abbr'],df['home_on_ice'],df['away_on_ice'])
40
-
41
- df['strength_state'] = np.where(df['strength_state'].isin(['5v5','5v4','4v5']),df['strength_state'],'Other')
42
- df['strength_state_2'] = np.where(df['strength_state_2'].isin(['5v5','5v4','4v5']),df['strength_state_2'],'Other')
43
-
44
- if strengths != 'all':
45
- if onice == 'against':
46
- df = df.loc[((df['strength_state_2'].isin(strengths)))]
47
- else:
48
- df = df.loc[((df['strength_state'].isin(strengths)))]
49
-
50
- [x,y] = np.round(np.meshgrid(np.linspace(x_min,x_max,(x_max-x_min)),np.linspace(-42.5,42.5,85)))
51
- xgoals = griddata((df['x'],df['y']),df['xG'],(x,y),method='cubic',fill_value=0)
52
- xgoals = np.where(xgoals < 0,0,xgoals)
53
- xgoals_smooth = gaussian_filter(xgoals,sigma=3)
54
-
55
- if onice == 'for':
56
- player_shots = df.loc[(df['event_team_abbr']==team)]
57
- else:
58
- player_shots = df.loc[(df['event_team_abbr_2']==team)]
59
- [x,y] = np.round(np.meshgrid(np.linspace(x_min,x_max,(x_max-x_min)),np.linspace(-42.5,42.5,85)))
60
- xgoals_player = griddata((player_shots['x'],player_shots['y']),player_shots['xG'],(x,y),method='cubic',fill_value=0)
61
- xgoals_player = np.where(xgoals_player < 0,0,xgoals_player)
62
-
63
- difference = (gaussian_filter(xgoals_player,sigma = 3)) - xgoals_smooth
64
- data_min= difference.min()
65
- data_max= difference.max()
66
-
67
- if abs(data_min) > data_max:
68
- data_max = data_min * -1
69
- elif data_max > abs(data_min):
70
- data_min = data_max * -1
71
-
72
- fig = go.Figure(
73
- data = go.Contour( x=np.linspace(x_min,x_max,(x_max-x_min)),
74
- y=np.linspace(-42.5,42.5,85),
75
- z=difference,
76
- colorscale=[[0.0,'red'],[0.5,'#09090b'],[1.0,'blue']],
77
- connectgaps=True,
78
- contours=dict(
79
- type='levels',
80
- start = data_min,
81
- end = data_max,
82
- size=(data_max-data_min)/11
83
- ),
84
- colorbar=dict(
85
- len = 0.7,
86
- orientation='h',
87
- showticklabels=False,
88
- thickness=15,
89
- yref='paper',
90
- yanchor='top',
91
- y=0
92
- ))
93
- )
94
-
95
- return fig
@@ -1,245 +0,0 @@
1
-
2
- import numpy as np
3
- import plotly.graph_objects as go
4
- import io
5
- import base64
6
- import requests as rs
7
- from PIL import Image
8
-
9
- def rink(setting = "full", vertical = False):
10
- '''
11
- Function to plot rink in Plotly. Takes 2 arguments :
12
-
13
- setting : full (default) for full ice, offense positive half of the ice, ozone positive quarter of ice, defense for negative half of the ice, dzone for negative quarter of the ice, and neutral for the neutral zone
14
- vertical : True if you want a vertical rink, False (default) is for an horizontal rink
15
-
16
- '''
17
-
18
- def faceoff_circle(x, y, outer=True):
19
- segments = []
20
- theta = np.linspace(0, 2*np.pi, 300)
21
- if outer:
22
- # Outer circle
23
- x_outer = x + 15*np.cos(theta)
24
- y_outer = y + 15*np.sin(theta)
25
- outer_circle = go.Scatter(x=x_outer, y=y_outer, mode='lines', line=dict(width=2, color='red'), showlegend=False, hoverinfo='skip')
26
-
27
- segments.append(outer_circle)
28
-
29
- # Inner circle
30
- x_inner = x + np.cos(theta)
31
- y_inner = y + np.sin(theta)
32
- inner_circle = go.Scatter(x=x_inner, y=y_inner, mode='lines', fill='toself', fillcolor='rgba(255, 0, 0, 0.43)', line=dict(color='rgba(255, 0, 0, 1)', width=2), showlegend=False, hoverinfo='skip')
33
-
34
- segments.append(inner_circle)
35
-
36
- return segments #segments
37
-
38
- fig = go.Figure()
39
-
40
- if vertical :
41
- setting_dict = {
42
- "full" : [-101, 101],
43
- "offense" : [0, 101],
44
- "ozone" : [25, 101],
45
- "defense" : [-101, 0],
46
- "dzone" : [-101, -25],
47
- "neutral" : [-25,25]
48
- }
49
- fig.update_layout(xaxis=dict(range=[-42.6, 42.6], showgrid=False, zeroline=False, showticklabels=False, constrain="domain"), yaxis=dict(range=setting_dict[setting], showgrid=False, zeroline=False, showticklabels=False, constrain="domain"),
50
- showlegend=False, autosize=True, template="plotly_white")
51
- fig.update_yaxes(
52
- scaleanchor="x",
53
- scaleratio=1,
54
- )
55
- def goal_crease(flip=1):
56
- x_seq = np.linspace(-4, 4, 100)
57
- x_goal = np.concatenate(([-4], x_seq, [4]))
58
- y_goal = flip * np.concatenate(([89], 83 + x_seq**2/4**2*1.5, [89]))
59
- goal_crease = go.Scatter(x=x_goal, y=y_goal, fill='toself', fillcolor='rgba(173, 216, 230, 0.3)', line=dict(color='red'))
60
- return goal_crease
61
-
62
- # Outer circle
63
- theta = np.linspace(0, 2*np.pi, 300)
64
- x_outer = 15 * np.cos(theta)
65
- y_outer = 15 * np.sin(theta)
66
- fig.add_trace(go.Scatter(x=x_outer, y=y_outer, mode='lines', line=dict(color='royalblue', width=2), showlegend=False, hoverinfo='skip'))
67
- # Inner circle
68
- theta2 = np.linspace(np.pi/2, 3*np.pi/2, 300)
69
- x_inner = 42.5 + 10 * np.cos(theta2)
70
- y_inner = 10 * np.sin(theta2)
71
- fig.add_trace(go.Scatter(x=x_inner, y=y_inner, mode='lines', line=dict(color='red', width=2), showlegend=False, hoverinfo='skip'))
72
- # Rink boundaries
73
- fig.add_shape(type='rect', xref='x', yref='y', x0=-42.5, y0=25, x1=42.5, y1=26, line=dict(color='royalblue', width=1), fillcolor='royalblue', opacity=1)
74
- fig.add_shape(type='rect', xref='x', yref='y', x0=-42.5, y0=-25, x1=42.5, y1=-26, line=dict(color='royalblue', width=1), fillcolor='royalblue', opacity=1)
75
- fig.add_shape(type='rect', xref='x', yref='y', x0=-42.5, y0=-0.5, x1=42.5, y1=0.5, line=dict(color='red', width=2), fillcolor='red')
76
-
77
- # Goal crease
78
- fig.add_trace(goal_crease())
79
- fig.add_trace(goal_crease(-1))
80
- # Goal lines
81
- goal_line_extreme = 42.5 - 28 + np.sqrt(28**2 - (28-11)**2)
82
- fig.add_shape(type='line', xref='x', yref='y', x0=-goal_line_extreme, y0=89, x1=goal_line_extreme, y1=89, line=dict(color='red', width=2))
83
- fig.add_shape(type='line', xref='x', yref='y', x0=-goal_line_extreme, y0=-89, x1=goal_line_extreme, y1=-89, line=dict(color='red', width=2))
84
-
85
- # Faceoff circles
86
- fig.add_traces(faceoff_circle(-22, 69))
87
- fig.add_traces(faceoff_circle(22, 69))
88
- fig.add_traces(faceoff_circle(-22, -69))
89
- fig.add_traces(faceoff_circle(22, -69))
90
- fig.add_traces(faceoff_circle(-22, -20, False))
91
- fig.add_traces(faceoff_circle(22, -20, False))
92
- fig.add_traces(faceoff_circle(-22, 20, False))
93
- fig.add_traces(faceoff_circle(22, 20, False))
94
-
95
- # Sidelines
96
- theta_lines = np.linspace(0, np.pi/2, 20)
97
- x_lines1 = np.concatenate(([-42.5], -42.5 + 28 - 28*np.cos(theta_lines), 42.5 - 28 + 28*np.cos(np.flip(theta_lines))))
98
- y_lines1 = np.concatenate(([15], 72 + 28*np.sin(theta_lines), 72 + 28*np.sin(np.flip(theta_lines))))
99
- x_lines2 = np.concatenate(([-42.5], -42.5 + 28 - 28*np.cos(theta_lines), 42.5 - 28 + 28*np.cos(np.flip(theta_lines))))
100
- y_lines2 = np.concatenate(([15], -72 - 28*np.sin(theta_lines), -72 - 28*np.sin(np.flip(theta_lines))))
101
- fig.add_trace(go.Scatter(x=x_lines1, y=y_lines1, mode='lines', line=dict(color='white', width=2), showlegend=False, hoverinfo='skip'))
102
- fig.add_trace(go.Scatter(x=x_lines2, y=y_lines2, mode='lines', line=dict(color='white', width=2), showlegend=False, hoverinfo='skip'))
103
- fig.add_shape(type='line', xref='x', yref='y', x0=42.5, y0=-72.5, x1=42.5, y1=72.5, line=dict(color='white', width=2))
104
- fig.add_shape(type='line', xref='x', yref='y', x0=-42.5, y0=-72.5, x1=-42.5, y1=72.5, line=dict(color='white', width=2))
105
-
106
- # Add goals
107
- goal_width = 6 # feet
108
- goal_depth = 4 # feet
109
-
110
- # Top goal
111
- fig.add_shape(
112
- type="rect",
113
- xref="x",
114
- yref="y",
115
- x0=-goal_width / 2,
116
- y0=89,
117
- x1=goal_width / 2,
118
- y1=89 + goal_depth,
119
- line=dict(color="red", width=2),
120
- )
121
- # Bottom goal
122
- fig.add_shape(
123
- type="rect",
124
- xref="x",
125
- yref="y",
126
- x0=-goal_width / 2,
127
- y0=-89 - goal_depth,
128
- x1=goal_width / 2,
129
- y1=-89,
130
- line=dict(color="red", width=2),
131
- )
132
-
133
- else :
134
- setting_dict = {
135
- "full" : [-101, 101],
136
- "offense" : [0, 101],
137
- "ozone" : [25, 101],
138
- "defense" : [-101, 0],
139
- "dzone" : [-101, -25]
140
- }
141
- fig.update_layout(xaxis=dict(range=setting_dict[setting], showgrid=False, zeroline=False, showticklabels=False), yaxis=dict(range=[-42.6, 42.6], showgrid=False, zeroline=False, showticklabels=False, constrain="domain"),
142
- showlegend=True, autosize =True, template="plotly_white")
143
- fig.update_yaxes(
144
- scaleanchor="x",
145
- scaleratio=1,
146
- )
147
- def goal_crease(flip=1):
148
- y_seq = np.linspace(-4, 4, 100)
149
- y_goal = np.concatenate(([-4], y_seq, [4]))
150
- x_goal = flip * np.concatenate(([89], 83 + y_seq**2/4**2*1.5, [89]))
151
- goal_crease = go.Scatter(x=x_goal, y=y_goal, fill='toself', fillcolor='rgba(173, 216, 230, 0.3)', line=dict(color='red'), showlegend=False, hoverinfo='skip')
152
- return goal_crease
153
-
154
- # Outer circle
155
- theta = np.linspace(0, 2 * np.pi, 300)
156
- x_outer = 15 * np.sin(theta)
157
- y_outer = 15 * np.cos(theta)
158
- fig.add_trace(go.Scatter(x=x_outer, y=y_outer, mode='lines', line=dict(color='royalblue', width=2), showlegend=False, hoverinfo='skip'))
159
- # Inner circle
160
- theta2 = np.linspace(3 * np.pi / 2, np.pi / 2, 300) # Update theta2 to rotate the plot by 180 degrees
161
- x_inner = 10 * np.sin(theta2) # Update x_inner to rotate the plot by 180 degrees
162
- y_inner = -42.5 - 10 * np.cos(theta2) # Update y_inner to rotate the plot by 180 degrees
163
- fig.add_trace(go.Scatter(x=x_inner, y=y_inner, mode='lines', line=dict(color='red', width=2), showlegend=False, hoverinfo='skip'))
164
-
165
- # Rink boundaries
166
- fig.add_shape(type='rect', xref='x', yref='y', x0=25, y0=-42.5, x1=26, y1=42.5, line=dict(color='royalblue', width=1), fillcolor='royalblue', opacity=1)
167
- fig.add_shape(type='rect', xref='x', yref='y', x0=-25, y0=-42.5, x1=-26, y1=42.5, line=dict(color='royalblue', width=1), fillcolor='royalblue', opacity=1)
168
- fig.add_shape(type='rect', xref='x', yref='y', x0=-0.5, y0=-42.5, x1=0.5, y1=42.5, line=dict(color='red', width=2), fillcolor='red')
169
- # Goal crease
170
- fig.add_trace(goal_crease())
171
- fig.add_trace(goal_crease(-1))
172
- # Goal lines
173
- goal_line_extreme = 42.5 - 28 + np.sqrt(28 ** 2 - (28 - 11) ** 2)
174
- fig.add_shape(type='line', xref='x', yref='y', x0=89, y0=-goal_line_extreme, x1=89, y1=goal_line_extreme, line=dict(color='red', width=2))
175
- fig.add_shape(type='line', xref='x', yref='y', x0=-89, y0=-goal_line_extreme, x1=-89, y1=goal_line_extreme, line=dict(color='red', width=2))
176
- # Faceoff circles
177
- fig.add_traces(faceoff_circle(-69, -22))
178
- fig.add_traces(faceoff_circle(-69, 22))
179
- fig.add_traces(faceoff_circle(69, -22))
180
- fig.add_traces(faceoff_circle(69, 22))
181
- fig.add_traces(faceoff_circle(-20, -22, False))
182
- fig.add_traces(faceoff_circle(-20, 22, False))
183
- fig.add_traces(faceoff_circle(20, -22, False))
184
- fig.add_traces(faceoff_circle(20, 22, False))
185
-
186
- # Sidelines
187
- theta_lines = np.linspace(0, np.pi / 2, 20)
188
- x_lines1 = np.concatenate(([15], 72 + 28 * np.sin(theta_lines), 72 + 28 * np.sin(np.flip(theta_lines))))
189
- y_lines1 = np.concatenate(([-42.5], -42.5 + 28 - 28 * np.cos(theta_lines), 42.5 - 28 + 28 * np.cos(np.flip(theta_lines))))
190
- x_lines2 = np.concatenate(([15], -72 - 28 * np.sin(theta_lines), -72 - 28 * np.sin(np.flip(theta_lines))))
191
- y_lines2 = np.concatenate(([-42.5], -42.5 + 28 - 28 * np.cos(theta_lines), 42.5 - 28 + 28 * np.cos(np.flip(theta_lines))))
192
- fig.add_trace(go.Scatter(x=x_lines1, y=y_lines1, mode='lines', line=dict(color='white', width=2), showlegend=False, hoverinfo='skip'))
193
- fig.add_trace(go.Scatter(x=x_lines2, y=y_lines2, mode='lines', line=dict(color='white', width=2), showlegend=False, hoverinfo='skip'))
194
- fig.add_shape(type='line', xref='x', yref='y', x0=-72.5, y0=-42.5, x1=72.5, y1=-42.5, line=dict(color='white', width=2))
195
- fig.add_shape(type='line', xref='x', yref='y', x0=-72.5, y0=42.5, x1=72.5, y1=42.5, line=dict(color='white', width=2))
196
-
197
- # Add goals
198
- goal_width = 6 # feet
199
- goal_depth = 4 # feet
200
-
201
- # Right goal
202
- fig.add_shape(
203
- type="rect",
204
- xref="x",
205
- yref="y",
206
- x0=89,
207
- y0=-goal_width / 2,
208
- x1=89 + goal_depth,
209
- y1=goal_width / 2,
210
- line=dict(color="red", width=2),
211
- )
212
- # Left goal
213
- fig.add_shape(
214
- type="rect",
215
- xref="x",
216
- yref="y",
217
- x0=-89 - goal_depth,
218
- y0=-goal_width / 2,
219
- x1=-89,
220
- y1=goal_width / 2,
221
- line=dict(color="red", width=2),
222
- )
223
-
224
- # Add logo
225
- logo = Image.open(rs.get('https://weakside-breakout.s3.us-east-2.amazonaws.com/utils/wsba.png',stream=True).raw)
226
-
227
- fig.add_layout_image(
228
- dict(
229
- source=logo,
230
- xref="x",
231
- yref="y",
232
- x=-12,
233
- y=12,
234
- sizex=24,
235
- sizey=24,
236
- sizing="stretch",
237
- opacity=1)
238
- )
239
-
240
- #Set background to transparent
241
- fig.update_layout(
242
- paper_bgcolor="rgba(0,0,0,0)",
243
- plot_bgcolor="rgba(0,0,0,0)"
244
- )
245
- return fig
wsba_hockey/flask/app.py DELETED
@@ -1,77 +0,0 @@
1
- from flask import Flask, render_template, request, redirect
2
- from flask_sqlalchemy import SQLAlchemy
3
- import pandas as pd
4
-
5
- app = Flask(__name__)
6
-
7
- #Globals
8
- seasons = [
9
- '20102011',
10
- '20112012',
11
- '20122013',
12
- '20132014',
13
- '20142015',
14
- '20152016',
15
- '20162017',
16
- '20172018',
17
- '20182019',
18
- '20192020',
19
- '20202021',
20
- '20212022',
21
- '20222023',
22
- '20232024',
23
- '20242025'
24
- ]
25
-
26
- #Generate pages
27
- @app.route("/")
28
- def index():
29
- return render_template("index.html")
30
-
31
- @app.route("/about/about")
32
- def about():
33
- return render_template("about/about.html")
34
-
35
- @app.route("/about/glossary")
36
- def glossary():
37
- return render_template("about/glossary.html")
38
-
39
- @app.route("/about/goal_impact")
40
- def goal_impact():
41
- return render_template("about/goal_impact.html")
42
-
43
- @app.route("/about/resources")
44
- def resources():
45
- return render_template("about/resources.html")
46
-
47
- @app.route("/about/xg_model")
48
- def xg_model():
49
- return render_template("about/xg_model.html")
50
-
51
- @app.route("/games/schedule")
52
- def schedule():
53
- return render_template("games/schedule.html")
54
-
55
- @app.route("/games/game_metrics")
56
- def pbp_viewer():
57
- return render_template("games/game_metrics.html")
58
-
59
- @app.route("/players/skater_stats", methods=["GET", "POST"])
60
- def skater_stats():
61
- filters = {}
62
- for filter in ['season','span','strength','position','display','type','min_age','min_toi']:
63
- print(request.args.get(filter))
64
- filters.update({filter:request.args.get(filter)})
65
-
66
- return render_template("players/skater_stats.html")
67
-
68
- @app.route("/players/goalie_stats")
69
- def goalie_stats():
70
- return render_template("players/goalie_stats.html")
71
-
72
- @app.route("/players/team_stats")
73
- def team_stats():
74
- return render_template("players/team_stats.html")
75
-
76
- if __name__ == "__main__":
77
- app.run()
@@ -1,14 +0,0 @@
1
- """
2
- Basic configurations
3
- """
4
-
5
- # Directory where to save pages
6
- # When True assumes ~/hockey_scraper_data
7
- # Otherwise can take str to `existing` directory
8
- DOCS_DIR = False
9
-
10
- # Boolean that tells us whether or not we should re-scrape a given page if it's already saved
11
- RESCRAPE = False
12
-
13
- # Whether to log verbose errors to log file
14
- LOG = False
@@ -1,133 +0,0 @@
1
- #
2
- #Saves the scraped docs so you don't have to re-scrape them every time you want to parse the docs.
3
- #
4
- #\**** Don't mess with this unless you know what you're doing \****
5
- #
6
- import os
7
- import gzip
8
-
9
-
10
- def create_base_file_path(file_info):
11
- """
12
- Creates the base file path for a given file
13
-
14
- :param file_info: Dictionary containing the info on the file. Includes the name, season, file type, and the dir
15
- we want to deposit any data in.
16
-
17
- :return: path
18
- """
19
- # Shitty fix for when you already have it saved but don't have nwhl folders
20
- if 'nwhl' in file_info['type']:
21
- if not os.path.isdir(os.path.join(file_info['dir'], 'docs', str(file_info['season']), file_info['type'])):
22
- os.mkdir(os.path.join(file_info['dir'], 'docs', str(file_info['season']), file_info['type']))
23
-
24
- return os.path.join(file_info['dir'], 'docs', str(file_info['season']), file_info['type'], file_info['name'] + ".txt")
25
-
26
-
27
- def is_compressed(file_info):
28
- """
29
- Check if stored file is compressed as we used to not save them as compressed.
30
-
31
- :param file_info: Dictionary containing the info on the file. Includes the name, season, file type, and the dir
32
- we want to deposit any data in.
33
-
34
- return Boolean
35
- """
36
- return os.path.isfile(create_base_file_path(file_info) + ".gz")
37
-
38
-
39
- def create_dir_structure(dir_name):
40
- """
41
- Create the basic directory structure for docs_dir if not done yet.
42
- Creates the docs and csvs subdir if it doesn't exist
43
-
44
- :param dir_name: Name of dir to create
45
-
46
- :return None
47
- """
48
- if not os.path.isdir(os.path.join(dir_name, 'docs')):
49
- os.mkdir(os.path.join(dir_name, 'docs'))
50
-
51
- if not os.path.isdir(os.path.join(dir_name, 'csvs')):
52
- os.mkdir(os.path.join(dir_name, 'csvs'))
53
-
54
-
55
-
56
- def create_season_dirs(file_info):
57
- """
58
- Creates the infrastructure to hold all the scraped docs for a season
59
-
60
- :param file_info: Dictionary containing the info on the file. Includes the name, season, file type, and the dir
61
- we want to deposit any data in.
62
-
63
- :return: None
64
- """
65
- sub_folders = ["html_pbp", "json_pbp", "espn_pbp", "html_shifts_home", "html_shifts_away",
66
- "json_shifts", "html_roster", "json_schedule", "espn_scoreboard"]
67
-
68
- season_path = os.path.join(file_info['dir'], 'docs', str(file_info['season']))
69
- os.mkdir(season_path)
70
-
71
- for sub_f in sub_folders:
72
- os.mkdir(os.path.join(season_path, sub_f))
73
-
74
-
75
- def check_file_exists(file_info):
76
- """
77
- Checks if the file exists. Also check if structure for holding scraped file exists to. If not, it creates it.
78
-
79
- :param file_info: Dictionary containing the info on the file. Includes the name, season, file type, and the dir
80
- we want to deposit any data in.
81
-
82
- :return: Boolean - True if it exists
83
- """
84
- create_dir_structure(file_info['dir'])
85
-
86
- # Check if the folder for the season for the given game was created yet...if not create it
87
- if not os.path.isdir(os.path.join(file_info['dir'], 'docs', str(file_info['season']))):
88
- create_season_dirs(file_info)
89
-
90
- # May or may not be compressed due to file saved under older versions
91
- non_compressed_file = os.path.isfile(create_base_file_path(file_info))
92
- compressed_file = is_compressed(file_info)
93
-
94
- return compressed_file or non_compressed_file
95
-
96
-
97
- def get_page(file_info):
98
- """
99
- Get the file so we don't need to re-scrape.
100
-
101
- Try both compressed and non-compressed for backwards compatability issues (formerly non-compressed)
102
-
103
- :param file_info: Dictionary containing the info on the file. Includes the name, season, file type, and the dir
104
- we want to deposit any data in.
105
-
106
- :return: Response or None
107
- """
108
- base_file = create_base_file_path(file_info)
109
-
110
- if is_compressed(file_info):
111
- with gzip.open(base_file + ".gz", 'rb') as my_file:
112
- return my_file.read().decode("utf-8").replace('\n', '')
113
- else:
114
- with open(base_file, 'r') as my_file:
115
- return my_file.read().replace('\n', '')
116
-
117
-
118
- def save_page(page, file_info):
119
- """
120
- Save the page we just scraped.
121
-
122
- Note: It'll only get saved if the directory already exists!!!!!!. I'm not dealing with any fuck ups. That would
123
- involve checking if it's even a valid path and creating it. Make sure you get it right.
124
-
125
- :param page: File scraped
126
- :param file_info: Dictionary containing the info on the file. Includes the name, season, file type, and the dir
127
- we want to deposit any data in.
128
-
129
- :return: None
130
- """
131
- if file_info['dir'] and page is not None and page != '':
132
- with gzip.open(create_base_file_path(file_info) + ".gz", 'wb') as file:
133
- file.write(page.encode())