cdechoch commited on
Commit
2b0e233
·
verified ·
1 Parent(s): e59ec96

Update database.py

Browse files
Files changed (1) hide show
  1. database.py +102 -105
database.py CHANGED
@@ -1,18 +1,20 @@
1
- """Database module for NBA Buzz"""
2
 
3
  import sqlite3
4
  import json
5
  from datetime import datetime, timezone, timedelta
6
- from typing import List, Dict, Optional
7
-
8
- DB_PATH = "/tmp/nba_mentions.db"
9
 
 
 
10
 
11
  def get_conn():
12
- conn = sqlite3.connect(DB_PATH)
13
- conn.row_factory = sqlite3.Row
14
- return conn
15
-
 
16
 
17
  def init_db():
18
  conn = get_conn()
@@ -49,84 +51,85 @@ def init_db():
49
  except:
50
  pass
51
  conn.commit()
52
- conn.close()
53
-
54
 
55
- init_db()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
 
 
 
 
 
57
 
58
- def process_and_store_posts(posts: List[Dict], player_matcher_module, get_player_team_func) -> tuple:
59
- posts_added = 0
60
- mentions_added = 0
61
  conn = get_conn()
62
  c = conn.cursor()
63
-
64
- print(f"Processing {len(posts)} posts...")
65
-
66
- for i, post in enumerate(posts):
67
- text = post.get("text", "")
68
- if not text:
69
- continue
70
-
71
- c.execute("INSERT OR IGNORE INTO posts (uri, author_handle, author_name, author_avatar, text, created_at, web_url, quote_post) VALUES (?,?,?,?,?,?,?,?)",
72
- (post.get("uri"), post.get("author_handle"), post.get("author_name"), post.get("author_avatar", ""), text, post.get("created_at"), post.get("web_url"),
73
- json.dumps(post.get("quote_post")) if post.get("quote_post") else None))
74
-
75
- if c.rowcount > 0:
76
- post_id = c.lastrowid
77
- posts_added += 1
78
-
79
- mentions = player_matcher_module.find_player_mentions(text)
80
- for player in mentions.keys():
81
- team = get_player_team_func(player)
82
- c.execute("INSERT OR IGNORE INTO mentions (post_id, player_name, team_name) VALUES (?,?,?)", (post_id, player, team))
83
- if c.rowcount > 0:
84
- mentions_added += 1
85
-
86
- # Progress every 1000 posts
87
- if (i + 1) % 1000 == 0:
88
- conn.commit()
89
- print(f"Processed {i + 1}/{len(posts)} posts ({posts_added} new, {mentions_added} mentions)")
90
-
91
- conn.commit()
92
- conn.close()
93
- print(f"Done: {posts_added} posts, {mentions_added} mentions")
94
- return posts_added, mentions_added
95
 
 
 
 
 
 
96
 
97
- def get_player_mention_counts(hours: int = 24, limit: int = 50) -> List[Dict]:
98
  conn = get_conn()
99
  c = conn.cursor()
100
  cutoff = (datetime.now(timezone.utc) - timedelta(hours=hours)).isoformat()
101
  c.execute("""
102
- SELECT m.player_name, m.team_name, COUNT(DISTINCT m.post_id) as mention_count
103
  FROM mentions m JOIN posts p ON m.post_id = p.id
104
  WHERE p.created_at >= ?
105
  GROUP BY m.player_name
106
  ORDER BY mention_count DESC
107
  LIMIT ?
108
  """, (cutoff, limit))
109
- results = [dict(row) for row in c.fetchall()]
110
- conn.close()
111
- return results
112
-
113
 
114
- def get_team_mention_counts(hours: int = 24, limit: int = 30) -> List[Dict]:
115
  conn = get_conn()
116
  c = conn.cursor()
117
  cutoff = (datetime.now(timezone.utc) - timedelta(hours=hours)).isoformat()
118
  c.execute("""
119
- SELECT m.team_name, COUNT(DISTINCT m.post_id) as mention_count
120
  FROM mentions m JOIN posts p ON m.post_id = p.id
121
- WHERE p.created_at >= ? AND m.team_name != ''
122
  GROUP BY m.team_name
123
  ORDER BY mention_count DESC
124
  LIMIT ?
125
  """, (cutoff, limit))
126
- results = [dict(row) for row in c.fetchall()]
127
- conn.close()
128
- return results
129
-
130
 
131
  def get_player_recent_mentions(player_name: str, limit: int = 50, hours: int = 168) -> List[Dict]:
132
  conn = get_conn()
@@ -147,18 +150,16 @@ def get_player_recent_mentions(player_name: str, limit: int = 50, hours: int = 1
147
  except:
148
  pass
149
  results.append({
150
- "author": r["author_name"] or r["author_handle"],
151
  "author_handle": r["author_handle"],
152
- "author_avatar": r["author_avatar"],
153
- "text": r["text"],
154
- "created_at": r["created_at"],
155
  "url": r["web_url"],
156
  "quote_post": quote
157
  })
158
- conn.close()
159
  return results
160
 
161
-
162
  def get_team_recent_mentions(team_name: str, limit: int = 50, hours: int = 168) -> List[Dict]:
163
  conn = get_conn()
164
  c = conn.cursor()
@@ -179,54 +180,50 @@ def get_team_recent_mentions(team_name: str, limit: int = 50, hours: int = 168)
179
  pass
180
  results.append({
181
  "player": r["player_name"],
182
- "author": r["author_name"] or r["author_handle"],
183
  "author_handle": r["author_handle"],
184
- "author_avatar": r["author_avatar"],
185
- "text": r["text"],
186
- "created_at": r["created_at"],
187
  "url": r["web_url"],
188
  "quote_post": quote
189
  })
190
- conn.close()
191
  return results
192
 
193
-
194
- def get_database_stats() -> Dict:
195
  conn = get_conn()
196
  c = conn.cursor()
197
- c.execute("SELECT COUNT(*) FROM posts")
198
- posts = c.fetchone()[0]
199
- c.execute("SELECT COUNT(*) FROM mentions")
200
- mentions = c.fetchone()[0]
201
- c.execute("SELECT COUNT(DISTINCT player_name) FROM mentions")
202
- players = c.fetchone()[0]
203
- conn.close()
204
- return {"total_posts": posts, "total_mentions": mentions, "unique_players": players}
205
-
206
-
207
- def get_last_update() -> Optional[str]:
208
- conn = get_conn()
209
- c = conn.cursor()
210
- c.execute("SELECT value FROM app_state WHERE key='last_update'")
211
  row = c.fetchone()
212
- conn.close()
213
- return row[0] if row else None
214
-
215
-
216
- def set_last_update():
217
- conn = get_conn()
218
- c = conn.cursor()
219
- c.execute("INSERT OR REPLACE INTO app_state (key, value) VALUES ('last_update', ?)",
220
- (datetime.now(timezone.utc).isoformat(),))
221
- conn.commit()
222
- conn.close()
223
-
224
-
225
- def cleanup_old_data(days: int = 3):
226
  conn = get_conn()
227
  c = conn.cursor()
228
- cutoff = (datetime.now(timezone.utc) - timedelta(days=days)).isoformat()
229
- c.execute("DELETE FROM mentions WHERE post_id IN (SELECT id FROM posts WHERE created_at < ?)", (cutoff,))
230
- c.execute("DELETE FROM posts WHERE created_at < ?", (cutoff,))
231
- conn.commit()
232
- conn.close()
 
 
 
 
 
 
 
 
 
 
1
+ """Database operations for NBA Buzz"""
2
 
3
  import sqlite3
4
  import json
5
  from datetime import datetime, timezone, timedelta
6
+ from typing import List, Dict
7
+ from nba_players import PLAYER_TEAMS
 
8
 
9
+ DB_PATH = "nba_buzz.db"
10
+ _conn = None
11
 
12
  def get_conn():
13
+ global _conn
14
+ if _conn is None:
15
+ _conn = sqlite3.connect(DB_PATH, check_same_thread=False)
16
+ _conn.row_factory = sqlite3.Row
17
+ return _conn
18
 
19
  def init_db():
20
  conn = get_conn()
 
51
  except:
52
  pass
53
  conn.commit()
 
 
54
 
55
+ def store_post(post: dict) -> int:
56
+ conn = get_conn()
57
+ c = conn.cursor()
58
+ quote_json = json.dumps(post.get("quote_post")) if post.get("quote_post") else None
59
+ try:
60
+ c.execute("""INSERT OR IGNORE INTO posts (uri, author_handle, author_name, author_avatar, text, created_at, web_url, quote_post)
61
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)""",
62
+ (post.get("uri"), post.get("author_handle"), post.get("author_name"),
63
+ post.get("author_avatar"), post.get("text"), post.get("created_at"),
64
+ post.get("web_url"), quote_json))
65
+ conn.commit()
66
+ if c.lastrowid:
67
+ return c.lastrowid
68
+ c.execute("SELECT id FROM posts WHERE uri = ?", (post.get("uri"),))
69
+ row = c.fetchone()
70
+ return row["id"] if row else None
71
+ except Exception as e:
72
+ print(f"Error storing post: {e}")
73
+ return None
74
+
75
+ def store_mention(post_id: int, player_name: str):
76
+ if not post_id:
77
+ return
78
+ conn = get_conn()
79
+ c = conn.cursor()
80
+ team = PLAYER_TEAMS.get(player_name)
81
+ try:
82
+ c.execute("INSERT OR IGNORE INTO mentions (post_id, player_name, team_name) VALUES (?, ?, ?)",
83
+ (post_id, player_name, team))
84
+ conn.commit()
85
+ except Exception as e:
86
+ print(f"Error storing mention: {e}")
87
 
88
+ def get_post_count() -> int:
89
+ conn = get_conn()
90
+ c = conn.cursor()
91
+ c.execute("SELECT COUNT(*) FROM posts")
92
+ return c.fetchone()[0]
93
 
94
+ def get_mention_count() -> int:
 
 
95
  conn = get_conn()
96
  c = conn.cursor()
97
+ c.execute("SELECT COUNT(*) FROM mentions")
98
+ return c.fetchone()[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
+ def get_unique_player_count() -> int:
101
+ conn = get_conn()
102
+ c = conn.cursor()
103
+ c.execute("SELECT COUNT(DISTINCT player_name) FROM mentions")
104
+ return c.fetchone()[0]
105
 
106
+ def get_top_players(hours: int = 24, limit: int = 50) -> List[Dict]:
107
  conn = get_conn()
108
  c = conn.cursor()
109
  cutoff = (datetime.now(timezone.utc) - timedelta(hours=hours)).isoformat()
110
  c.execute("""
111
+ SELECT m.player_name, m.team_name, COUNT(*) as mention_count
112
  FROM mentions m JOIN posts p ON m.post_id = p.id
113
  WHERE p.created_at >= ?
114
  GROUP BY m.player_name
115
  ORDER BY mention_count DESC
116
  LIMIT ?
117
  """, (cutoff, limit))
118
+ return [{"player": r["player_name"], "team": r["team_name"], "mentions": r["mention_count"]} for r in c.fetchall()]
 
 
 
119
 
120
+ def get_top_teams(hours: int = 24, limit: int = 30) -> List[Dict]:
121
  conn = get_conn()
122
  c = conn.cursor()
123
  cutoff = (datetime.now(timezone.utc) - timedelta(hours=hours)).isoformat()
124
  c.execute("""
125
+ SELECT m.team_name, COUNT(*) as mention_count
126
  FROM mentions m JOIN posts p ON m.post_id = p.id
127
+ WHERE m.team_name IS NOT NULL AND p.created_at >= ?
128
  GROUP BY m.team_name
129
  ORDER BY mention_count DESC
130
  LIMIT ?
131
  """, (cutoff, limit))
132
+ return [{"team": r["team_name"], "mentions": r["mention_count"]} for r in c.fetchall()]
 
 
 
133
 
134
  def get_player_recent_mentions(player_name: str, limit: int = 50, hours: int = 168) -> List[Dict]:
135
  conn = get_conn()
 
150
  except:
151
  pass
152
  results.append({
153
+ "author": r["author_name"] or r["author_handle"],
154
  "author_handle": r["author_handle"],
155
+ "author_avatar": r["author_avatar"],
156
+ "text": r["text"],
157
+ "created_at": r["created_at"],
158
  "url": r["web_url"],
159
  "quote_post": quote
160
  })
 
161
  return results
162
 
 
163
  def get_team_recent_mentions(team_name: str, limit: int = 50, hours: int = 168) -> List[Dict]:
164
  conn = get_conn()
165
  c = conn.cursor()
 
180
  pass
181
  results.append({
182
  "player": r["player_name"],
183
+ "author": r["author_name"] or r["author_handle"],
184
  "author_handle": r["author_handle"],
185
+ "author_avatar": r["author_avatar"],
186
+ "text": r["text"],
187
+ "created_at": r["created_at"],
188
  "url": r["web_url"],
189
  "quote_post": quote
190
  })
 
191
  return results
192
 
193
+ def get_player_latest_mention(player_name: str) -> dict:
194
+ """Get the most recent mention for a player."""
195
  conn = get_conn()
196
  c = conn.cursor()
197
+ c.execute("""
198
+ SELECT p.text, p.author_name, p.author_handle, p.created_at
199
+ FROM mentions m JOIN posts p ON m.post_id = p.id
200
+ WHERE m.player_name = ?
201
+ ORDER BY p.created_at DESC LIMIT 1
202
+ """, (player_name,))
 
 
 
 
 
 
 
 
203
  row = c.fetchone()
204
+ if row:
205
+ return {
206
+ "text": row["text"],
207
+ "author": row["author_name"] or row["author_handle"],
208
+ "created_at": row["created_at"]
209
+ }
210
+ return None
211
+
212
+ def get_team_latest_mention(team_name: str) -> dict:
213
+ """Get the most recent mention for a team."""
 
 
 
 
214
  conn = get_conn()
215
  c = conn.cursor()
216
+ c.execute("""
217
+ SELECT p.text, p.author_name, p.author_handle, p.created_at
218
+ FROM mentions m JOIN posts p ON m.post_id = p.id
219
+ WHERE m.team_name = ?
220
+ ORDER BY p.created_at DESC LIMIT 1
221
+ """, (team_name,))
222
+ row = c.fetchone()
223
+ if row:
224
+ return {
225
+ "text": row["text"],
226
+ "author": row["author_name"] or row["author_handle"],
227
+ "created_at": row["created_at"]
228
+ }
229
+ return None