Files
WFL/repositories/player_repository.py
2026-04-22 13:02:49 +03:00

375 lines
9.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from db import get_connection
from repositories.team_repository import get_team_id_by_external_id
def normalize_birth_date_for_input(value) -> str:
if not value:
return ""
text = str(value).strip()
if not text:
return ""
# Уже нормальный формат для input[type=date]
if len(text) == 10 and text[4] == "-" and text[7] == "-":
return text
# Формат ДД.ММ.ГГГГ -> YYYY-MM-DD
if len(text) == 10 and text[2] == "." and text[5] == ".":
dd, mm, yyyy = text.split(".")
return f"{yyyy}-{mm}-{dd}"
return ""
def upsert_player(
external_id: str,
team_external_id: str,
player: str,
lastname: str = "",
name: str = "",
number: str = "",
pos: str = "",
amplua: str = "",
born: str = "",
games: int = 0,
goals: int = 0,
penaltys: int = 0,
assists: int = 0,
yellows: int = 0,
reds: int = 0,
is_active: bool = True,
) -> None:
team_id = get_team_id_by_external_id(str(team_external_id).strip())
if team_id is None:
raise ValueError(f"Team not found by external_id: {team_external_id}")
query = """
INSERT INTO players (
external_id,
team_id,
full_name,
first_name,
last_name,
number,
position,
is_active,
pos,
amplua,
born,
games,
goals,
penaltys,
assists,
yellows,
reds,
created_at,
updated_at
)
VALUES (
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
NOW(), NOW()
)
ON CONFLICT (external_id)
DO UPDATE SET
team_id = EXCLUDED.team_id,
full_name = EXCLUDED.full_name,
first_name = EXCLUDED.first_name,
last_name = EXCLUDED.last_name,
number = EXCLUDED.number,
position = EXCLUDED.position,
is_active = EXCLUDED.is_active,
pos = EXCLUDED.pos,
amplua = EXCLUDED.amplua,
born = EXCLUDED.born,
games = EXCLUDED.games,
goals = EXCLUDED.goals,
penaltys = EXCLUDED.penaltys,
assists = EXCLUDED.assists,
yellows = EXCLUDED.yellows,
reds = EXCLUDED.reds,
updated_at = NOW();
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(
query,
(
str(external_id).strip(),
team_id,
player.strip(),
name.strip(),
lastname.strip(),
str(number).strip(),
amplua.strip(),
is_active,
pos.strip(),
amplua.strip(),
born.strip(),
games,
goals,
penaltys,
assists,
yellows,
reds,
),
)
conn.commit()
except Exception:
conn.rollback()
raise
finally:
conn.close()
def get_match_by_external_id(external_id: str):
query = """
SELECT id, external_id, home_team_id, away_team_id
FROM matches
WHERE external_id = %s
LIMIT 1;
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (str(external_id).strip(),))
return cur.fetchone()
finally:
conn.close()
def mark_match_parsed(external_id: str) -> None:
query = """
UPDATE matches
SET parsed = TRUE,
parse_error = NULL,
updated_at = NOW()
WHERE external_id = %s;
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (str(external_id).strip(),))
conn.commit()
except Exception:
conn.rollback()
raise
finally:
conn.close()
def mark_match_parse_error(external_id: str, error_text: str) -> None:
query = """
UPDATE matches
SET parsed = FALSE,
parse_error = %s,
updated_at = NOW()
WHERE external_id = %s;
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (str(error_text)[:2000], str(external_id).strip()))
conn.commit()
except Exception:
conn.rollback()
raise
finally:
conn.close()
def get_player_id_by_name_and_team(full_name: str, team_id: int) -> int | None:
query = """
SELECT id
FROM players
WHERE team_id = %s
AND LOWER(full_name) = LOWER(%s)
LIMIT 1;
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (team_id, full_name.strip()))
row = cur.fetchone()
return row[0] if row else None
finally:
conn.close()
def get_player_id_by_external_id(external_id: str) -> int | None:
query = """
SELECT id,
position
FROM players
WHERE external_id = %s
LIMIT 1;
"""
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(query, (str(external_id).strip(),))
row = cur.fetchone()
return row if row else None
finally:
conn.close()
from db import get_connection
def search_players_for_admin(q: str = "") -> list[dict]:
conn = get_connection()
try:
with conn.cursor() as cur:
if q.strip():
pattern = f"%{q.strip()}%"
cur.execute(
"""
SELECT
p.id,
p.full_name,
p.first_name,
p.last_name,
p.external_id,
p.position
FROM players p
WHERE
p.full_name ILIKE %s
OR p.first_name ILIKE %s
OR p.last_name ILIKE %s
OR COALESCE(p.external_id, '') ILIKE %s
ORDER BY p.full_name ASC, p.id ASC
LIMIT 200
""",
(pattern, pattern, pattern, pattern),
)
else:
cur.execute(
"""
SELECT
p.id,
p.full_name,
p.first_name,
p.last_name,
p.external_id,
p.position
FROM players p
ORDER BY p.id DESC
LIMIT 200
"""
)
rows = cur.fetchall()
return [
{
"id": row[0],
"full_name": row[1] or "",
"first_name": row[2] or "",
"last_name": row[3] or "",
"external_id": row[4] or "",
"position": row[5] or "",
}
for row in rows
]
finally:
conn.close()
def get_player_by_id(player_id: int) -> dict | None:
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(
"""
SELECT
p.id,
p.full_name,
p.first_name,
p.last_name,
p.external_id,
p.position,
p.born,
p.photo,
p.video
FROM players p
WHERE p.id = %s
LIMIT 1
""",
(player_id,),
)
row = cur.fetchone()
if not row:
return None
return {
"id": row[0],
"full_name": row[1] or "",
"first_name": row[2] or "",
"last_name": row[3] or "",
"external_id": row[4] or "",
"position": row[5] or "",
"birth_date": normalize_birth_date_for_input(row[6]),
"photo": row[7] or "",
"video": row[8] or "",
}
finally:
conn.close()
def update_player_admin(
player_id: int,
full_name: str = "",
first_name: str = "",
last_name: str = "",
external_id: str = "",
position: str = "",
birth_date: str = "",
photo: str = "",
video: str = "",
) -> None:
conn = get_connection()
try:
with conn.cursor() as cur:
cur.execute(
"""
UPDATE players
SET
full_name = %s,
first_name = %s,
last_name = %s,
external_id = NULLIF(%s, ''),
position = %s,
born = NULLIF(%s, '')::date,
photo = NULLIF(%s, ''),
video = NULLIF(%s, '')
WHERE id = %s
""",
(
full_name.strip(),
first_name.strip(),
last_name.strip(),
external_id.strip(),
position.strip(),
birth_date.strip(),
photo.strip(),
video.strip(),
player_id,
),
)
conn.commit()
except Exception:
conn.rollback()
raise
finally:
conn.close()