wsba-hockey 1.1.8__py3-none-any.whl → 1.2.0__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 (145) hide show
  1. wsba_hockey/__init__.py +22 -1
  2. wsba_hockey/tools/scraping.py +166 -190
  3. wsba_hockey/tools/utils/__init__.py +0 -1
  4. wsba_hockey/tools/utils/shared.py +14 -389
  5. wsba_hockey/tools/xg_model.py +6 -1
  6. wsba_hockey/wsba_main.py +330 -20
  7. {wsba_hockey-1.1.8.dist-info → wsba_hockey-1.2.0.dist-info}/METADATA +16 -15
  8. wsba_hockey-1.2.0.dist-info/RECORD +15 -0
  9. wsba_hockey/api/api/index.py +0 -162
  10. wsba_hockey/data_pipelines.py +0 -247
  11. wsba_hockey/evidence/weakside-breakout/node_modules/duckdb/vendor.py +0 -146
  12. wsba_hockey/evidence/weakside-breakout/node_modules/flatted/python/flatted.py +0 -149
  13. wsba_hockey/evidence/weakside-breakout/node_modules/flatted/python/test.py +0 -63
  14. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/gyp_main.py +0 -45
  15. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py +0 -367
  16. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py +0 -206
  17. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py +0 -1270
  18. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py +0 -1547
  19. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py +0 -59
  20. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py +0 -153
  21. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py +0 -271
  22. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py +0 -574
  23. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/__init__.py +0 -690
  24. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/common.py +0 -661
  25. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/common_test.py +0 -78
  26. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py +0 -165
  27. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py +0 -109
  28. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py +0 -55
  29. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/__init__.py +0 -0
  30. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py +0 -808
  31. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py +0 -1173
  32. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py +0 -1321
  33. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py +0 -120
  34. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py +0 -103
  35. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py +0 -464
  36. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py +0 -89
  37. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py +0 -58
  38. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py +0 -2714
  39. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py +0 -3981
  40. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py +0 -44
  41. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py +0 -2936
  42. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py +0 -55
  43. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py +0 -1394
  44. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py +0 -25
  45. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/input.py +0 -3130
  46. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/input_test.py +0 -98
  47. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py +0 -771
  48. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py +0 -1271
  49. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/ninja_syntax.py +0 -174
  50. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py +0 -61
  51. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py +0 -374
  52. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py +0 -1939
  53. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py +0 -302
  54. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py +0 -3197
  55. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py +0 -65
  56. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/test_gyp.py +0 -261
  57. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/graphviz.py +0 -102
  58. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/pretty_gyp.py +0 -156
  59. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/pretty_sln.py +0 -181
  60. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/pretty_vcproj.py +0 -339
  61. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/test/fixtures/test-charmap.py +0 -31
  62. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/update-gyp.py +0 -64
  63. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/gyp_main.py +0 -45
  64. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py +0 -367
  65. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py +0 -206
  66. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py +0 -1270
  67. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py +0 -1547
  68. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py +0 -59
  69. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py +0 -153
  70. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py +0 -271
  71. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py +0 -574
  72. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/__init__.py +0 -666
  73. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/common.py +0 -654
  74. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/common_test.py +0 -78
  75. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py +0 -165
  76. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py +0 -109
  77. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py +0 -55
  78. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/__init__.py +0 -0
  79. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py +0 -808
  80. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py +0 -1173
  81. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py +0 -1321
  82. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py +0 -120
  83. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py +0 -103
  84. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py +0 -464
  85. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py +0 -89
  86. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py +0 -58
  87. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py +0 -2518
  88. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py +0 -3978
  89. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py +0 -44
  90. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py +0 -2936
  91. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py +0 -55
  92. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py +0 -1394
  93. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py +0 -25
  94. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/input.py +0 -3137
  95. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/input_test.py +0 -98
  96. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py +0 -771
  97. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py +0 -1271
  98. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/ninja_syntax.py +0 -174
  99. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py +0 -61
  100. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py +0 -374
  101. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py +0 -1939
  102. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py +0 -302
  103. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py +0 -3197
  104. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py +0 -65
  105. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/setup.py +0 -42
  106. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/test_gyp.py +0 -260
  107. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/graphviz.py +0 -102
  108. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_gyp.py +0 -156
  109. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_sln.py +0 -181
  110. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_vcproj.py +0 -339
  111. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/test/fixtures/test-charmap.py +0 -31
  112. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/update-gyp.py +0 -46
  113. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/duos/app.py +0 -210
  114. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/duos/calc.py +0 -163
  115. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/game_stats/app.py +0 -401
  116. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/game_stats/name_fix.py +0 -47
  117. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/goalie/app.py +0 -101
  118. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/goalie/plot.py +0 -71
  119. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/goalie/rink_plot.py +0 -245
  120. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/app.py +0 -108
  121. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/plot.py +0 -95
  122. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/rink_plot.py +0 -245
  123. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/line-combos/app.py +0 -245
  124. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/line-combos/plot.py +0 -275
  125. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/line-combos/rink_plot.py +0 -245
  126. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/app.py +0 -145
  127. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/plot.py +0 -79
  128. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/rink_plot.py +0 -245
  129. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/app.py +0 -406
  130. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/plot.py +0 -79
  131. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/rink_plot.py +0 -245
  132. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/skater/app.py +0 -110
  133. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/skater/plot.py +0 -59
  134. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/skater/rink_plot.py +0 -245
  135. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/team_heatmaps/app.py +0 -103
  136. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/team_heatmaps/plot.py +0 -95
  137. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/team_heatmaps/rink_plot.py +0 -245
  138. wsba_hockey/flask/app.py +0 -77
  139. wsba_hockey/tools/utils/config.py +0 -14
  140. wsba_hockey/tools/utils/save_pages.py +0 -133
  141. wsba_hockey/workspace.py +0 -31
  142. wsba_hockey-1.1.8.dist-info/RECORD +0 -148
  143. {wsba_hockey-1.1.8.dist-info → wsba_hockey-1.2.0.dist-info}/WHEEL +0 -0
  144. {wsba_hockey-1.1.8.dist-info → wsba_hockey-1.2.0.dist-info}/licenses/LICENSE +0 -0
  145. {wsba_hockey-1.1.8.dist-info → wsba_hockey-1.2.0.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())