first commit

This commit is contained in:
2026-04-20 11:56:11 +03:00
commit 8d80fadb56
103 changed files with 19756 additions and 0 deletions

View File

@@ -0,0 +1,424 @@
# services/vmix_json_service.py
from db import get_connection
from repositories.match_lineup_repository import get_match_lineup_for_vmix
def build_lineup_json(match_id, home_team_id, away_team_id, name, team_a_name, team_b_name):
lineups = get_match_lineup_for_vmix(
match_id=match_id,
home_team_id=home_team_id,
away_team_id=away_team_id,
)
players = lineups.get(name, [])
result = []
for p in players:
suffix = []
if "вратарь" in (p.get("pos") or "").lower():
suffix.append("ВР")
if p.get("is_captain"):
suffix.append("К")
number = p.get("number", "")
lastname = p.get("last_name", "")
suffix_str = f'({", ".join(suffix)})' if suffix else ""
result.append(
{
"number": p.get("number", ""),
"number_lastname_amp_K": f"{number} {lastname} {suffix_str}".strip(),
"first_name": p.get("first_name", ""),
"last_name": p.get("last_name", ""),
"number_fullname": f"{number} {p.get('first_name', '')} {p.get('last_name', '')}".strip(),
"full_name": (
p.get("first_name", "") + " " + p.get("last_name", "")
).strip(),
"full_name_K": (
p.get("first_name", "") + " " + p.get("last_name", "")
).strip()
+ (f" {', '.join(suffix)}" if suffix else ""),
"pos": p.get("pos", ""),
"position": p.get("position", ""),
"photo": (
r"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Photo"
+ "\\"
+ (team_a_name if "home" in name else team_b_name)
+ "\\"
+ (p.get("last_name", "")
+ " "
+ p.get("first_name", "")).strip()
+ ".png"
),
}
)
return {"players": result}
def get_vmix_match_info_by_token(session_token: str):
query = """
SELECT
ms.match_id,
m.match_date,
m.place,
m.stadium_id,
ht.id AS home_team_id,
ht.name AS home_team_name,
COALESCE(ht.full_name, ht.name) AS home_team_full_name,
COALESCE(ht.short_name_3, '') AS home_team_short_name,
at.id AS away_team_id,
at.name AS away_team_name,
COALESCE(at.full_name, at.name) AS away_team_full_name,
COALESCE(at.short_name_3, '') AS away_team_short_name,
COALESCE(s.stadium_gfx, s.name, m.place, '') AS stadium_name,
m.tour,
ht.logo_path AS home_logo,
REPLACE(at.logo_path, 'HOME', 'AWAY') AS away_logo,
ref1.referee_name AS referee1,
ref2.referee_name AS referee2,
ref3.referee_name AS referee3,
ref4.referee_name AS referee4,
CASE
WHEN ht.name ILIKE '%%динамо%%'
THEN REPLACE(REPLACE(ht.logo_path, 'HOME\\', ''), 'Динамо', 'Динамоелый')
WHEN ht.name ILIKE '%%зенит%%'
THEN REPLACE(REPLACE(ht.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Белый')
ELSE REPLACE(ht.logo_path, 'HOME\\', '')
END AS home_logo1,
CASE
WHEN at.name ILIKE '%%динамо%%'
THEN REPLACE(REPLACE(at.logo_path, 'HOME\\', ''), 'Динамо', 'Динамоелый')
WHEN at.name ILIKE '%%зенит%%'
THEN REPLACE(REPLACE(at.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Белый')
ELSE REPLACE(at.logo_path, 'HOME\\', '')
END AS away_logo1,
CASE
WHEN ht.name ILIKE '%%динамо%%'
THEN REPLACE(REPLACE(ht.logo_path, 'HOME\\', ''), 'Динамо', 'Динамо_Синий')
WHEN ht.name ILIKE '%%зенит%%'
THEN REPLACE(REPLACE(ht.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Синий')
ELSE REPLACE(ht.logo_path, 'HOME\\', '')
END AS home_logo2,
CASE
WHEN at.name ILIKE '%%динамо%%'
THEN REPLACE(REPLACE(at.logo_path, 'HOME\\', ''), 'Динамо', 'Динамо_Синий')
WHEN at.name ILIKE '%%зенит%%'
THEN REPLACE(REPLACE(at.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Синий')
ELSE REPLACE(at.logo_path, 'HOME\\', '')
END AS away_logo2,
ht.city AS home_city,
at.city AS away_city,
TRIM(COALESCE(c1.name, '') || ' ' || COALESCE(c1.lastname, '')) AS coach_name1,
c1.amplua AS coach_amplua1,
TRIM(COALESCE(c2.name, '') || ' ' || COALESCE(c2.lastname, '')) AS coach_name2,
c2.amplua AS coach_amplua2
FROM match_sessions ms
JOIN matches m ON m.id = ms.match_id
JOIN teams ht ON ht.id = m.home_team_id
JOIN teams at ON at.id = m.away_team_id
LEFT JOIN match_referees ref1 ON ref1.match_id = m.id AND ref1.role = 'Главный судья'
LEFT JOIN match_referees ref2 ON ref2.match_id = m.id AND ref2.role = 'Ассистент судьи №1'
LEFT JOIN match_referees ref3 ON ref3.match_id = m.id AND ref3.role = 'Ассистент судьи №2'
LEFT JOIN match_referees ref4 ON ref4.match_id = m.id AND ref4.role = 'Резервный судья'
LEFT JOIN match_coaches mc1 ON mc1.match_id = m.id AND mc1.side = 'home'
LEFT JOIN coaches c1 ON c1.id = mc1.coach_id
LEFT JOIN match_coaches mc2 ON mc2.match_id = m.id AND mc2.side = 'away'
LEFT JOIN coaches c2 ON c2.id = mc2.coach_id
LEFT JOIN stadiums s ON s.id = m.stadium_id
WHERE ms.session_token = %s
LIMIT 1;
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (session_token,))
return cur.fetchone()
finally:
conn.close()
def get_vmix_standings(session_token: str):
query = """
SELECT
s.position,
t.full_name,
CASE
WHEN t.full_name ILIKE '%%динамо%%'
THEN REPLACE(REPLACE(t.logo_path, 'HOME\\', ''), 'Динамо', 'Динамоелый')
WHEN t.full_name ILIKE '%%зенит%%'
THEN REPLACE(REPLACE(t.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Белый')
ELSE REPLACE(t.logo_path, 'HOME\\', '')
END AS logo,
s.played,
s.wins,
s.losses,
s.draws,
s.points_for || ' - ' || s.points_against AS score,
s.points,
s.team_id
FROM standings s
LEFT JOIN teams t ON s.team_id = t.id
ORDER BY s.position
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (session_token,))
return cur.fetchall()
finally:
conn.close()
def get_vmix_schedule(session_token: str):
query = """
SELECT
CASE
WHEN t1.full_name ILIKE '%%динамо%%'
THEN REPLACE(REPLACE(t1.logo_path, 'HOME\\', ''), 'Динамо', 'Динамоелый')
WHEN t1.full_name ILIKE '%%зенит%%'
THEN REPLACE(REPLACE(t1.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Белый')
ELSE REPLACE(t1.logo_path, 'HOME\\', '')
END AS logo1,
CASE
WHEN t2.full_name ILIKE '%%динамо%%'
THEN REPLACE(REPLACE(t2.logo_path, 'HOME\\', ''), 'Динамо', 'Динамоелый')
WHEN t2.full_name ILIKE '%%зенит%%'
THEN REPLACE(REPLACE(t2.logo_path, 'HOME\\', ''), 'Зенит', 'Зенит_Белый')
ELSE REPLACE(t2.logo_path, 'HOME\\', '')
END AS logo2,
m.home_score,
m.away_score,
m.match_date,
m.status,
m.id
FROM matches m
LEFT JOIN teams t1 ON m.home_team_id = t1.id
LEFT JOIN teams t2 ON m.away_team_id = t2.id
WHERE m.tour = %s
ORDER BY m.match_date, m.id
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (session_token[10],))
return cur.fetchall()
finally:
conn.close()
def get_vmix_team_formations(session_token: str, team_id: int):
query = """
SELECT
p.last_name,
mf.is_captain,
p.number,
p.position,
p.first_name
FROM match_formations mf
LEFT JOIN players p ON p.id = mf.player_id
WHERE mf.match_id = %s and mf.team_id = %s
ORDER BY mf.id
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (session_token[1], team_id))
return cur.fetchall()
finally:
conn.close()
def get_vmix_scoreboard_info(session_token: str):
query = """
WITH yellow_reds AS (
SELECT
side,
player_id
FROM match_events_ui
WHERE match_id = %s
AND type = 'yellow'
AND player_id IS NOT NULL
GROUP BY side, player_id
HAVING COUNT(*) >= 2
),
direct_reds AS (
SELECT
side,
COUNT(*) AS cnt
FROM match_events_ui
WHERE match_id = %s
AND type = 'red'
GROUP BY side
),
two_yellow_reds AS (
SELECT
side,
COUNT(*) AS cnt
FROM yellow_reds
GROUP BY side
),
red_totals AS (
SELECT
s.side,
COALESCE(dr.cnt, 0) + COALESCE(tyr.cnt, 0) AS red_count
FROM (
SELECT 'home' AS side
UNION ALL
SELECT 'away' AS side
) s
LEFT JOIN direct_reds dr ON dr.side = s.side
LEFT JOIN two_yellow_reds tyr ON tyr.side = s.side
)
SELECT
-- голы
COALESCE(SUM(
CASE
WHEN m.side = 'home' AND m.type IN ('goal', 'penalty', 'own_goal')
THEN 1 ELSE 0
END
), 0) AS home_goals,
COALESCE(SUM(
CASE
WHEN m.side = 'away' AND m.type IN ('goal', 'penalty', 'own_goal')
THEN 1 ELSE 0
END
), 0) AS away_goals,
-- домашние карточки
CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'home') >= 1 THEN '#FF0000' ELSE '#FF000000' END AS home_red_1,
CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'home') >= 2 THEN '#FF0000' ELSE '#FF000000' END AS home_red_2,
CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'home') >= 3 THEN '#FF0000' ELSE '#FF000000' END AS home_red_3,
CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'home') >= 4 THEN '#FF0000' ELSE '#FF000000' END AS home_red_4,
-- гостевые карточки
CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'away') >= 1 THEN '#FF0000' ELSE '#FF000000' END AS away_red_1,
CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'away') >= 2 THEN '#FF0000' ELSE '#FF000000' END AS away_red_2,
CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'away') >= 3 THEN '#FF0000' ELSE '#FF000000' END AS away_red_3,
CASE WHEN (SELECT red_count FROM red_totals WHERE side = 'away') >= 4 THEN '#FF0000' ELSE '#FF000000' END AS away_red_4
FROM match_events_ui m
WHERE m.match_id = %s;
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (session_token[1],session_token[1],session_token[1]))
return cur.fetchone()
finally:
conn.close()
def get_vmix_players_goal(match_id: int):
query = """
WITH goal_events AS (
SELECT
meu.side,
COALESCE(p.last_name, meu.player_name) AS last_name,
meu.seconds,
meu.id,
meu.type,
CASE
WHEN EXISTS (
SELECT 1
FROM match_events_ui m2
WHERE m2.match_id = meu.match_id
AND m2.type = 'period_start_2h'
AND m2.seconds <= meu.seconds
) THEN 2
WHEN EXISTS (
SELECT 1
FROM match_events_ui m2
WHERE m2.match_id = meu.match_id
AND m2.type = 'period_start_1h'
AND m2.seconds <= meu.seconds
) THEN 1
ELSE NULL
END AS period_no
FROM match_events_ui meu
LEFT JOIN players p ON p.id = meu.player_id
WHERE meu.match_id = %s
AND meu.type IN ('goal', 'penalty', 'own_goal')
),
grouped_players AS (
SELECT
side,
last_name,
MIN(seconds) AS first_goal_seconds,
STRING_AGG(
(
CASE
WHEN period_no = 1 AND seconds > 2700
THEN '45''' || '+ ' || ((seconds - 2700) / 60)::int::text
WHEN period_no = 2 AND seconds > 5400
THEN '90''' || '+ ' || ((seconds - 5400) / 60)::int::text
WHEN period_no = 2
THEN (46 + ((seconds - 2700) / 60)::int)::text || ''''
ELSE (1 + (seconds / 60)::int)::text || ''''
END
) ||
CASE
WHEN type = 'own_goal' THEN ' (АГ)'
WHEN type = 'penalty' THEN ' (П)'
ELSE ''
END,
', ' ORDER BY seconds, id
) AS goal_minutes
FROM goal_events
GROUP BY side, last_name
),
home_rows AS (
SELECT
ROW_NUMBER() OVER (ORDER BY first_goal_seconds, last_name) AS rn,
last_name || ' ' || goal_minutes AS player_name1
FROM grouped_players
WHERE side = 'home'
),
away_rows AS (
SELECT
ROW_NUMBER() OVER (ORDER BY first_goal_seconds, last_name) AS rn,
last_name || ' ' || goal_minutes AS player_name2
FROM grouped_players
WHERE side = 'away'
)
SELECT
COALESCE(h.player_name1, '') AS player_name1,
COALESCE(a.player_name2, '') AS player_name2
FROM home_rows h
FULL OUTER JOIN away_rows a ON a.rn = h.rn
ORDER BY COALESCE(h.rn, a.rn);
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (match_id,))
return cur.fetchall()
finally:
conn.close()