2.0.0-rc1 : Profile and achievements update.
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
import json
|
||||
|
||||
from web.database import query_db
|
||||
from web.services.roster_version_service import RosterVersionService
|
||||
from web.services.team_context_service import TeamContextService
|
||||
|
||||
|
||||
class TeamPerformanceService:
|
||||
@staticmethod
|
||||
def _player_identity_map(steam_ids):
|
||||
if not steam_ids:
|
||||
return {}
|
||||
placeholders = ','.join('?' for _ in steam_ids)
|
||||
rows = query_db(
|
||||
'l2',
|
||||
f"""
|
||||
SELECT steam_id_64, username, avatar_url
|
||||
FROM dim_players
|
||||
WHERE steam_id_64 IN ({placeholders})
|
||||
""",
|
||||
steam_ids,
|
||||
)
|
||||
return {str(row['steam_id_64']): dict(row) for row in rows}
|
||||
|
||||
@staticmethod
|
||||
def get_team_summary():
|
||||
roster_ids = TeamContextService.get_active_roster_ids()
|
||||
if not roster_ids:
|
||||
return {
|
||||
'matches': 0,
|
||||
'wins': 0,
|
||||
'win_rate': 0,
|
||||
'avg_rating': 0,
|
||||
'maps': [],
|
||||
}
|
||||
placeholders = ','.join('?' for _ in roster_ids)
|
||||
rows = query_db(
|
||||
'l2',
|
||||
f"""
|
||||
SELECT
|
||||
p.match_id,
|
||||
CASE
|
||||
WHEN p.group_id IN (1, 2) THEN p.group_id
|
||||
WHEN p.team_id IN (1, 2) THEN p.team_id
|
||||
END AS team_key,
|
||||
COUNT(DISTINCT p.steam_id_64) AS roster_count,
|
||||
AVG(p.rating) AS avg_rating,
|
||||
MAX(p.is_win) AS is_win,
|
||||
m.map_name,
|
||||
m.start_time
|
||||
FROM fact_match_players p
|
||||
JOIN fact_matches m ON m.match_id = p.match_id
|
||||
WHERE p.steam_id_64 IN ({placeholders})
|
||||
GROUP BY p.match_id, team_key
|
||||
HAVING roster_count >= 2 AND team_key IS NOT NULL
|
||||
ORDER BY m.start_time DESC
|
||||
""",
|
||||
roster_ids,
|
||||
)
|
||||
matches = len(rows)
|
||||
wins = sum(int(row['is_win'] or 0) for row in rows)
|
||||
map_stats = {}
|
||||
for row in rows:
|
||||
item = map_stats.setdefault(
|
||||
row['map_name'] or 'Unknown',
|
||||
{'map_name': row['map_name'] or 'Unknown', 'matches': 0, 'wins': 0},
|
||||
)
|
||||
item['matches'] += 1
|
||||
item['wins'] += int(row['is_win'] or 0)
|
||||
maps = []
|
||||
for item in map_stats.values():
|
||||
item['win_rate'] = item['wins'] / item['matches']
|
||||
maps.append(item)
|
||||
maps.sort(key=lambda item: item['matches'], reverse=True)
|
||||
return {
|
||||
'matches': matches,
|
||||
'wins': wins,
|
||||
'losses': matches - wins,
|
||||
'win_rate': wins / matches if matches else 0,
|
||||
'avg_rating': (
|
||||
sum(float(row['avg_rating'] or 0) for row in rows) / matches
|
||||
if matches else 0
|
||||
),
|
||||
'maps': maps,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def get_current_roster():
|
||||
members = RosterVersionService.get_current_members()
|
||||
identities = TeamPerformanceService._player_identity_map(
|
||||
[member['steam_id_64'] for member in members]
|
||||
)
|
||||
result = []
|
||||
for member in members:
|
||||
item = dict(member)
|
||||
item.update(identities.get(str(member['steam_id_64']), {}))
|
||||
result.append(item)
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def get_top_duos(limit=12):
|
||||
rows = query_db(
|
||||
'l3',
|
||||
"""
|
||||
SELECT *
|
||||
FROM dm_duo_stats
|
||||
ORDER BY sample_reliable DESC, matches DESC,
|
||||
win_rate DESC, avg_combined_rating DESC
|
||||
LIMIT ?
|
||||
""",
|
||||
[limit],
|
||||
)
|
||||
steam_ids = {
|
||||
str(value)
|
||||
for row in rows
|
||||
for value in (row['steam_id_a'], row['steam_id_b'])
|
||||
}
|
||||
identities = TeamPerformanceService._player_identity_map(sorted(steam_ids))
|
||||
result = []
|
||||
for row in rows:
|
||||
item = dict(row)
|
||||
item['player_a'] = identities.get(str(row['steam_id_a']), {})
|
||||
item['player_b'] = identities.get(str(row['steam_id_b']), {})
|
||||
result.append(item)
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def get_top_lineups(player_count=None, limit=12):
|
||||
args = []
|
||||
where = ''
|
||||
if player_count:
|
||||
where = 'WHERE player_count = ?'
|
||||
args.append(int(player_count))
|
||||
args.append(limit)
|
||||
rows = query_db(
|
||||
'l3',
|
||||
f"""
|
||||
SELECT *
|
||||
FROM dm_lineup_stats
|
||||
{where}
|
||||
ORDER BY sample_reliable DESC, matches DESC,
|
||||
win_rate DESC, avg_team_rating DESC
|
||||
LIMIT ?
|
||||
""",
|
||||
args,
|
||||
)
|
||||
all_ids = set()
|
||||
parsed = []
|
||||
for row in rows:
|
||||
item = dict(row)
|
||||
item['player_ids'] = [
|
||||
str(value) for value in json.loads(item['player_ids_json'])
|
||||
]
|
||||
all_ids.update(item['player_ids'])
|
||||
parsed.append(item)
|
||||
identities = TeamPerformanceService._player_identity_map(sorted(all_ids))
|
||||
for item in parsed:
|
||||
item['players'] = [
|
||||
identities.get(steam_id, {'username': steam_id})
|
||||
for steam_id in item['player_ids']
|
||||
]
|
||||
return parsed
|
||||
|
||||
@staticmethod
|
||||
def get_dashboard():
|
||||
return {
|
||||
'summary': TeamPerformanceService.get_team_summary(),
|
||||
'roster': TeamPerformanceService.get_current_roster(),
|
||||
'versions': RosterVersionService.list_versions(),
|
||||
'duos': TeamPerformanceService.get_top_duos(),
|
||||
'lineups': TeamPerformanceService.get_top_lineups(),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user