1.6.2: Refreshed.

This commit is contained in:
2026-01-27 19:23:05 +08:00
parent 92ad093895
commit e019d3e458
4 changed files with 57 additions and 8 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -109,9 +109,12 @@ class OpponentService:
# Post-process for derived stats # Post-process for derived stats
results = [] results = []
for r in rows: # Resolve avatar fallback from local static if missing
from web.services.stats_service import StatsService
for r in rows or []:
d = dict(r) d = dict(r)
d['win_rate'] = (d['wins'] / d['matches']) if d['matches'] else 0 d['win_rate'] = (d['wins'] / d['matches']) if d['matches'] else 0
d['avatar_url'] = StatsService.resolve_avatar_url(d.get('steam_id_64'), d.get('avatar_url'))
results.append(d) results.append(d)
return results, total return results, total
@@ -209,6 +212,9 @@ class OpponentService:
info = query_db('l2', "SELECT * FROM dim_players WHERE steam_id_64 = ?", [steam_id], one=True) info = query_db('l2', "SELECT * FROM dim_players WHERE steam_id_64 = ?", [steam_id], one=True)
if not info: if not info:
return None return None
from web.services.stats_service import StatsService
player = dict(info)
player['avatar_url'] = StatsService.resolve_avatar_url(steam_id, player.get('avatar_url'))
# 2. Match History vs Us (All matches this player played) # 2. Match History vs Us (All matches this player played)
# We define "Us" as matches where this player is an opponent. # We define "Us" as matches where this player is an opponent.
@@ -333,7 +339,7 @@ class OpponentService:
}) })
return { return {
'player': info, 'player': player,
'history': processed_history, 'history': processed_history,
'elo_stats': elo_stats, 'elo_stats': elo_stats,
'side_stats': dict(side_stats) if side_stats else {} 'side_stats': dict(side_stats) if side_stats else {}

View File

@@ -1,7 +1,29 @@
from web.database import query_db from web.database import query_db, execute_db
from flask import current_app, url_for
import os
class StatsService: class StatsService:
@staticmethod @staticmethod
def resolve_avatar_url(steam_id, avatar_url):
try:
if avatar_url and str(avatar_url).strip():
return avatar_url
base = os.path.join(current_app.root_path, 'static', 'avatars')
# Check jpg/png in order
for ext in ('.jpg', '.png'):
fname = f"{steam_id}{ext}"
if os.path.exists(os.path.join(base, fname)):
url = url_for('static', filename=f'avatars/{fname}')
try:
# Persist fallback URL into L2 for future reads
execute_db('l2', "UPDATE dim_players SET avatar_url = ? WHERE steam_id_64 = ?", [url, str(steam_id)])
except Exception:
pass
return url
return None
except Exception:
return avatar_url
@staticmethod
def get_team_stats_summary(): def get_team_stats_summary():
""" """
Calculates aggregate statistics for matches where at least 2 roster members played together. Calculates aggregate statistics for matches where at least 2 roster members played together.
@@ -374,7 +396,13 @@ class StatsService:
WHERE mp.match_id = ? WHERE mp.match_id = ?
ORDER BY mp.team_id, mp.rating DESC ORDER BY mp.team_id, mp.rating DESC
""" """
return query_db('l2', sql, [match_id]) rows = query_db('l2', sql, [match_id])
result = []
for r in rows or []:
d = dict(r)
d['avatar_url'] = StatsService.resolve_avatar_url(d.get('steam_id_64'), d.get('avatar_url'))
result.append(d)
return result
@staticmethod @staticmethod
def get_match_rounds(match_id): def get_match_rounds(match_id):
@@ -411,7 +439,12 @@ class StatsService:
""" """
args.extend([per_page, offset]) args.extend([per_page, offset])
players = query_db('l2', sql, args) rows = query_db('l2', sql, args)
players = []
for r in rows or []:
d = dict(r)
d['avatar_url'] = StatsService.resolve_avatar_url(d.get('steam_id_64'), d.get('avatar_url'))
players.append(d)
total = query_db('l2', f"SELECT COUNT(*) as cnt FROM dim_players WHERE {where_str}", args[:-2], one=True)['cnt'] total = query_db('l2', f"SELECT COUNT(*) as cnt FROM dim_players WHERE {where_str}", args[:-2], one=True)['cnt']
return players, total return players, total
@@ -419,7 +452,12 @@ class StatsService:
@staticmethod @staticmethod
def get_player_info(steam_id): def get_player_info(steam_id):
sql = "SELECT * FROM dim_players WHERE steam_id_64 = ?" sql = "SELECT * FROM dim_players WHERE steam_id_64 = ?"
return query_db('l2', sql, [steam_id], one=True) r = query_db('l2', sql, [steam_id], one=True)
if not r:
return None
d = dict(r)
d['avatar_url'] = StatsService.resolve_avatar_url(steam_id, d.get('avatar_url'))
return d
@staticmethod @staticmethod
def get_daily_match_counts(days=365): def get_daily_match_counts(days=365):
@@ -442,7 +480,13 @@ class StatsService:
return [] return []
placeholders = ','.join('?' for _ in steam_ids) placeholders = ','.join('?' for _ in steam_ids)
sql = f"SELECT * FROM dim_players WHERE steam_id_64 IN ({placeholders})" sql = f"SELECT * FROM dim_players WHERE steam_id_64 IN ({placeholders})"
return query_db('l2', sql, steam_ids) rows = query_db('l2', sql, steam_ids)
result = []
for r in rows or []:
d = dict(r)
d['avatar_url'] = StatsService.resolve_avatar_url(d.get('steam_id_64'), d.get('avatar_url'))
result.append(d)
return result
@staticmethod @staticmethod
def get_player_basic_stats(steam_id): def get_player_basic_stats(steam_id):
@@ -841,4 +885,3 @@ class StatsService:
result[r_num]['economy'][sid] = dict(eco) result[r_num]['economy'][sid] = dict(eco)
return result return result