2586 lines
110 KiB
Python
2586 lines
110 KiB
Python
import os
|
||
import json
|
||
import time
|
||
import logging
|
||
import logging.config
|
||
import urllib3
|
||
import argparse
|
||
import datetime
|
||
import platform
|
||
import requests
|
||
import numpy as np
|
||
import pandas as pd
|
||
from threading import Event, Thread
|
||
from telegram_handler import TelegramHandler
|
||
from concurrent.futures import ThreadPoolExecutor
|
||
|
||
urllib3.disable_warnings()
|
||
myhost = platform.node()
|
||
VERSION = "v.1 (7) 12.12.2024"
|
||
TAGS = [
|
||
{"tag": "vtb", "name": "Единая Лига ВТБ", "lang": "en"},
|
||
{"tag": "vtbyouth", "name": "Молодежка ВТБ", "lang": ""},
|
||
{"tag": "rfb-deti", "name": "Дети", "lang": ""},
|
||
{"tag": "rfb-silent", "name": "Тихий!баскетбол", "lang": ""},
|
||
{"tag": "orgRoot", "name": "Все соревнования", "lang": ""},
|
||
{"tag": "vtb-supercup", "name": "Супер-Кубок ЕЛ ВТБ", "lang": ""},
|
||
{"tag": "uba-leto", "name": "UBA лето", "lang": "ru"},
|
||
{"tag": "phygital-russia-cup-m", "name": "Фиджитал кубок", "lang": "ru"},
|
||
{"tag": "phygital", "name": "Фиджитал", "lang": "ru"},
|
||
{"tag": "3x3Root", "name": "3х3", "lang": "ru"},
|
||
{"tag": "LS3x3", "name": "Лига Сильных 3х3", "lang": "ru"},
|
||
{"tag": "uba", "name": "ЮБА", "lang": "ru"},
|
||
{"tag": "uba-main", "name": "ЮБА-маин", "lang": "ru"},
|
||
{"tag": "msl", "name": "Суперлига. Мужчины", "lang": ""},
|
||
{"tag": "mhl", "name": "Высшая лига. Мужчины", "lang": ""},
|
||
{"tag": "mcup", "name": "Кубок России. Мужчины", "lang": ""},
|
||
{"tag": "wpremier", "name": "Премьер-Лига. Женщины", "lang": ""},
|
||
{"tag": "wsl", "name": "Суперлига. Женщины", "lang": ""},
|
||
{"tag": "whl", "name": "Высшая лига. Женщины", "lang": ""},
|
||
{"tag": "wcup", "name": "Кубок России. Женщины", "lang": ""},
|
||
{"tag": "uba-summer", "name": "UBA Leto", "lang": "ru"},
|
||
{"tag": "unics", "name": "UNICS", "lang": "ru"},
|
||
]
|
||
TOKEN = "7639240596:AAH0YtdQoWZSC-_R_EW4wKAHHNLIA0F_ARY"
|
||
GROUP_CHAT = 228977654
|
||
|
||
# Используем argparse для обработки аргументов командной строки
|
||
parser = argparse.ArgumentParser(description="VTB Data Fetcher")
|
||
parser.add_argument("--league", type=str, default="vtb", help="League tag")
|
||
parser.add_argument("--lang", type=str, default="en", help="Language")
|
||
parser.add_argument("--team", type=str, default=None, help="Team")
|
||
args = parser.parse_args()
|
||
|
||
LEAGUE = args.league
|
||
LANG = args.lang
|
||
TEAM = args.team
|
||
|
||
# Глобальные параметры таймаута (в секундах)
|
||
TIMEOUT_STANDINGS = 1 # Интервал для обновления турнирной таблицы
|
||
TIMEOUT_GAME = 120 # Интервал для обновления расписания
|
||
|
||
LOG_CONFIG = {
|
||
"version": 1,
|
||
"handlers": {
|
||
"telegram": {
|
||
"class": "telegram_handler.TelegramHandler",
|
||
"level": "INFO",
|
||
"token": TOKEN,
|
||
"chat_id": GROUP_CHAT,
|
||
"formatter": "telegram",
|
||
},
|
||
"console": {
|
||
"class": "logging.StreamHandler",
|
||
"level": "DEBUG",
|
||
"formatter": "simple",
|
||
"stream": "ext://sys.stdout",
|
||
},
|
||
"file": {
|
||
"class": "logging.FileHandler",
|
||
"level": "DEBUG",
|
||
"formatter": "simple",
|
||
"filename": f"logs/GFX_{myhost}.log",
|
||
"encoding": "utf-8",
|
||
},
|
||
},
|
||
"loggers": {
|
||
__name__: {"handlers": ["console", "file", "telegram"], "level": "DEBUG"},
|
||
},
|
||
"formatters": {
|
||
"telegram": {
|
||
"class": "telegram_handler.HtmlFormatter",
|
||
"format": "%(levelname)s %(message)s",
|
||
"use_emoji": "True",
|
||
},
|
||
"simple": {
|
||
"class": "logging.Formatter",
|
||
"format": "%(asctime)s %(levelname)-8s %(funcName)12s() - %(message)s",
|
||
"datefmt": "%d.%m.%Y %H:%M:%S",
|
||
},
|
||
},
|
||
}
|
||
|
||
if not os.path.exists("logs"):
|
||
os.makedirs("logs")
|
||
if not os.path.exists("JSON"):
|
||
os.makedirs("JSON")
|
||
|
||
logging.config.dictConfig(LOG_CONFIG)
|
||
logger = logging.getLogger(__name__)
|
||
logger.handlers[2].formatter.use_emoji = True
|
||
pd.set_option("display.max_rows", None)
|
||
|
||
if TEAM is None:
|
||
logger.critical(f"{myhost}\nКоманда не указана")
|
||
time.sleep(3)
|
||
exit(1)
|
||
|
||
logger.info(
|
||
f"{myhost}\n!!!!!!!!СТАРТ!!!!!!!!! \nHOST: <b>{TEAM}</b>\nTAG: <b>{LEAGUE}</b>"
|
||
)
|
||
|
||
if LANG is None:
|
||
LANG = next(
|
||
(tag["lang"] for tag in TAGS if tag["tag"].lower() == LEAGUE.lower()), ""
|
||
)
|
||
|
||
URL = (
|
||
"https://basket.sportoteka.org/"
|
||
if "uba" in LEAGUE.lower()
|
||
# else "https://deti.russiabasket.org/"
|
||
else "https://pro.russiabasket.org/"
|
||
)
|
||
|
||
stat_name_list = [
|
||
("points", "Очки", "points"),
|
||
("pt-1", "Штрафные", "free throws"),
|
||
("pt-1_pro", "штрафные, процент", "free throws pro"),
|
||
("pt-2", "2-очковые", "2-points"),
|
||
("pt-2_pro", "2-очковые, процент", "2-points pro"),
|
||
("pt-3", "3-очковые", "3-points"),
|
||
("pt-3_pro", "3-очковые, процент", "3-points pro"),
|
||
("fg", "очки с игры", "field goals"),
|
||
("fg_pro", "Очки с игры, процент", "field goals pro"),
|
||
("assist", "Передачи", "assists"),
|
||
("pass", "", ""),
|
||
("defReb", "подборы в защите", ""),
|
||
("offReb", "подборы в нападении", ""),
|
||
("Reb", "Подборы", "rebounds"),
|
||
("steal", "Перехваты", "steals"),
|
||
("block", "Блокшоты", "blocks"),
|
||
("blocked", "", ""),
|
||
("turnover", "Потери", "turnovers"),
|
||
("foul", "Фолы", "fouls"),
|
||
("foulsOn", "", ""),
|
||
("foulT", "", ""),
|
||
("foulD", "", ""),
|
||
("foulC", "", ""),
|
||
("foulB", "", ""),
|
||
("second", "секунды", "seconds"),
|
||
("dunk", "данки", "dunks"),
|
||
("fastBreak", "", "fast breaks"),
|
||
("plusMinus", "+/-", "+/-"),
|
||
("avgAge", "", "avg Age"),
|
||
("ptsBench", "", "Bench PTS"),
|
||
("ptsBench_pro", "", "Bench PTS, %"),
|
||
("ptsStart", "", "Start PTS"),
|
||
("ptsStart_pro", "", "Start PTS, %"),
|
||
("avgHeight", "", "avg height"),
|
||
("timeout_left", "", "timeout left"),
|
||
("timeout_str", "", "timeout str"),
|
||
]
|
||
|
||
|
||
def get_json(url):
|
||
try:
|
||
logger.debug(f"Пытаюсь получить данные: {url}")
|
||
response = requests.get(url, verify=False, timeout=10)
|
||
if response.status_code == 200:
|
||
return response.json()
|
||
except requests.RequestException as e:
|
||
logger.warning(f"{myhost}\n{url}: {e}")
|
||
return None
|
||
|
||
|
||
def get_season_and_schedule():
|
||
try:
|
||
url = f"{URL}api/abc/comps/seasons?Tag={LEAGUE}&Lang={LANG}"
|
||
data = get_json(url)
|
||
|
||
if data and "result" in data and data["result"]:
|
||
season = data["result"][0]["season"]
|
||
schedule_url = f"{URL}api/abc/comps/calendar?Tag={LEAGUE}&Season={season}&Lang={LANG}&MaxResultCount=1000"
|
||
schedule = get_json(schedule_url)
|
||
|
||
if schedule and "items" in schedule:
|
||
df_schedule = pd.json_normalize(schedule["items"])
|
||
|
||
df_schedule["game.DateStr"] = df_schedule["game.localDate"]
|
||
# Преобразование дат для корректного сравнения
|
||
df_schedule["game.localDate"] = pd.to_datetime(
|
||
df_schedule["game.localDate"], format="%d.%m.%Y"
|
||
)
|
||
# print(f"befor pada{df_schedule['game.localDate']}")
|
||
current_date = datetime.datetime.now().strftime("%d.%m.%Y")
|
||
current_date = pd.to_datetime(current_date, format="%d.%m.%Y")
|
||
|
||
df_schedule["team1.name"] = df_schedule["team1.name"].str.strip()
|
||
# Фильтрация данных
|
||
df_schedule = df_schedule[
|
||
(df_schedule["game.localDate"] <= current_date)
|
||
& (df_schedule["team1.name"].str.lower() == TEAM.lower())
|
||
].iloc[-1]
|
||
data = {
|
||
"season": season,
|
||
"game_id": df_schedule["game.id"],
|
||
"team1_id": df_schedule["team1.teamId"],
|
||
"team2_id": df_schedule["team2.teamId"],
|
||
"team1": df_schedule["team1.name"],
|
||
"team2": df_schedule["team2.name"],
|
||
"when": df_schedule["game.DateStr"],
|
||
"time": df_schedule["game.localTime"],
|
||
}
|
||
return data
|
||
else:
|
||
logger.warning("Season or schedule data missing.")
|
||
except Exception as e:
|
||
logger.error(f"Error fetching season or schedule: {e}")
|
||
|
||
|
||
def is_file_locked(filepath):
|
||
try:
|
||
# Попытаемся открыть файл в режиме записи (перезапись)
|
||
with open(filepath, "w"):
|
||
pass
|
||
return False # Если получилось открыть, файл не заблокирован
|
||
except IOError:
|
||
return True # Если произошла ошибка, файл заблокирован
|
||
|
||
|
||
def rewrite_file(filepath, data):
|
||
filepath = f"JSON/{filepath}.json"
|
||
with open(filepath, "w", encoding="utf-8") as data_file:
|
||
json.dump(data, data_file, ensure_ascii=False, indent=4)
|
||
logger.debug(f"Файл {filepath} успешно перезаписан.")
|
||
|
||
|
||
def Team_Stat_Game(team_id, game_id):
|
||
game = Game_Online(game_id)
|
||
if game["result"]["teams"][1]["teamId"] == int(team_id):
|
||
logger.debug(f"send {game['result']['team1']['name']}")
|
||
result = game["result"]["teams"][1]
|
||
else:
|
||
logger.debug(f"send {game['result']['team2']['name']}")
|
||
result = game["result"]["teams"][2]
|
||
return result
|
||
|
||
|
||
def Player_Stat_Game(player_id, game_id):
|
||
pass
|
||
|
||
|
||
def Team_Stat_Season(team_id, season):
|
||
pass
|
||
|
||
|
||
def Player_Stat_Season(player_id, season):
|
||
url = f"{URL}api/abc/players/stats?teamId=0&Tag={LEAGUE}&season={season}&Id={player_id}"
|
||
player_stat_season = requests.get(url)
|
||
logger.debug(f"API response OK!!!")
|
||
if player_stat_season.status_code == 200:
|
||
player_stat_season = player_stat_season.json()
|
||
if player_stat_season["items"]:
|
||
player_stat_season = player_stat_season["items"][-2:]
|
||
logger.debug(f"Данные на сезон для игрока: {player_id} получены!!!")
|
||
return {player_id: player_stat_season}
|
||
else:
|
||
logger.debug(
|
||
f"Не нашел на {player_id} данные. Скорее всего еще не играл в сезоне."
|
||
)
|
||
return {
|
||
player_id: [
|
||
{
|
||
"team": None,
|
||
"game": None,
|
||
"stats": {
|
||
"games": 0,
|
||
"isStarts": "",
|
||
"points": "",
|
||
"goal2": "",
|
||
"shot2": "",
|
||
"goal3": "",
|
||
"shot3": "",
|
||
"goal1": "",
|
||
"shot1": "",
|
||
"goal23": "",
|
||
"shot23": "",
|
||
"shot2Percent": "",
|
||
"shot3Percent": "",
|
||
"shot23Percent": "",
|
||
"shot1Percent": "",
|
||
"assist": "",
|
||
"pass": "",
|
||
"steal": "",
|
||
"blockShot": "",
|
||
"blockedOwnShot": "",
|
||
"defRebound": "",
|
||
"offRebound": "",
|
||
"rebound": "",
|
||
"foulsOnPlayer": "",
|
||
"turnover": "",
|
||
"foul": "",
|
||
"second": 0,
|
||
"playedTime": "",
|
||
"dunk": "",
|
||
"fastBreak": "",
|
||
"plusMinus": None,
|
||
},
|
||
"class": "Sum",
|
||
},
|
||
{
|
||
"team": None,
|
||
"game": None,
|
||
"stats": {
|
||
"games": 0,
|
||
"isStarts": "",
|
||
"points": "",
|
||
"goal2": "",
|
||
"shot2": "",
|
||
"goal3": "",
|
||
"shot3": "",
|
||
"goal1": "",
|
||
"shot1": "",
|
||
"goal23": "",
|
||
"shot23": "",
|
||
"shot2Percent": "",
|
||
"shot3Percent": "",
|
||
"shot23Percent": "",
|
||
"shot1Percent": "",
|
||
"assist": "",
|
||
"pass": "",
|
||
"steal": "",
|
||
"blockShot": "",
|
||
"blockedOwnShot": "",
|
||
"defRebound": "",
|
||
"offRebound": "",
|
||
"rebound": "",
|
||
"foulsOnPlayer": "",
|
||
"turnover": "",
|
||
"foul": "",
|
||
"second": 0,
|
||
"playedTime": "",
|
||
"dunk": "",
|
||
"fastBreak": "",
|
||
"plusMinus": None,
|
||
},
|
||
"class": "Avg",
|
||
},
|
||
]
|
||
}
|
||
|
||
|
||
def Player_Stat_Career(player_id):
|
||
url = f"{URL}api/abc/players/career?teamId=0&Tag={LEAGUE}&Id={player_id}"
|
||
player_stat_career = requests.get(url)
|
||
logger.debug(f"API response OK!!!")
|
||
if player_stat_career.status_code == 200:
|
||
player_stat_career = player_stat_career.json()
|
||
if player_stat_career["items"]:
|
||
logger.debug(f"Данные за карьеру на игрока: {player_id} получены!!!")
|
||
player_stat_career = player_stat_career["items"][-2:]
|
||
return {player_id: player_stat_career}
|
||
else:
|
||
logger.debug(f"Не нашел на {player_id} данные. Скорее всего новичок")
|
||
return {
|
||
player_id: [
|
||
{
|
||
"season": None,
|
||
"team": None,
|
||
"stats": {
|
||
"games": 0,
|
||
"isStarts": "",
|
||
"points": "",
|
||
"goal2": "",
|
||
"shot2": "",
|
||
"goal3": "",
|
||
"shot3": "",
|
||
"goal1": "",
|
||
"shot1": "",
|
||
"goal23": "",
|
||
"shot23": "",
|
||
"shot2Percent": "",
|
||
"shot3Percent": "",
|
||
"shot23Percent": "",
|
||
"shot1Percent": "",
|
||
"assist": "",
|
||
"pass": "",
|
||
"steal": "",
|
||
"blockShot": "",
|
||
"blockedOwnShot": "",
|
||
"defRebound": "",
|
||
"offRebound": "",
|
||
"rebound": "",
|
||
"foulsOnPlayer": "",
|
||
"turnover": "",
|
||
"foul": "",
|
||
"second": 0,
|
||
"playedTime": "",
|
||
"dunk": "",
|
||
"fastBreak": "",
|
||
"plusMinus": None,
|
||
},
|
||
"class": "Sum",
|
||
},
|
||
{
|
||
"season": None,
|
||
"team": None,
|
||
"stats": {
|
||
"games": 0,
|
||
"isStarts": "",
|
||
"points": "",
|
||
"goal2": "",
|
||
"shot2": "",
|
||
"goal3": "",
|
||
"shot3": "",
|
||
"goal1": "",
|
||
"shot1": "",
|
||
"goal23": "",
|
||
"shot23": "",
|
||
"shot2Percent": "",
|
||
"shot3Percent": "",
|
||
"shot23Percent": "",
|
||
"shot1Percent": "",
|
||
"assist": "",
|
||
"pass": "",
|
||
"steal": "",
|
||
"blockShot": "",
|
||
"blockedOwnShot": "",
|
||
"defRebound": "",
|
||
"offRebound": "",
|
||
"rebound": "",
|
||
"foulsOnPlayer": "",
|
||
"turnover": "",
|
||
"foul": "",
|
||
"second": 0,
|
||
"playedTime": "",
|
||
"dunk": "",
|
||
"fastBreak": "",
|
||
"plusMinus": None,
|
||
},
|
||
"class": "Avg",
|
||
},
|
||
]
|
||
}
|
||
|
||
|
||
def format_time(seconds):
|
||
minutes = int(seconds // 60)
|
||
seconds = int(seconds % 60)
|
||
return f"{minutes:01}:{seconds:02}"
|
||
|
||
|
||
def Coach_Stat(coach_id, season, team_id):
|
||
url = f"{URL}api/abc/coaches/career?teamId={team_id}&tag={LEAGUE}&season={season}&Id={coach_id}"
|
||
coach_stat = requests.get(url)
|
||
logger.debug(f"API response OK!!!")
|
||
if coach_stat.status_code == 200:
|
||
coach_stat = coach_stat.json()
|
||
if coach_stat["items"]:
|
||
logger.debug(f"Данные за карьеру на тренера: {coach_id} получены!!!")
|
||
coach_stat = coach_stat["items"]
|
||
return {coach_id: coach_stat}
|
||
else:
|
||
logger.debug(f"Не нашел на {coach_id} данные. Скорее всего новичок")
|
||
return None
|
||
|
||
|
||
def coach_team_stat(data, team_id):
|
||
games = 0
|
||
wins = 0
|
||
loses = 0
|
||
gamesAsCoach = 0
|
||
winsAsCoach = 0
|
||
losesAsCoach = 0
|
||
season = 0
|
||
if data:
|
||
for d in data:
|
||
if d["team"] and d["team"]["id"] == team_id:
|
||
season += 1
|
||
games += d["games"]
|
||
wins += d["wins"]
|
||
loses += d["loses"]
|
||
gamesAsCoach += d["games"]
|
||
winsAsCoach += d["wins"]
|
||
losesAsCoach += d["loses"]
|
||
team_stat = {
|
||
"games": games,
|
||
"wins": wins,
|
||
"loses": loses,
|
||
"gamesAsCoach": gamesAsCoach,
|
||
"winsAsCoach": winsAsCoach,
|
||
"losesAsCoach": losesAsCoach,
|
||
"season": season,
|
||
}
|
||
return team_stat
|
||
|
||
|
||
def safe_int(value, default=0):
|
||
try:
|
||
return int(value)
|
||
except (ValueError, TypeError):
|
||
return default
|
||
|
||
|
||
def Json_Team_Generation(who, data, event):
|
||
logger.info(f"START making json for {data[who]}, {data[f'{who}_id']}")
|
||
|
||
payload = Team_Stat_Game(f'{data[f"{who}_id"]}', data["game_id"])
|
||
# print(payload)
|
||
# получаю ID игроков
|
||
player_ids = [
|
||
i["personId"] for i in payload["starts"] if i["startRole"] == "Player"
|
||
]
|
||
print(player_ids)
|
||
coach_ids = [i["personId"] for i in payload["starts"] if i["startRole"] == "Coach"]
|
||
print(coach_ids)
|
||
|
||
url = f"{URL}api/abc/games/live-status?id={data['game_id']}"
|
||
# print(url)
|
||
json_live_status = requests.get(url)
|
||
json_live_status = json_live_status.json()
|
||
online = (
|
||
True
|
||
if "status" in json_live_status
|
||
and json_live_status["status"] == "Ok"
|
||
and json_live_status["result"]["gameStatus"] == "Online"
|
||
else False
|
||
)
|
||
online = True
|
||
|
||
# получаю статистику на игроков по сезону и карьере
|
||
player_season_stat = []
|
||
player_career_stat = []
|
||
coach_stat = []
|
||
with ThreadPoolExecutor() as pool:
|
||
player_season_stat_temp = [
|
||
pool.submit(Player_Stat_Season, player_id, data["season"])
|
||
for player_id in player_ids
|
||
]
|
||
player_career_stat_temp = [
|
||
pool.submit(Player_Stat_Career, player_id) for player_id in player_ids
|
||
]
|
||
coach_stat_temp = [
|
||
pool.submit(Coach_Stat, coach_id, data["season"], data[f"{who}_id"])
|
||
for coach_id in coach_ids
|
||
]
|
||
player_season_stat += [res.result() for res in player_season_stat_temp]
|
||
player_career_stat += [res.result() for res in player_career_stat_temp]
|
||
coach_stat += [res.result() for res in coach_stat_temp]
|
||
while not event.is_set():
|
||
payload = Team_Stat_Game(f'{data[f"{who}_id"]}', data["game_id"])
|
||
role_list = [
|
||
("Center", "C"),
|
||
("Guard", "G"),
|
||
("Forward", "F"),
|
||
("Power Forward", "PF"),
|
||
("Small Forward", "SF"),
|
||
("Shooting Guard", "SG"),
|
||
("Point Guard", "PG"),
|
||
("Forward-Center", "FC"),
|
||
]
|
||
starts = payload["starts"]
|
||
HeadCoachStatsCareer, HeadCoachStatsTeam = "", ""
|
||
team = []
|
||
for item in starts:
|
||
# print(player_season_stat)
|
||
|
||
row_player_season = next(
|
||
(
|
||
v
|
||
for row in player_season_stat
|
||
for k, v in row.items()
|
||
if k == item["personId"]
|
||
),
|
||
None,
|
||
)
|
||
row_player_career = next(
|
||
(
|
||
v
|
||
for row in player_career_stat
|
||
for k, v in row.items()
|
||
if k == item["personId"]
|
||
),
|
||
None,
|
||
)
|
||
row_coach_stat = next(
|
||
(
|
||
v
|
||
for row in coach_stat
|
||
for k, v in row.items()
|
||
if k == item["personId"]
|
||
),
|
||
None,
|
||
)
|
||
row_player_season_avg, row_player_season_sum = (
|
||
(
|
||
next(
|
||
(r["stats"] for r in row_player_season if r["class"] == "Avg"),
|
||
None,
|
||
),
|
||
next(
|
||
(r["stats"] for r in row_player_season if r["class"] == "Sum"),
|
||
None,
|
||
),
|
||
)
|
||
if row_player_season
|
||
else (None, None)
|
||
)
|
||
row_player_career_avg, row_player_career_sum = (
|
||
(
|
||
next(
|
||
(r["stats"] for r in row_player_career if r["class"] == "Avg"),
|
||
None,
|
||
),
|
||
next(
|
||
(r["stats"] for r in row_player_career if r["class"] == "Sum"),
|
||
None,
|
||
),
|
||
)
|
||
if row_player_career
|
||
else (None, None)
|
||
)
|
||
if row_coach_stat:
|
||
games_word = (
|
||
"game" if row_coach_stat[-1]["games"] in [0, 1] else "games"
|
||
)
|
||
total_season = len(row_coach_stat) - 1
|
||
season_word = "season" if total_season == 1 else "seasons"
|
||
procent = (
|
||
round(
|
||
(row_coach_stat[-1]["wins"] * 100)
|
||
/ row_coach_stat[-1]["games"],
|
||
1,
|
||
)
|
||
if row_coach_stat[-1]["games"] != 0
|
||
else ""
|
||
)
|
||
# HeadCoachStatsCareer = (
|
||
# f'{row_s["total_seasons"]} {season_word} in The VTB United League career'
|
||
# )
|
||
HeadCoachStatsCareer = "in The VTB United League career"
|
||
if total_season == 0:
|
||
HeadCoachStatsCareer = f'{row_coach_stat[-1]["games"] if row_coach_stat[-1]["games"] != 0 else "first"} {games_word} as {data[who]} head coach'
|
||
HeadCoachStatsCareer += (
|
||
f'\n{row_coach_stat[-1]["games"] if row_coach_stat[-1]["games"] != 0 else "first"} {games_word}: {row_coach_stat[-1]["wins"]}-{row_coach_stat[-1]["loses"]} ({procent}% wins)'
|
||
if row_coach_stat[-1]["games"] != 0
|
||
else ""
|
||
)
|
||
coach_team_stat_temp = coach_team_stat(
|
||
row_coach_stat, data[f"{who}_id"]
|
||
)
|
||
games_word_team = (
|
||
"game" if coach_team_stat_temp["games"] in [0, 1] else "games"
|
||
)
|
||
season_word_team = (
|
||
"season" if coach_team_stat_temp["season"] == 1 else "seasons"
|
||
)
|
||
procent_team = (
|
||
round(
|
||
(coach_team_stat_temp["wins"] * 100)
|
||
/ coach_team_stat_temp["games"],
|
||
1,
|
||
)
|
||
if coach_team_stat_temp["games"] != 0
|
||
else ""
|
||
)
|
||
# HeadCoachStatsTeam = (
|
||
# f'{coach_team_stat_temp["season"]} {season_word_team} as {data[f"{who}"]} head coach'
|
||
# )
|
||
HeadCoachStatsTeam = f"{data[f'{who}']} head coach"
|
||
if coach_team_stat_temp["season"] == 0:
|
||
HeadCoachStatsTeam = f'{coach_team_stat_temp["games"] if coach_team_stat_temp["games"] != 0 else "first"} {games_word} as {data[f"{who}"]} head coach'
|
||
HeadCoachStatsTeam += (
|
||
f'\n{coach_team_stat_temp["games"] if coach_team_stat_temp["games"] != 0 else "first"} {games_word}: {coach_team_stat_temp["wins"]}-{coach_team_stat_temp["loses"]} ({procent_team}% wins)'
|
||
if coach_team_stat_temp["games"] != 0
|
||
else ""
|
||
)
|
||
|
||
text = ""
|
||
if row_player_season_avg:
|
||
text = f"GAMES: {row_player_season_avg['games']} MINUTES: {row_player_season_avg['playedTime']} "
|
||
text += (
|
||
f"PTS: {row_player_season_avg['points']} "
|
||
if row_player_season_avg["points"] != ""
|
||
else ""
|
||
)
|
||
text += (
|
||
f"REB: {row_player_season_avg['rebound']} "
|
||
if row_player_season_avg["rebound"] != ""
|
||
and float(row_player_season_avg["rebound"]) >= 1.0
|
||
else ""
|
||
)
|
||
text += (
|
||
f"AST: {row_player_season_avg['assist']} "
|
||
if row_player_season_avg["assist"] != ""
|
||
and float(row_player_season_avg["assist"]) >= 1.0
|
||
else ""
|
||
)
|
||
text += (
|
||
f"STL: {row_player_season_avg['steal']} "
|
||
if row_player_season_avg["steal"] != ""
|
||
and float(row_player_season_avg["steal"]) >= 1.0
|
||
else ""
|
||
)
|
||
text += (
|
||
f"BLK: {row_player_season_avg['blockShot']} "
|
||
if row_player_season_avg["blockShot"] != ""
|
||
and float(row_player_season_avg["blockShot"]) >= 1.0
|
||
else ""
|
||
)
|
||
text = text.strip()
|
||
# print(item)
|
||
player = {
|
||
"id": item["personId"],
|
||
"num": item["displayNumber"],
|
||
"startRole": item["startRole"],
|
||
"role": item["positionName"],
|
||
"roleShort": (
|
||
[
|
||
r[1]
|
||
for r in role_list
|
||
if r[0].lower() == item["positionName"].lower()
|
||
][0]
|
||
if any(
|
||
r[0].lower() == item["positionName"].lower() for r in role_list
|
||
)
|
||
else ""
|
||
),
|
||
"NameGFX": (
|
||
f"{item['firstName'].strip()} {item['lastName'].strip()}"
|
||
if item["firstName"] is not None and item["lastName"] is not None
|
||
else "Команда"
|
||
),
|
||
"captain": item["isCapitan"],
|
||
"age": item["age"] if item["age"] is not None else 0,
|
||
"height": f'{item["height"]} cm' if item["height"] else 0,
|
||
"weight": f'{item["weight"]} kg' if item["weight"] else 0,
|
||
"isStart": (item["stats"]["isStart"] if item["stats"] else False),
|
||
"isOn": (
|
||
"🏀" if item["stats"] and item["stats"]["isOnCourt"] is True else ""
|
||
),
|
||
"flag": f"https://flagicons.lipis.dev/flags/4x3/{'ru' if item['countryId'] is None and item['countryName'] == 'Russia' else '' if item['countryId'] is None else item['countryId'].lower() if item['countryName'] is not None else ''}.svg",
|
||
"pts": item["stats"]["points"] if item["stats"] else 0,
|
||
"pt-2": (
|
||
f"{item['stats']['goal2']}/{item['stats']['shot2']}"
|
||
if item["stats"]
|
||
else 0
|
||
),
|
||
"pt-3": (
|
||
f"{item['stats']['goal3']}/{item['stats']['shot3']}"
|
||
if item["stats"]
|
||
else 0
|
||
),
|
||
"pt-1": (
|
||
f"{item['stats']['goal1']}/{item['stats']['shot1']}"
|
||
if item["stats"]
|
||
else 0
|
||
),
|
||
"fg": (
|
||
f"{item['stats']['goal2'] + item['stats']['goal3']}/{item['stats']['shot2'] + item['stats']['shot3']}"
|
||
if item["stats"]
|
||
else 0
|
||
),
|
||
"ast": item["stats"]["assist"] if item["stats"] else 0,
|
||
"stl": item["stats"]["steal"] if item["stats"] else 0,
|
||
"blk": item["stats"]["block"] if item["stats"] else 0,
|
||
"blkVic": item["stats"]["blocked"] if item["stats"] else 0,
|
||
"dreb": item["stats"]["defReb"] if item["stats"] else 0,
|
||
"oreb": item["stats"]["offReb"] if item["stats"] else 0,
|
||
"reb": (
|
||
item["stats"]["defReb"] + item["stats"]["offReb"]
|
||
if item["stats"]
|
||
else 0
|
||
),
|
||
"to": item["stats"]["turnover"] if item["stats"] else 0,
|
||
"foul": item["stats"]["foul"] if item["stats"] else 0,
|
||
"foulT": item["stats"]["foulT"] if item["stats"] else 0,
|
||
"foulD": item["stats"]["foulD"] if item["stats"] else 0,
|
||
"foulC": item["stats"]["foulC"] if item["stats"] else 0,
|
||
"foulB": item["stats"]["foulB"] if item["stats"] else 0,
|
||
"fouled": item["stats"]["foulsOn"] if item["stats"] else 0,
|
||
"plusMinus": item["stats"]["plusMinus"] if item["stats"] else 0,
|
||
"dunk": item["stats"]["dunk"] if item["stats"] else 0,
|
||
"kpi": (
|
||
item["stats"]["points"]
|
||
+ item["stats"]["defReb"]
|
||
+ item["stats"]["offReb"]
|
||
+ item["stats"]["assist"]
|
||
+ item["stats"]["steal"]
|
||
+ item["stats"]["block"]
|
||
+ item["stats"]["foulsOn"]
|
||
+ (item["stats"]["goal1"] - item["stats"]["shot1"])
|
||
+ (item["stats"]["goal2"] - item["stats"]["shot2"])
|
||
+ (item["stats"]["goal3"] - item["stats"]["shot3"])
|
||
- item["stats"]["turnover"]
|
||
- item["stats"]["foul"]
|
||
if item["stats"]
|
||
else 0
|
||
),
|
||
"time": (
|
||
format_time(item["stats"]["second"]) if item["stats"] else "0:00"
|
||
),
|
||
"Name1GFX": item["firstName"].strip() if item["firstName"] else "",
|
||
"Name2GFX": item["lastName"].strip() if item["lastName"] else "",
|
||
"photoGFX": (
|
||
f"D:\Photos\{LEAGUE}\{data[who]}\{item['displayNumber']}.png"
|
||
if item["startRole"] == "Player"
|
||
else ""
|
||
),
|
||
"season": text,
|
||
"isOnCourt": (item["stats"]["isOnCourt"] if item["stats"] else False),
|
||
"AvgPoints": (
|
||
row_player_season_avg["points"]
|
||
if row_player_season_avg and row_player_season_avg["points"] != ""
|
||
else "0.0"
|
||
),
|
||
"AvgAssist": (
|
||
row_player_season_avg["assist"]
|
||
if row_player_season_avg and row_player_season_avg["assist"] != ""
|
||
else "0.0"
|
||
),
|
||
"AvgBlocks": (
|
||
row_player_season_avg["blockShot"]
|
||
if row_player_season_avg
|
||
and row_player_season_avg["blockShot"] != ""
|
||
else "0.0"
|
||
),
|
||
"AvgDefRebound": (
|
||
row_player_season_avg["defRebound"]
|
||
if row_player_season_avg
|
||
and row_player_season_avg["defRebound"] != ""
|
||
else "0.0"
|
||
),
|
||
"AvgOffRebound": (
|
||
row_player_season_avg["offRebound"]
|
||
if row_player_season_avg
|
||
and row_player_season_avg["offRebound"] != ""
|
||
else "0.0"
|
||
),
|
||
"AvgRebound": (
|
||
row_player_season_avg["rebound"]
|
||
if row_player_season_avg and row_player_season_avg["rebound"] != ""
|
||
else "0.0"
|
||
),
|
||
"AvgSteal": (
|
||
row_player_season_avg["steal"]
|
||
if row_player_season_avg and row_player_season_avg["steal"] != ""
|
||
else "0.0"
|
||
),
|
||
"AvgTurnover": (
|
||
row_player_season_avg["turnover"]
|
||
if row_player_season_avg and row_player_season_avg["turnover"] != ""
|
||
else "0.0"
|
||
),
|
||
"AvgFoul": (
|
||
row_player_season_avg["foul"]
|
||
if row_player_season_avg and row_player_season_avg["foul"] != ""
|
||
else "0.0"
|
||
),
|
||
"AvgOpponentFoul": (
|
||
row_player_season_avg["foulsOnPlayer"]
|
||
if row_player_season_avg
|
||
and row_player_season_avg["foulsOnPlayer"] != ""
|
||
else "0.0"
|
||
),
|
||
"AvgPlusMinus": (
|
||
row_player_season_avg["plusMinus"]
|
||
if row_player_season_avg
|
||
and row_player_season_avg["plusMinus"] != ""
|
||
else "0.0"
|
||
),
|
||
"AvgKPI": "0.0",
|
||
"AvgPlayedTime": (
|
||
row_player_season_avg["playedTime"]
|
||
if row_player_season_avg
|
||
and row_player_season_avg["playedTime"] != ""
|
||
else "0:00"
|
||
),
|
||
"Shot1Percent": (
|
||
f'{row_player_season_avg["shot1Percent"]}%'
|
||
if row_player_season_avg
|
||
and row_player_season_avg["shot1Percent"] != ""
|
||
else "0.0%"
|
||
),
|
||
"Shot2Percent": (
|
||
f'{row_player_season_avg["shot2Percent"]}%'
|
||
if row_player_season_avg
|
||
and row_player_season_avg["shot2Percent"] != ""
|
||
else "0.0%"
|
||
),
|
||
"Shot3Percent": (
|
||
f'{row_player_season_avg["shot3Percent"]}%'
|
||
if row_player_season_avg
|
||
and row_player_season_avg["shot3Percent"] != ""
|
||
else "0.0%"
|
||
),
|
||
"Shot23Percent": (
|
||
f'{row_player_season_avg["shot23Percent"]}%'
|
||
if row_player_season_avg
|
||
and row_player_season_avg["shot23Percent"] != ""
|
||
else "0.0%"
|
||
),
|
||
"TPoints": safe_int(
|
||
row_player_season_sum.get("points") if row_player_season_sum else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["points"]),
|
||
"TShots1": (
|
||
f'{safe_int(row_player_season_sum.get("goal1")) + (0 if online is False else item["stats"]["goal1"] if item["stats"]["goal1"] != "" else 0)}/{safe_int(row_player_season_sum.get("shot1")) + (0 if online is False else item["stats"]["shot1"] if item["stats"]["shot1"] != "" else 0)}'
|
||
if row_player_season_sum
|
||
and row_player_season_sum["shot1"] != ""
|
||
and item["stats"]["shot1"] != ""
|
||
else "0/0"
|
||
),
|
||
"TShots2": (
|
||
f'{safe_int(row_player_season_sum.get("goal2")) + (0 if online is False else item["stats"]["goal2"] if item["stats"]["goal2"] != "" else 0)}/{safe_int(row_player_season_sum.get("shot2")) + (0 if online is False else item["stats"]["shot2"] if item["stats"]["shot2"] != "" else 0)}'
|
||
if row_player_season_sum
|
||
and row_player_season_sum["shot2"] != ""
|
||
and item["stats"]["shot2"] != ""
|
||
else "0/0"
|
||
),
|
||
"TShots3": (
|
||
f'{safe_int(row_player_season_sum.get("goal3")) + (0 if online is False else item["stats"]["goal3"] if item["stats"]["goal3"] != "" else 0)}/{safe_int(row_player_season_sum.get("shot3")) + (0 if online is False else item["stats"]["shot3"] if item["stats"]["shot3"] != "" else 0)}'
|
||
if row_player_season_sum
|
||
and row_player_season_sum["shot3"] != ""
|
||
and item["stats"]["shot3"] != ""
|
||
else "0/0"
|
||
),
|
||
"TShots23": (
|
||
f'{safe_int(row_player_season_sum.get("goal2")) + safe_int(row_player_season_sum.get("goal3")) + (0 if online is False else item["stats"]["goal2"] if item["stats"]["goal2"] != "" else 0) + (0 if online is False else item["stats"]["goal3"] if item["stats"]["goal3"] != "" else 0)}/'
|
||
f'{safe_int(row_player_season_sum.get("shot2")) + safe_int(row_player_season_sum.get("shot3")) + (0 if online is False else item["stats"]["shot2"] if item["stats"]["shot2"] != "" else 0) + (0 if online is False else item["stats"]["shot3"] if item["stats"]["shot3"] != "" else 0)}'
|
||
if row_player_season_sum
|
||
else "0/0"
|
||
),
|
||
# "TShot1Percent": (
|
||
# f'{row_player_season_sum["shot1Percent"]}%'
|
||
# if row_player_season_sum
|
||
# and row_player_season_sum["shot1Percent"] != ""
|
||
# else "0.0%"
|
||
# ),
|
||
"TShot1Percent": (
|
||
f'{round( ((int(row_player_season_sum["goal1"]) if row_player_season_sum["goal1"] != "" else 0) + (0 if online is False else item["stats"]["goal1"] if item["stats"]["goal1"] != "" else 0)) * 100 / ((int(row_player_season_sum["shot1"]) if row_player_season_sum["shot1"] != "" else 0) + (0 if online is False else item["stats"]["shot1"] if item["stats"]["shot1"] != "" else 0)), 1)}%'
|
||
if row_player_season_sum
|
||
and row_player_season_sum["shot1"] != ""
|
||
and item["stats"]["shot1"] != ""
|
||
else "0.0%"
|
||
),
|
||
"TShot2Percent": (
|
||
f'{round( ((int(row_player_season_sum["goal2"]) if row_player_season_sum["goal2"] != "" else 0) + (0 if online is False else item["stats"]["goal2"] if item["stats"]["goal2"] != "" else 0)) * 100 / ((int(row_player_season_sum["shot2"]) if row_player_season_sum["shot2"] != "" else 0) + (0 if online is False else item["stats"]["shot2"] if item["stats"]["shot2"] != "" else 0)), 1)}%'
|
||
if row_player_season_sum
|
||
and row_player_season_sum["shot2"] != ""
|
||
and item["stats"]["shot2"] != ""
|
||
else "0.0%"
|
||
# f'{row_player_season_sum["shot2Percent"]}%'
|
||
# if row_player_season_sum
|
||
# and row_player_season_sum["shot2Percent"] != ""
|
||
# else "0.0%"
|
||
),
|
||
"TShot3Percent": (
|
||
f'{round( ((int(row_player_season_sum["goal3"]) if row_player_season_sum["goal3"] != "" else 0) + (0 if online is False else item["stats"]["goal3"] if item["stats"]["goal3"] != "" else 0)) * 100 / ((int(row_player_season_sum["shot3"]) if row_player_season_sum["shot3"] != "" else 0) + (0 if online is False else item["stats"]["shot3"] if item["stats"]["shot3"] != "" else 0)), 1)}%'
|
||
if row_player_season_sum
|
||
and row_player_season_sum["shot3"] != ""
|
||
and item["stats"]["shot3"] != ""
|
||
else "0.0%"
|
||
# f'{row_player_season_sum["shot3Percent"]}%'
|
||
# if row_player_season_sum
|
||
# and row_player_season_sum["shot3Percent"] != ""
|
||
# else "0.0%"
|
||
),
|
||
"TShot23Percent": (
|
||
f'{round( ((int(row_player_season_sum["goal2"]) if row_player_season_sum["goal2"] != "" else 0) + (0 if online is False else item["stats"]["goal2"] if item["stats"]["goal2"] != "" else 0) + (int(row_player_season_sum["goal3"]) if row_player_season_sum["goal3"] != "" else 0) + (0 if online is False else item["stats"]["goal3"] if item["stats"]["goal3"] != "" else 0)) * 100 / ((int(row_player_season_sum["shot2"]) if row_player_season_sum["shot2"] != "" else 0) + (0 if online is False else item["stats"]["shot2"] if item["stats"]["shot2"] != "" else 0) + ((int(row_player_season_sum["shot3"]) if row_player_season_sum["shot3"] != "" else 0) + (0 if online is False else item["stats"]["shot3"] if item["stats"]["shot3"] != "" else 0))), 1)}%'
|
||
if row_player_season_sum
|
||
and row_player_season_sum["shot2"] != ""
|
||
and item["stats"]["shot2"] != ""
|
||
else "0.0%"
|
||
),
|
||
"TAssist": safe_int(
|
||
row_player_season_sum.get("assist") if row_player_season_sum else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["assist"]),
|
||
"TBlocks": safe_int(
|
||
row_player_season_sum.get("blockShot")
|
||
if row_player_season_sum
|
||
else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["block"]),
|
||
"TDefRebound": safe_int(
|
||
row_player_season_sum.get("defRebound")
|
||
if row_player_season_sum
|
||
else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["defReb"]),
|
||
"TOffRebound": safe_int(
|
||
row_player_season_sum.get("offRebound")
|
||
if row_player_season_sum
|
||
else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["offReb"]),
|
||
"TRebound": safe_int(
|
||
row_player_season_sum.get("rebound") if row_player_season_sum else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["defReb"])
|
||
+ (0 if online is False else item["stats"]["offReb"]),
|
||
"TSteal": safe_int(
|
||
row_player_season_sum.get("steal") if row_player_season_sum else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["steal"]),
|
||
"TTurnover": safe_int(
|
||
row_player_season_sum.get("turnover")
|
||
if row_player_season_sum
|
||
else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["turnover"]),
|
||
"TFoul": safe_int(
|
||
row_player_season_sum.get("foul") if row_player_season_sum else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["foul"]),
|
||
"TOpponentFoul": safe_int(
|
||
row_player_season_sum.get("foulsOnPlayer")
|
||
if row_player_season_sum
|
||
else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["foulsOn"]),
|
||
"TPlusMinus": 0,
|
||
"TKPI": 0,
|
||
"TPlayedTime": (
|
||
row_player_season_sum["playedTime"]
|
||
if row_player_season_sum
|
||
else "0:00"
|
||
),
|
||
"TGameCount": safe_int(
|
||
row_player_season_sum.get("games")
|
||
if row_player_season_sum and row_player_season_sum["games"] != ""
|
||
else 0
|
||
)
|
||
+ (0 if online is False else 1),
|
||
"TStartCount": safe_int(
|
||
row_player_season_sum.get("isStarts")
|
||
if row_player_season_sum and row_player_season_sum["isStarts"] != ""
|
||
else 0
|
||
),
|
||
"CareerTPoints": safe_int(
|
||
row_player_career_sum.get("points")
|
||
if row_player_career_sum and row_player_career_sum["points"] != ""
|
||
else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["points"]),
|
||
"CareerTShots1": (
|
||
f'{(int(row_player_career_sum["goal1"]) if row_player_career_sum["goal1"] != "" else 0) + (0 if online is False else item["stats"]["goal1"] if item["stats"]["goal1"] != "" else 0)}/{(int(row_player_career_sum["shot1"]) if row_player_career_sum["shot1"] != "" else 0) + (0 if online is False else item["stats"]["shot1"] if item["stats"]["shot1"] != "" else 0)}'
|
||
if row_player_career_sum
|
||
and row_player_career_sum["shot1"] != ""
|
||
and item["stats"]["shot1"] != ""
|
||
else "0/0"
|
||
),
|
||
"CareerTShots2": (
|
||
f'{(int(row_player_career_sum["goal2"]) if row_player_career_sum["goal2"] != "" else 0) + (0 if online is False else item["stats"]["goal2"] if item["stats"]["goal2"] != "" else 0)}/{(int(row_player_career_sum["shot2"]) if row_player_career_sum["shot2"] != "" else 0) + (0 if online is False else item["stats"]["shot2"] if item["stats"]["shot2"] != "" else 0)}'
|
||
if row_player_career_sum
|
||
and row_player_career_sum["shot2"] != ""
|
||
and item["stats"]["shot2"] != ""
|
||
else "0/0"
|
||
),
|
||
"CareerTShots3": (
|
||
f'{(int(row_player_career_sum["goal3"]) if row_player_career_sum["goal3"] != "" else 0) + (0 if online is False else item["stats"]["goal3"] if item["stats"]["goal3"] != "" else 0)}/{(int(row_player_career_sum["shot3"]) if row_player_career_sum["shot3"] != "" else 0) + (0 if online is False else item["stats"]["shot3"] if item["stats"]["shot3"] != "" else 0)}'
|
||
if row_player_career_sum
|
||
and row_player_career_sum["shot3"] != ""
|
||
and item["stats"]["shot3"] != ""
|
||
else "0/0"
|
||
),
|
||
"CareerTShots23": (
|
||
f'{safe_int(row_player_career_sum.get("goal2")) + safe_int(row_player_career_sum.get("goal3")) + (0 if online is False else item["stats"]["goal2"] if item["stats"]["goal2"] != "" else 0) + (0 if online is False else item["stats"]["goal3"] if item["stats"]["goal3"] != "" else 0)}/'
|
||
f'{safe_int(row_player_career_sum.get("shot2")) + safe_int(row_player_career_sum.get("shot3")) + (0 if online is False else item["stats"]["shot2"] if item["stats"]["shot2"] != "" else 0) + (0 if online is False else item["stats"]["shot3"] if item["stats"]["shot3"] != "" else 0)}'
|
||
if row_player_career_sum
|
||
else "0/0"
|
||
),
|
||
"CareerTShot1Percent": (
|
||
f'{round( ((int(row_player_career_sum["goal1"]) if row_player_career_sum["goal1"] != "" else 0) + (0 if online is False else item["stats"]["goal1"] if item["stats"]["goal1"] != "" else 0)) * 100 / ((int(row_player_career_sum["shot1"]) if row_player_career_sum["shot1"] != "" else 0) + (0 if online is False else item["stats"]["shot1"] if item["stats"]["shot1"] != "" else 0)), 1)}%'
|
||
if row_player_career_sum
|
||
and row_player_career_sum["shot1"] != ""
|
||
and item["stats"]["shot1"] != ""
|
||
else "0.0%"
|
||
),
|
||
"CareerTShot2Percent": (
|
||
f'{round( ((int(row_player_career_sum["goal2"]) if row_player_career_sum["goal2"] != "" else 0) + (0 if online is False else item["stats"]["goal2"] if item["stats"]["goal2"] != "" else 0)) * 100 / ((int(row_player_career_sum["shot2"]) if row_player_career_sum["shot2"] != "" else 0) + (0 if online is False else item["stats"]["shot2"] if item["stats"]["shot2"] != "" else 0)), 1)}%'
|
||
if row_player_career_sum
|
||
and row_player_career_sum["shot2"] != ""
|
||
and item["stats"]["shot2"] != ""
|
||
else "0.0%"
|
||
),
|
||
"CareerTShot3Percent": (
|
||
f'{round( ((int(row_player_career_sum["goal3"]) if row_player_career_sum["goal3"] != "" else 0) + (0 if online is False else item["stats"]["goal3"] if item["stats"]["goal3"] != "" else 0)) * 100 / ((int(row_player_career_sum["shot3"]) if row_player_career_sum["shot3"] != "" else 0) + (0 if online is False else item["stats"]["shot3"] if item["stats"]["shot3"] != "" else 0)), 1)}%'
|
||
if row_player_career_sum
|
||
and row_player_career_sum["shot3"] != ""
|
||
and item["stats"]["shot3"] != ""
|
||
else "0.0%"
|
||
),
|
||
"CareerTShot23Percent": (
|
||
f'{round( ((int(row_player_career_sum["goal2"]) if row_player_career_sum["goal2"] != "" else 0) + (0 if online is False else item["stats"]["goal2"] if item["stats"]["goal2"] != "" else 0) + (int(row_player_career_sum["goal3"]) if row_player_career_sum["goal3"] != "" else 0) + (0 if online is False else item["stats"]["goal3"] if item["stats"]["goal3"] != "" else 0)) * 100 / ((int(row_player_career_sum["shot2"]) if row_player_career_sum["shot2"] != "" else 0) + (0 if online is False else item["stats"]["shot2"] if item["stats"]["shot2"] != "" else 0) + ((int(row_player_career_sum["shot3"]) if row_player_career_sum["shot3"] != "" else 0) + (0 if online is False else item["stats"]["shot3"] if item["stats"]["shot3"] != "" else 0))), 1)}%'
|
||
if row_player_career_sum
|
||
and row_player_career_sum["shot2"] != ""
|
||
and item["stats"]["shot2"] != ""
|
||
else "0.0%"
|
||
),
|
||
"CareerTAssist": safe_int(
|
||
row_player_career_sum.get("assist") if row_player_career_sum else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["assist"]),
|
||
"CareerTBlocks": safe_int(
|
||
row_player_career_sum.get("blockShot")
|
||
if row_player_career_sum
|
||
else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["block"]),
|
||
"CareerTDefRebound": safe_int(
|
||
row_player_career_sum.get("defRebound")
|
||
if row_player_career_sum
|
||
else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["defReb"]),
|
||
"CareerTOffRebound": safe_int(
|
||
row_player_career_sum.get("offRebound")
|
||
if row_player_career_sum
|
||
else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["offReb"]),
|
||
"CareerTRebound": safe_int(
|
||
row_player_career_sum.get("rebound") if row_player_career_sum else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["defReb"])
|
||
+ (0 if online is False else item["stats"]["offReb"]),
|
||
"CareerTSteal": safe_int(
|
||
row_player_career_sum.get("steal") if row_player_career_sum else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["steal"]),
|
||
"CareerTTurnover": safe_int(
|
||
row_player_career_sum.get("turnover")
|
||
if row_player_career_sum
|
||
else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["turnover"]),
|
||
"CareerTFoul": safe_int(
|
||
row_player_career_sum.get("foul") if row_player_career_sum else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["foul"]),
|
||
"CareerTOpponentFoul": safe_int(
|
||
row_player_career_sum.get("foulsOnPlayer")
|
||
if row_player_career_sum
|
||
else 0
|
||
)
|
||
+ (0 if online is False else item["stats"]["foulsOn"]),
|
||
"CareerTPlusMinus": 0,
|
||
"CareerTPlayedTime": (
|
||
row_player_career_sum["playedTime"]
|
||
if row_player_career_sum
|
||
else "0:00"
|
||
),
|
||
"CareerTGameCount": safe_int(
|
||
row_player_career_sum.get("games") if row_player_career_sum else 0
|
||
)
|
||
+ (0 if online is False else 1),
|
||
"CareerTStartCount": safe_int(
|
||
row_player_career_sum.get("isStarts")
|
||
if row_player_career_sum
|
||
else 0
|
||
),
|
||
"HeadCoachStatsCareer": HeadCoachStatsCareer,
|
||
"HeadCoachStatsTeam": HeadCoachStatsTeam,
|
||
}
|
||
# print(row_player_career_avg)
|
||
# print(row_player_career_sum)
|
||
# print(item)
|
||
# print(player)
|
||
team.append(player)
|
||
count_player = sum(1 for x in team if x["startRole"] == "Player")
|
||
if count_player < 12:
|
||
if team: # Check if team is not empty
|
||
empty_rows = [
|
||
{
|
||
key: (
|
||
False
|
||
if key in ["captain", "isStart", "isOnCourt"]
|
||
else (
|
||
0
|
||
if key
|
||
in [
|
||
"id",
|
||
"pts",
|
||
"weight",
|
||
"height",
|
||
"age",
|
||
"ast",
|
||
"stl",
|
||
"blk",
|
||
"blkVic",
|
||
"dreb",
|
||
"oreb",
|
||
"reb",
|
||
"to",
|
||
"foul",
|
||
"foulT",
|
||
"foulD",
|
||
"foulC",
|
||
"foulB",
|
||
"fouled",
|
||
"plusMinus",
|
||
"dunk",
|
||
"kpi",
|
||
]
|
||
else ""
|
||
)
|
||
)
|
||
for key in team[0].keys()
|
||
}
|
||
for _ in range((4 if count_player <= 4 else 12) - count_player)
|
||
]
|
||
team.extend(empty_rows)
|
||
else:
|
||
time.sleep(3)
|
||
pass
|
||
|
||
sorted_team = sorted(
|
||
team, key=lambda x: ("Player", "", "Coach", "Team").index(x["startRole"])
|
||
)
|
||
rewrite_file(who, sorted_team)
|
||
top_sorted_team = sorted(
|
||
filter(lambda x: x["startRole"] in ["Player", ""], sorted_team),
|
||
key=lambda x: (
|
||
x["pts"],
|
||
x["dreb"] + x["oreb"],
|
||
x["ast"],
|
||
x["stl"],
|
||
x["blk"],
|
||
x["time"],
|
||
),
|
||
reverse=True,
|
||
)
|
||
for item in top_sorted_team:
|
||
item["pts"] = "" if item["num"] == "" else item["pts"]
|
||
item["foul"] = "" if item["num"] == "" else item["foul"]
|
||
rewrite_file(f"top{who.replace('t','T')}", top_sorted_team)
|
||
started_team = sorted(
|
||
filter(
|
||
lambda x: x["startRole"] == "Player" and x["isOnCourt"] is True,
|
||
sorted_team,
|
||
),
|
||
key=lambda x: int(x["num"]),
|
||
reverse=False,
|
||
)
|
||
rewrite_file(f"started_{who}", started_team)
|
||
time.sleep(0.5)
|
||
|
||
|
||
def add_new_team_stat(data, avg_age, points, avg_height, timeout_str, timeout_left):
|
||
data["pt-1"] = f'{data["goal1"]}/{data["shot1"]}'
|
||
data["pt-2"] = f'{data["goal2"]}/{data["shot2"]}'
|
||
data["pt-3"] = f'{data["goal3"]}/{data["shot3"]}'
|
||
data["fg"] = (
|
||
f'{int(data["goal2"]) + int(data["goal3"])}/{int(data["shot2"]) + int(data["shot3"])}'
|
||
)
|
||
data["pt-1_pro"] = (
|
||
f'{round(int(data["goal1"]) / int(data["shot1"]) * 100)}%'
|
||
if int(data["shot1"]) != 0
|
||
else "0%"
|
||
)
|
||
data["pt-2_pro"] = (
|
||
f'{round(int(data["goal2"]) / int(data["shot2"]) * 100)}%'
|
||
if int(data["shot2"]) != 0
|
||
else "0%"
|
||
)
|
||
data["pt-3_pro"] = (
|
||
f'{round(int(data["goal3"]) / int(data["shot3"]) * 100)}%'
|
||
if int(data["shot3"]) != 0
|
||
else "0%"
|
||
)
|
||
data["fg_pro"] = (
|
||
f'{round((int(data["goal2"]) + int(data["goal3"])) / (int(data["shot2"]) + int(data["shot3"])) * 100)}%'
|
||
if int(data["shot2"]) != 0 or int(data["shot3"]) != 0
|
||
else "0%"
|
||
)
|
||
data["Reb"] = f'{int(data["defReb"]) + int(data["offReb"])}'
|
||
data["avgAge"] = avg_age
|
||
data["ptsStart"] = points[0]
|
||
data["ptsStart_pro"] = points[1]
|
||
data["ptsBench"] = points[2]
|
||
data["ptsBench_pro"] = points[3]
|
||
data["avgHeight"] = f"{avg_height} cm"
|
||
data["timeout_left"] = timeout_left
|
||
data["timeout_str"] = timeout_str
|
||
for k, v in data.items():
|
||
data[k] = str(v)
|
||
return data
|
||
|
||
|
||
def add_data_for_teams(new_data):
|
||
players = [item for item in new_data if item["startRole"] == "Player"]
|
||
# for player in players:
|
||
# print(player)
|
||
points_start = sum(
|
||
player["stats"]["points"]
|
||
for player in players
|
||
if player["stats"]["isStart"] is True
|
||
)
|
||
points_bench = sum(
|
||
player["stats"]["points"]
|
||
for player in players
|
||
if player["stats"]["isStart"] is False
|
||
)
|
||
points_start_pro = (
|
||
(str(round(points_start / (points_start + points_bench) * 100)) + "%")
|
||
if points_start != 0 or points_bench != 0
|
||
else "0%"
|
||
)
|
||
points_bench_pro = (
|
||
(str(round(points_bench / (points_start + points_bench) * 100)) + "%")
|
||
if points_start != 0 or points_bench != 0
|
||
else "0%"
|
||
)
|
||
points = [points_start, points_start_pro, points_bench, points_bench_pro]
|
||
try:
|
||
total_age = sum(player["age"] for player in players)
|
||
average_age = total_age / len(players) if len(players) > 0 else 0
|
||
average_age = round(average_age, 1)
|
||
except TypeError:
|
||
average_age = 0
|
||
try:
|
||
total_height = sum(player["height"] for player in players)
|
||
average_height = total_height / len(players) if len(players) > 0 else 0
|
||
average_height = round(average_height, 1)
|
||
except TypeError:
|
||
average_height = 0
|
||
return average_age, points, average_height
|
||
|
||
|
||
def time_outs_func(data_pbp):
|
||
timeout1 = []
|
||
timeout2 = []
|
||
for event in data_pbp:
|
||
if event["play"] == 23:
|
||
if event["startNum"] == 1:
|
||
timeout1.append(event)
|
||
elif event["startNum"] == 2:
|
||
timeout2.append(event)
|
||
|
||
def timeout_str(timeout):
|
||
timeout_str = ""
|
||
timeout_left = ""
|
||
count_timeout = 0
|
||
if last_event["period"] < 3:
|
||
timeout_max = 2
|
||
count_timeout = sum(
|
||
1 for t in timeout if t["period"] <= last_event["period"]
|
||
)
|
||
timeout_left = timeout_max - count_timeout
|
||
quarter = "1st half"
|
||
elif last_event["period"] < 5:
|
||
timeout_max = 3
|
||
count_timeout = sum(
|
||
1 for t in timeout if 2 < t["period"] <= last_event["period"]
|
||
)
|
||
timeout_left = timeout_max - count_timeout
|
||
quarter = "2nd half"
|
||
if (
|
||
last_event["period"] == 4
|
||
and last_event["sec"] >= 4800
|
||
and count_timeout in (0, 1)
|
||
):
|
||
timeout_max = 2
|
||
timeout_left = timeout_max - count_timeout
|
||
quarter = "2nd half"
|
||
else:
|
||
ot = last_event["period"] - 4
|
||
timeout_max = 1
|
||
count_timeout = sum(
|
||
1 for t in timeout if t["period"] == last_event["period"]
|
||
)
|
||
timeout_left = timeout_max - count_timeout
|
||
quarter = f"OverTime {ot}"
|
||
|
||
timeout_word = "Time-outs" if timeout_left != 1 else "Time-out"
|
||
timeout_str = f"{timeout_left if timeout_left != 0 else 'No'} {timeout_word} left in {quarter}"
|
||
return timeout_str, timeout_left
|
||
|
||
timeout_str1 = ""
|
||
timeout_left1 = ""
|
||
timeout_str2 = ""
|
||
timeout_left2 = ""
|
||
|
||
if data_pbp != []:
|
||
last_event = data_pbp[-1]
|
||
timeout_str1, timeout_left1 = timeout_str(timeout1)
|
||
timeout_str2, timeout_left2 = timeout_str(timeout2)
|
||
|
||
return timeout_str1, timeout_left1, timeout_str2, timeout_left2
|
||
|
||
|
||
def Team_Both_Stat(data, event):
|
||
logger.info("START making json for team statistics")
|
||
|
||
while not event.is_set():
|
||
team_stat_1 = Team_Stat_Game(data["team1_id"], data["game_id"])
|
||
team_stat_2 = Team_Stat_Game(data["team2_id"], data["game_id"])
|
||
data_pbp = Game_Online(data["game_id"])
|
||
|
||
data_pbp = data_pbp["result"]["plays"]
|
||
timeout_str1, timeout_left1, timeout_str2, timeout_left2 = time_outs_func(
|
||
data_pbp
|
||
)
|
||
|
||
avg_age_1, points_1, avg_height_1 = add_data_for_teams(team_stat_1["starts"])
|
||
avg_age_2, points_2, avg_height_2 = add_data_for_teams(team_stat_2["starts"])
|
||
|
||
# timeout_str1, timeout_left1 = "", ""
|
||
# timeout_str2, timeout_left2 = "", ""
|
||
team_stat_1 = add_new_team_stat(
|
||
team_stat_1["total"],
|
||
avg_age_1,
|
||
points_1,
|
||
avg_height_1,
|
||
timeout_str1,
|
||
timeout_left1,
|
||
)
|
||
team_stat_2 = add_new_team_stat(
|
||
team_stat_2["total"],
|
||
avg_age_2,
|
||
points_2,
|
||
avg_height_2,
|
||
timeout_str2,
|
||
timeout_left2,
|
||
)
|
||
result_json = []
|
||
for key in team_stat_1:
|
||
val1 = (
|
||
team_stat_1[key]
|
||
if type(team_stat_1[key]) is not float
|
||
else int(team_stat_1[key])
|
||
)
|
||
val2 = (
|
||
team_stat_2[key]
|
||
if type(team_stat_2[key]) is not float
|
||
else int(team_stat_2[key])
|
||
)
|
||
new_stat_rus = ""
|
||
new_stat_eng = ""
|
||
for s in stat_name_list:
|
||
if s[0] == key:
|
||
new_stat_rus = s[1]
|
||
new_stat_eng = s[2]
|
||
result_json.append(
|
||
{
|
||
"name": key,
|
||
"nameGFX_rus": new_stat_rus,
|
||
"nameGFX_eng": new_stat_eng,
|
||
"val1": val1,
|
||
"val2": val2,
|
||
}
|
||
)
|
||
rewrite_file("team_stats", result_json)
|
||
logger.debug("Успешно положенны данные в файл")
|
||
time.sleep(0.5)
|
||
|
||
|
||
def restartable_thread(target, args, event):
|
||
while not event.is_set():
|
||
thread = Thread(target=target, args=args)
|
||
thread.start()
|
||
thread.join()
|
||
if not event.is_set():
|
||
logger.warning(f"Поток {target.__name__} завершился. Перезапуск...")
|
||
|
||
|
||
def Game_Online(game_id):
|
||
box_score = requests.get(f"{URL}api/abc/games/box-score?Id={game_id}")
|
||
# print(f"{URL}api/abc/games/box-score?Id={game_id}")
|
||
# print(f"{URL}api/abc/games/game?Id={game_id}&Lang={LANG}")
|
||
# print(f"{URL}api/abc/games/play-by-play?Id={game_id}")
|
||
if box_score.status_code == 200:
|
||
if box_score.json()["status"] != "Ok":
|
||
game = requests.get(f"{URL}api/abc/games/game?Id={game_id}&Lang={LANG}")
|
||
game = game.json()
|
||
logger.debug("У нас получилось получить данные со старого матча")
|
||
# print(game)
|
||
else:
|
||
# ОНЛАЙН
|
||
game = requests.get(f"{URL}api/abc/games/game?Id={game_id}&Lang={LANG}")
|
||
play_by_play = requests.get(f"{URL}api/abc/games/play-by-play?Id={game_id}")
|
||
game = game.json()
|
||
for index_team, i in enumerate(game["result"]["teams"][1:]):
|
||
for s in i["starts"]:
|
||
matching_stats = next(
|
||
(
|
||
stat
|
||
for stat in box_score.json()["result"]["teams"][index_team][
|
||
"starts"
|
||
]
|
||
if stat["startNum"] == s["startNum"]
|
||
),
|
||
None, # Значение по умолчанию, если не найдено совпадение
|
||
)
|
||
if matching_stats:
|
||
s["stats"] = matching_stats
|
||
i["total"] = box_score.json()["result"]["teams"][index_team]["total"]
|
||
game["result"]["plays"] = play_by_play.json()["result"]
|
||
game["result"]["scoreByPeriods"] = box_score.json()["result"][
|
||
"scoreByPeriods"
|
||
]
|
||
game["result"]["fullScore"] = box_score.json()["result"]["fullScore"]
|
||
logger.debug("Склеил данные по онлайн матчу")
|
||
return game
|
||
else:
|
||
logger.warning(f"{myhost}\nAPI responed <b>{box_score['status']}</b>")
|
||
return None
|
||
|
||
|
||
def Referee(data, event):
|
||
logger.info("START making json for referee")
|
||
while not event.is_set():
|
||
payload = Game_Online(data["game_id"])
|
||
|
||
referee = payload["result"]["teams"][0]["starts"]
|
||
referee = [
|
||
{
|
||
"displayNumber": r["displayNumber"],
|
||
"positionName": r["positionName"],
|
||
"lastNameGFX": f'{r["firstName"]} {r["lastName"]}',
|
||
"secondName": r["secondName"],
|
||
"birthday": r["birthday"],
|
||
"age": r["age"],
|
||
"flag": f"https://flagicons.lipis.dev/flags/4x3/{r['countryId'].lower() if r['countryName'] else ''}.svg",
|
||
}
|
||
for r in referee
|
||
]
|
||
desired_order = [
|
||
"Crew chief",
|
||
"Referee 1",
|
||
"Referee 2",
|
||
"Commissioner",
|
||
"Ст.судья",
|
||
"Судья 1",
|
||
"Судья 2",
|
||
"Комиссар",
|
||
]
|
||
referee = sorted(
|
||
referee,
|
||
key=lambda x: (
|
||
desired_order.index(x["positionName"])
|
||
if x["positionName"] in desired_order
|
||
else len(desired_order)
|
||
),
|
||
)
|
||
rewrite_file("referee", referee)
|
||
logger.debug("Успешно записаны судьи в файл")
|
||
time.sleep(60)
|
||
|
||
|
||
def Scores_Quarter(data, event):
|
||
logger.info(f"START making json for scores quarter")
|
||
while not event.is_set():
|
||
payload = Game_Online(data["game_id"])
|
||
rewrite_file("game_online", payload)
|
||
quarters = ["Q1", "Q2", "Q3", "Q4", "OT1", "OT2", "OT3", "OT4"]
|
||
score_by_quarter_new = [
|
||
{"Q": quarter, "score1": "", "score2": ""} for quarter in quarters
|
||
]
|
||
if payload["result"]["game"]["fullScore"]:
|
||
fullscore = payload["result"]["game"]["fullScore"].split(",")
|
||
for index, score in enumerate(fullscore):
|
||
score_by_quarter_new[index]["score1"] = score.split(":")[0]
|
||
score_by_quarter_new[index]["score2"] = score.split(":")[1]
|
||
rewrite_file("scores", score_by_quarter_new)
|
||
logger.debug("Успешно положил данные о счете по четвертям в файл")
|
||
time.sleep(0.5)
|
||
elif (
|
||
"scoreByPeriods" in payload["result"]
|
||
and payload["result"]["scoreByPeriods"]
|
||
):
|
||
fullscore = payload["result"]["scoreByPeriods"]
|
||
for index, score in enumerate(fullscore):
|
||
score_by_quarter_new[index]["score1"] = score["score1"]
|
||
score_by_quarter_new[index]["score2"] = score["score2"]
|
||
rewrite_file("scores", score_by_quarter_new)
|
||
logger.debug("Успешно положил данные о счете по четвертям в файл")
|
||
time.sleep(0.5)
|
||
else:
|
||
for score in score_by_quarter_new:
|
||
score["score1"] = ""
|
||
score["score2"] = ""
|
||
rewrite_file("scores", score_by_quarter_new)
|
||
logger.debug("Данных нет, положил пустоту в счет по четвертям")
|
||
time.sleep(10)
|
||
|
||
|
||
def Standing_func(data, event):
|
||
logger.info("START making json for standings")
|
||
while not event.is_set():
|
||
try:
|
||
season = data["season"]
|
||
url = (
|
||
f"{URL}api/abc/comps/standings?tag={LEAGUE}&season={season}&lang={LANG}"
|
||
)
|
||
data_standings = requests.get(url)
|
||
data_standings = data_standings.json()
|
||
|
||
if data_standings and "items" in data_standings and data_standings["items"]:
|
||
standings_temp = data_standings["items"][0].get("standings")
|
||
if standings_temp:
|
||
df = pd.json_normalize(standings_temp)
|
||
del df["scores"]
|
||
if not df["totalWin"].isna().all():
|
||
df["w_l"] = (
|
||
df["totalWin"].astype(str)
|
||
+ " / "
|
||
+ df["totalDefeat"].astype(str)
|
||
)
|
||
df["procent"] = df.apply(
|
||
lambda row: (
|
||
0
|
||
if row["w_l"] == "0 / 0"
|
||
or row["totalGames"] == 0
|
||
or pd.isna(row["totalWin"])
|
||
else round(
|
||
row["totalWin"] * 100 / row["totalGames"] + 0.000005
|
||
)
|
||
),
|
||
axis=1,
|
||
)
|
||
df["name"] = df["name"].replace("PBC Uralmash", "Uralmash")
|
||
df.to_json(
|
||
f"JSON/standings_{LEAGUE}.json",
|
||
orient="records",
|
||
force_ascii=False,
|
||
indent=4,
|
||
)
|
||
logger.debug("Standings data saved successfully.")
|
||
else:
|
||
logger.warning("Турнирное положение пусто.")
|
||
except Exception as e:
|
||
logger.warning(f"Ошибка в турнирном положении: {e}")
|
||
|
||
time.sleep(60)
|
||
|
||
|
||
def status_online_func(data):
|
||
url = f"{URL}api/abc/games/live-status?id={data['game_id']}"
|
||
# print(url)
|
||
json_live_status = requests.get(url)
|
||
json_live_status = json_live_status.json()
|
||
if json_live_status["status"] == "Ok":
|
||
temp_live_status = json_live_status["result"]
|
||
path_to_png = (
|
||
r"D:\ГРАФИКА\БАСКЕТБОЛ\ЕДИНАЯ ЛИГА ВТБ 2022-2023\Scorebug Indicators"
|
||
)
|
||
fouls_1 = 5 if temp_live_status["foulsA"] >= 5 else temp_live_status["foulsA"]
|
||
fouls_2 = 5 if temp_live_status["foulsB"] >= 5 else temp_live_status["foulsB"]
|
||
temp_live_status["foulsA_png"] = f"{path_to_png}\\Home_{fouls_1}.png"
|
||
temp_live_status["foulsB_png"] = f"{path_to_png}\\Away_{fouls_2}.png"
|
||
return temp_live_status
|
||
|
||
|
||
def Status_Online(data, event):
|
||
logger.info(f"START making json for status online")
|
||
while not event.is_set():
|
||
temp_live_status = status_online_func(data)
|
||
rewrite_file("live_status", [temp_live_status])
|
||
logger.debug("успешно положил данные об онлайн статусе в файл")
|
||
time.sleep(0.5)
|
||
|
||
|
||
def Play_By_Play(data, event):
|
||
logger.info("START making json for play-by-play")
|
||
payload1 = Team_Stat_Game(f'{data["team1_id"]}', data["game_id"])
|
||
team1_startnum = [
|
||
i["startNum"] for i in payload1["starts"] if i["startRole"] == "Player"
|
||
]
|
||
payload2 = Team_Stat_Game(f'{data["team2_id"]}', data["game_id"])
|
||
team2_startnum = [
|
||
i["startNum"] for i in payload2["starts"] if i["startRole"] == "Player"
|
||
]
|
||
team1_name = data["team1"]
|
||
team2_name = data["team2"]
|
||
|
||
while not event.is_set():
|
||
data_pbp = Game_Online(data["game_id"])
|
||
|
||
url = f"{URL}api/abc/games/live-status?id={data['game_id']}"
|
||
json_live_status = requests.get(url)
|
||
json_live_status = json_live_status.json()
|
||
|
||
data_pbp = data_pbp["result"]["plays"]
|
||
if data_pbp:
|
||
df_data_pbp = pd.DataFrame(data_pbp[::-1])
|
||
last_event = data_pbp[-1]
|
||
if "play" in df_data_pbp:
|
||
if json_live_status["status"] != "Not Found":
|
||
json_quarter = json_live_status["result"]["period"]
|
||
json_second = json_live_status["result"]["second"]
|
||
else:
|
||
json_quarter = last_event["period"]
|
||
json_second = 0
|
||
timer_str = ""
|
||
if "3x3" in LEAGUE:
|
||
df_data_pbp["play"].replace({2: 1, 3: 2}, inplace=True)
|
||
df_goals = df_data_pbp.loc[df_data_pbp["play"].isin([1, 2, 3])].copy()
|
||
if not df_goals.empty:
|
||
df_goals.loc[
|
||
df_goals["startNum"].isin(team1_startnum), "score1"
|
||
] = df_goals["play"]
|
||
df_goals.loc[
|
||
df_goals["startNum"].isin(team2_startnum), "score2"
|
||
] = df_goals["play"]
|
||
|
||
df_goals["score_sum1"] = df_goals["score1"].fillna(0).cumsum()
|
||
df_goals["score_sum2"] = df_goals["score2"].fillna(0).cumsum()
|
||
df_goals["new_sec"] = (
|
||
df_goals["sec"].astype(str).str.slice(0, -1).astype(int)
|
||
)
|
||
df_goals["time_now"] = (
|
||
600 if json_quarter < 5 else 300
|
||
) - json_second
|
||
df_goals["quar"] = json_quarter - df_goals["period"]
|
||
df_goals["diff_time"] = np.where(
|
||
df_goals["quar"] == 0,
|
||
df_goals["time_now"] - df_goals["new_sec"],
|
||
(600 * df_goals["quar"] - df_goals["new_sec"])
|
||
+ (df_goals["time_now"]),
|
||
)
|
||
df_goals["diff_time_str"] = df_goals["diff_time"].apply(
|
||
lambda x: (
|
||
f"{x // 60}:{str(x % 60).zfill(2)}"
|
||
if isinstance(x, int)
|
||
else x
|
||
)
|
||
)
|
||
df_goals["team"] = df_goals.apply(
|
||
lambda row: (
|
||
team1_name if not pd.isna(row["score1"]) else team2_name
|
||
),
|
||
axis=1,
|
||
)
|
||
df_goals["text_rus"] = df_goals.apply(
|
||
lambda row: (
|
||
f"рывок {int(row['score_sum1'])}-{int(row['score_sum2'])}"
|
||
if not pd.isna(row["score1"])
|
||
else f"рывок {int(row['score_sum2'])}-{int(row['score_sum1'])}"
|
||
),
|
||
axis=1,
|
||
)
|
||
df_goals["text_time_rus"] = df_goals.apply(
|
||
lambda row: (
|
||
f"рывок {int(row['score_sum1'])}-{int(row['score_sum2'])} за {row['diff_time_str']}"
|
||
if not pd.isna(row["score1"])
|
||
else f"рывок {int(row['score_sum2'])}-{int(row['score_sum1'])} за {row['diff_time_str']}"
|
||
),
|
||
axis=1,
|
||
)
|
||
df_goals["text"] = df_goals.apply(
|
||
lambda row: (
|
||
f"{team1_name} {int(row['score_sum1'])}-{int(row['score_sum2'])} run"
|
||
if not pd.isna(row["score1"])
|
||
else f"{team2_name} {int(row['score_sum2'])}-{int(row['score_sum1'])} run"
|
||
),
|
||
axis=1,
|
||
)
|
||
df_goals["text_time"] = df_goals.apply(
|
||
lambda row: (
|
||
f"{team1_name} {int(row['score_sum1'])}-{int(row['score_sum2'])} run in last {row['diff_time_str']}"
|
||
if not pd.isna(row["score1"])
|
||
else f"{team2_name} {int(row['score_sum2'])}-{int(row['score_sum1'])} run in last {row['diff_time_str']}"
|
||
),
|
||
axis=1,
|
||
)
|
||
|
||
new_order = ["text", "text_time"] + [
|
||
col
|
||
for col in df_goals.columns
|
||
if col not in ["text", "text_time"]
|
||
]
|
||
df_goals = df_goals[new_order]
|
||
for _ in [
|
||
"children",
|
||
"start",
|
||
"stop",
|
||
"hl",
|
||
"sort",
|
||
"startNum",
|
||
"zone",
|
||
"x",
|
||
"y",
|
||
]:
|
||
del df_goals[_]
|
||
df_goals.to_json(
|
||
"JSON/play_by_play",
|
||
orient="records",
|
||
force_ascii=False,
|
||
indent=4,
|
||
)
|
||
logger.debug("успешно положил данные об play-by-play в файл")
|
||
time.sleep(0.5)
|
||
|
||
else:
|
||
logger.debug("нет данных в play-by-play")
|
||
time.sleep(60)
|
||
|
||
|
||
def How_To_Play_Quarter(data):
|
||
game_id = data["game_id"]
|
||
team1_id = data["team1_id"]
|
||
team2_id = data["team2_id"]
|
||
team1_name = data["team1"]
|
||
team2_name = data["team2"]
|
||
season = data["season"]
|
||
url = f"{URL}api/abc/comps/calendar?Tag={LEAGUE}&Season={season}&Lang={LANG}&MaxResultCount=1000"
|
||
schedule_data = get_json(url)
|
||
df_schedule = pd.json_normalize(schedule_data["items"])
|
||
|
||
df_schedule_new = df_schedule[
|
||
[
|
||
"game.id",
|
||
"ot",
|
||
"game.gameStatus",
|
||
"game.score1",
|
||
"game.score2",
|
||
"game.fullScore",
|
||
"team1.teamId",
|
||
"team1.name",
|
||
"team2.teamId",
|
||
"team2.name",
|
||
]
|
||
]
|
||
|
||
def calculate_win(row, team_id):
|
||
if (
|
||
row["team1.teamId"] == team_id and row["game.score1"] > row["game.score2"]
|
||
) or (
|
||
row["team2.teamId"] == team_id and row["game.score2"] > row["game.score1"]
|
||
):
|
||
return 1
|
||
else:
|
||
return 0
|
||
|
||
df_schedule_new_2 = df_schedule_new.loc[
|
||
(df_schedule_new["game.id"] < game_id)
|
||
& (
|
||
(df_schedule_new["team1.teamId"].isin([team1_id, team2_id]))
|
||
| (df_schedule_new["team2.teamId"].isin([team1_id, team2_id]))
|
||
)
|
||
]
|
||
|
||
def win_lose_draw_quarter(teamid):
|
||
df_schedule_quarter_team = df_schedule_new_2.loc[
|
||
(
|
||
(df_schedule_new_2["team1.teamId"] == teamid)
|
||
| (df_schedule_new_2["team2.teamId"] == teamid)
|
||
)
|
||
]
|
||
|
||
columns_to_clear = [
|
||
"Q1",
|
||
"Q2",
|
||
"Q3",
|
||
"Q4",
|
||
"OT1",
|
||
"OT2",
|
||
"OT3",
|
||
"OT4",
|
||
"wldQ1",
|
||
"wldQ2",
|
||
"wldQ3",
|
||
"wldQ4",
|
||
"wldOT1",
|
||
"wldOT2",
|
||
"wldOT3",
|
||
"wldOT4",
|
||
"winQ1",
|
||
"winQ2",
|
||
"winQ3",
|
||
"winQ4",
|
||
"winOT1",
|
||
"winOT2",
|
||
"winOT3",
|
||
"winOT4",
|
||
"loseQ1",
|
||
"loseQ2",
|
||
"loseQ3",
|
||
"loseQ4",
|
||
"loseOT1",
|
||
"loseOT2",
|
||
"loseOT3",
|
||
"loseOT4",
|
||
"drawQ1",
|
||
"drawQ2",
|
||
"drawQ3",
|
||
"drawQ4",
|
||
"drawOT1",
|
||
"drawOT2",
|
||
"drawOT3",
|
||
"drawOT4",
|
||
]
|
||
|
||
df_schedule_quarter_team.loc[:, columns_to_clear] = [""] * len(columns_to_clear)
|
||
temp_score_quarter = df_schedule_quarter_team["game.fullScore"].str.split(",")
|
||
df_schedule_quarter_team = df_schedule_quarter_team.copy()
|
||
for q in range(1, 9):
|
||
new_q = f"OT{q - 4}" if q > 4 else f"Q{q}"
|
||
df_schedule_quarter_team[new_q] = temp_score_quarter.apply(
|
||
lambda x: x[q - 1] if (x is not None and len(x) >= q) else None
|
||
)
|
||
|
||
def calculate_quarter_result(row, teamid, quarter_name):
|
||
if pd.notna(row[quarter_name]) and ":" in row[quarter_name]:
|
||
score = row[quarter_name].split(":")
|
||
if len(score) == 2:
|
||
score1 = int(score[0])
|
||
score2 = int(score[1])
|
||
|
||
if (row["team1.teamId"] == teamid and score1 > score2) or (
|
||
row["team2.teamId"] == teamid and score2 > score1
|
||
):
|
||
return "win"
|
||
elif (row["team1.teamId"] == teamid and score1 < score2) or (
|
||
row["team2.teamId"] == teamid and score2 < score1
|
||
):
|
||
return "lose"
|
||
elif score1 == score2:
|
||
return "draw"
|
||
return ""
|
||
|
||
quarters = ["Q1", "Q2", "Q3", "Q4", "OT1", "OT2", "OT3", "OT4"]
|
||
|
||
for quarter in quarters:
|
||
df_schedule_quarter_team.loc[:, f"wld{quarter}"] = (
|
||
df_schedule_quarter_team.apply(
|
||
calculate_quarter_result, args=(teamid, quarter), axis=1
|
||
)
|
||
)
|
||
df_schedule_quarter_team.loc[:, f"win{quarter}"] = (
|
||
df_schedule_quarter_team[f"wld{quarter}"] == "win"
|
||
).astype(int)
|
||
df_schedule_quarter_team.loc[:, f"lose{quarter}"] = (
|
||
df_schedule_quarter_team[f"wld{quarter}"] == "lose"
|
||
).astype(int)
|
||
df_schedule_quarter_team.loc[:, f"draw{quarter}"] = (
|
||
df_schedule_quarter_team[f"wld{quarter}"] == "draw"
|
||
).astype(int)
|
||
return df_schedule_quarter_team
|
||
|
||
df_schedule_quarter_team1 = win_lose_draw_quarter(team1_id)
|
||
df_schedule_quarter_team2 = win_lose_draw_quarter(team2_id)
|
||
|
||
def score_quarter_team(teamid):
|
||
df_schedule_quarter_team_new = df_schedule_new_2.loc[
|
||
(
|
||
(df_schedule_new_2["team1.teamId"] == teamid)
|
||
| (df_schedule_new_2["team2.teamId"] == teamid)
|
||
)
|
||
]
|
||
temp_score_quarter = df_schedule_quarter_team_new["game.fullScore"].str.split(
|
||
","
|
||
)
|
||
|
||
df_schedule_quarter_team_new.loc[
|
||
:, ["Q1", "Q2", "Q3", "Q4", "OT1", "OT2", "OT3", "OT4"]
|
||
] = ("", "", "", "", "", "", "", "")
|
||
|
||
df_schedule_quarter_team_new = df_schedule_quarter_team_new.copy()
|
||
num_elements = temp_score_quarter.apply(
|
||
lambda x: len(x) if x is not None else 0
|
||
).astype(int)
|
||
if not num_elements.empty:
|
||
for q in range(1, num_elements.max() + 1):
|
||
new_q = f"OT{q - 4}" if q > 4 else f"Q{q}"
|
||
df_schedule_quarter_team_new.loc[:, new_q] = temp_score_quarter.apply(
|
||
lambda x: (x[q - 1] if (x is not None and len(x) >= q) else None)
|
||
)
|
||
|
||
def calculate_quarter_result(row2, team_id, quarter_name):
|
||
if pd.notna(row2[quarter_name]) and ":" in row2[quarter_name]:
|
||
score = row2[quarter_name].split(":")
|
||
score1 = int(score[0])
|
||
score2 = int(score[1])
|
||
|
||
if row2["team1.teamId"] == team_id:
|
||
return score1
|
||
elif row2["team2.teamId"] == team_id:
|
||
return score2
|
||
elif score1 == score2:
|
||
return score1
|
||
return None
|
||
|
||
quarters = ["Q1", "Q2", "Q3", "Q4", "OT1", "OT2", "OT3", "OT4"]
|
||
|
||
df_schedule_quarter_team_new = df_schedule_quarter_team_new.copy()
|
||
for quarter in quarters:
|
||
df_schedule_quarter_team_new.loc[:, f"score{quarter}"] = (
|
||
df_schedule_quarter_team_new.apply(
|
||
calculate_quarter_result, args=(teamid, quarter), axis=1
|
||
)
|
||
)
|
||
|
||
return df_schedule_quarter_team_new
|
||
|
||
df_schedule_quarter_team1_new = score_quarter_team(team1_id)
|
||
df_schedule_quarter_team2_new = score_quarter_team(team2_id)
|
||
|
||
schedule_json_quarter = [
|
||
{
|
||
"team": team1_name,
|
||
"winQ1": df_schedule_quarter_team1["winQ1"].sum(),
|
||
"winQ2": df_schedule_quarter_team1["winQ2"].sum(),
|
||
"winQ3": df_schedule_quarter_team1["winQ3"].sum(),
|
||
"winQ4": df_schedule_quarter_team1["winQ4"].sum(),
|
||
"winOT1": df_schedule_quarter_team1["winOT1"].sum(),
|
||
"winOT2": df_schedule_quarter_team1["winOT2"].sum(),
|
||
"winOT3": df_schedule_quarter_team1["winOT3"].sum(),
|
||
"winOT4": df_schedule_quarter_team1["winOT4"].sum(),
|
||
"loseQ1": df_schedule_quarter_team1["loseQ1"].sum(),
|
||
"loseQ2": df_schedule_quarter_team1["loseQ2"].sum(),
|
||
"loseQ3": df_schedule_quarter_team1["loseQ3"].sum(),
|
||
"loseQ4": df_schedule_quarter_team1["loseQ4"].sum(),
|
||
"loseOT1": df_schedule_quarter_team1["loseOT1"].sum(),
|
||
"loseOT2": df_schedule_quarter_team1["loseOT2"].sum(),
|
||
"loseOT3": df_schedule_quarter_team1["loseOT3"].sum(),
|
||
"loseOT4": df_schedule_quarter_team1["loseOT4"].sum(),
|
||
"drawQ1": df_schedule_quarter_team1["drawQ1"].sum(),
|
||
"drawQ2": df_schedule_quarter_team1["drawQ2"].sum(),
|
||
"drawQ3": df_schedule_quarter_team1["drawQ3"].sum(),
|
||
"drawQ4": df_schedule_quarter_team1["drawQ4"].sum(),
|
||
"drawOT1": df_schedule_quarter_team1["drawOT1"].sum(),
|
||
"drawOT2": df_schedule_quarter_team1["drawOT2"].sum(),
|
||
"drawOT3": df_schedule_quarter_team1["drawOT3"].sum(),
|
||
"drawOT4": df_schedule_quarter_team1["drawOT4"].sum(),
|
||
"scoreQ1": df_schedule_quarter_team1_new["scoreQ1"].sum(),
|
||
"scoreQ2": df_schedule_quarter_team1_new["scoreQ2"].sum(),
|
||
"scoreQ3": df_schedule_quarter_team1_new["scoreQ3"].sum(),
|
||
"scoreQ4": df_schedule_quarter_team1_new["scoreQ4"].sum(),
|
||
"scoreOT1": df_schedule_quarter_team1_new["scoreOT1"].sum(),
|
||
"scoreOT2": df_schedule_quarter_team1_new["scoreOT2"].sum(),
|
||
"scoreOT3": df_schedule_quarter_team1_new["scoreOT3"].sum(),
|
||
"scoreOT4": df_schedule_quarter_team1_new["scoreOT4"].sum(),
|
||
"score_avgQ1": df_schedule_quarter_team1_new["scoreQ1"].mean(),
|
||
"score_avgQ2": df_schedule_quarter_team1_new["scoreQ2"].mean(),
|
||
"score_avgQ3": df_schedule_quarter_team1_new["scoreQ3"].mean(),
|
||
"score_avgQ4": df_schedule_quarter_team1_new["scoreQ4"].mean(),
|
||
"score_avgOT1": df_schedule_quarter_team1_new["scoreOT1"].mean(),
|
||
"score_avgOT2": df_schedule_quarter_team1_new["scoreOT2"].mean(),
|
||
"score_avgOT3": df_schedule_quarter_team1_new["scoreOT3"].mean(),
|
||
"score_avgOT4": df_schedule_quarter_team1_new["scoreOT4"].mean(),
|
||
},
|
||
{
|
||
"team": team2_name,
|
||
"winQ1": df_schedule_quarter_team2["winQ1"].sum(),
|
||
"winQ2": df_schedule_quarter_team2["winQ2"].sum(),
|
||
"winQ3": df_schedule_quarter_team2["winQ3"].sum(),
|
||
"winQ4": df_schedule_quarter_team2["winQ4"].sum(),
|
||
"winOT1": df_schedule_quarter_team2["winOT1"].sum(),
|
||
"winOT2": df_schedule_quarter_team2["winOT2"].sum(),
|
||
"winOT3": df_schedule_quarter_team2["winOT3"].sum(),
|
||
"winOT4": df_schedule_quarter_team2["winOT4"].sum(),
|
||
"loseQ1": df_schedule_quarter_team2["loseQ1"].sum(),
|
||
"loseQ2": df_schedule_quarter_team2["loseQ2"].sum(),
|
||
"loseQ3": df_schedule_quarter_team2["loseQ3"].sum(),
|
||
"loseQ4": df_schedule_quarter_team2["loseQ4"].sum(),
|
||
"loseOT1": df_schedule_quarter_team2["loseOT1"].sum(),
|
||
"loseOT2": df_schedule_quarter_team2["loseOT2"].sum(),
|
||
"loseOT3": df_schedule_quarter_team2["loseOT3"].sum(),
|
||
"loseOT4": df_schedule_quarter_team2["loseOT4"].sum(),
|
||
"drawQ1": df_schedule_quarter_team2["drawQ1"].sum(),
|
||
"drawQ2": df_schedule_quarter_team2["drawQ2"].sum(),
|
||
"drawQ3": df_schedule_quarter_team2["drawQ3"].sum(),
|
||
"drawQ4": df_schedule_quarter_team2["drawQ4"].sum(),
|
||
"drawOT1": df_schedule_quarter_team2["drawOT1"].sum(),
|
||
"drawOT2": df_schedule_quarter_team2["drawOT2"].sum(),
|
||
"drawOT3": df_schedule_quarter_team2["drawOT3"].sum(),
|
||
"drawOT4": df_schedule_quarter_team2["drawOT4"].sum(),
|
||
"scoreQ1": df_schedule_quarter_team2_new["scoreQ1"].sum(),
|
||
"scoreQ2": df_schedule_quarter_team2_new["scoreQ2"].sum(),
|
||
"scoreQ3": df_schedule_quarter_team2_new["scoreQ3"].sum(),
|
||
"scoreQ4": df_schedule_quarter_team2_new["scoreQ4"].sum(),
|
||
"scoreOT1": df_schedule_quarter_team2_new["scoreOT1"].sum(),
|
||
"scoreOT2": df_schedule_quarter_team2_new["scoreOT2"].sum(),
|
||
"scoreOT3": df_schedule_quarter_team2_new["scoreOT3"].sum(),
|
||
"scoreOT4": df_schedule_quarter_team2_new["scoreOT4"].sum(),
|
||
"score_avgQ1": df_schedule_quarter_team2_new["scoreQ1"].mean(),
|
||
"score_avgQ2": df_schedule_quarter_team2_new["scoreQ2"].mean(),
|
||
"score_avgQ3": df_schedule_quarter_team2_new["scoreQ3"].mean(),
|
||
"score_avgQ4": df_schedule_quarter_team2_new["scoreQ4"].mean(),
|
||
"score_avgOT1": df_schedule_quarter_team2_new["scoreOT1"].mean(),
|
||
"score_avgOT2": df_schedule_quarter_team2_new["scoreOT2"].mean(),
|
||
"score_avgOT3": df_schedule_quarter_team2_new["scoreOT3"].mean(),
|
||
"score_avgOT4": df_schedule_quarter_team2_new["scoreOT4"].mean(),
|
||
},
|
||
]
|
||
|
||
for i in schedule_json_quarter:
|
||
i["scoreQ1"] = int(i["scoreQ1"])
|
||
i["scoreQ2"] = int(i["scoreQ2"])
|
||
i["scoreQ3"] = int(i["scoreQ3"])
|
||
i["scoreQ4"] = int(i["scoreQ4"])
|
||
i["scoreOT1"] = int(i["scoreOT1"])
|
||
i["scoreOT2"] = int(i["scoreOT2"])
|
||
i["scoreOT3"] = int(i["scoreOT3"])
|
||
i["scoreOT4"] = int(i["scoreOT4"])
|
||
i["score_avgQ1"] = round(i["score_avgQ1"], 1) if i["score_avgQ1"] else None
|
||
i["score_avgQ2"] = round(i["score_avgQ2"], 1) if i["score_avgQ2"] else None
|
||
i["score_avgQ3"] = round(i["score_avgQ3"], 1) if i["score_avgQ3"] else None
|
||
i["score_avgQ4"] = round(i["score_avgQ4"], 1) if i["score_avgQ4"] else None
|
||
i["score_avgOT1"] = round(i["score_avgOT1"], 1) if i["score_avgOT1"] else None
|
||
i["score_avgOT2"] = round(i["score_avgOT2"], 1) if i["score_avgOT2"] else None
|
||
i["score_avgOT3"] = round(i["score_avgOT3"], 1) if i["score_avgOT3"] else None
|
||
i["score_avgOT4"] = round(i["score_avgOT4"], 1) if i["score_avgOT4"] else None
|
||
rewrite_file("scores_quarter", schedule_json_quarter)
|
||
|
||
|
||
def Player_Stats_Online_Per_Quarter(data, event):
|
||
logger.info("START making json for players_stats_per_quarter")
|
||
payload1 = Team_Stat_Game(f'{data["team1_id"]}', data["game_id"])
|
||
team1_formatted = [i for i in payload1["starts"] if i["startRole"] == "Player"]
|
||
team1_formatted = pd.DataFrame(team1_formatted)
|
||
team1_formatted_json = team1_formatted.copy()
|
||
payload2 = Team_Stat_Game(f'{data["team2_id"]}', data["game_id"])
|
||
team2_formatted = [i for i in payload2["starts"] if i["startRole"] == "Player"]
|
||
team2_formatted = pd.DataFrame(team2_formatted)
|
||
team2_formatted_json = team2_formatted.copy()
|
||
|
||
while not event.is_set():
|
||
data_pbp = Game_Online(data["game_id"])
|
||
data_pbp = data_pbp["result"]["plays"]
|
||
|
||
df_data_pbp_2 = pd.DataFrame(data_pbp)
|
||
if "play" in df_data_pbp_2:
|
||
period_max = df_data_pbp_2[::-1].iloc[0]["period"]
|
||
childrens = []
|
||
for d in data_pbp:
|
||
if d["children"] != []:
|
||
for child in d["children"]:
|
||
child["sec"] = d["sec"]
|
||
child["period"] = d["period"]
|
||
child["play_parent"] = d["play"]
|
||
childrens.append(child)
|
||
if childrens:
|
||
df_childers = pd.DataFrame(childrens)
|
||
df_data_pbp_2 = pd.concat(
|
||
[df_data_pbp_2, df_childers], ignore_index=True
|
||
)
|
||
|
||
temp_data_all = []
|
||
temp_data_all = pd.concat([team1_formatted_json, team2_formatted_json])
|
||
players_start_num_1 = list(team1_formatted_json["startNum"])
|
||
players_start_num_2 = list(team2_formatted_json["startNum"])
|
||
df_info_players = pd.DataFrame(temp_data_all)
|
||
plays_uniq = [x for x in range(100)] # + ["q_ast_NO"]
|
||
players_uniq = sorted(df_data_pbp_2["startNum"].unique())[3:]
|
||
columns_temp_8 = [
|
||
f"Четверть {i}" if i < 5 else f"Овертайм {i-4}"
|
||
for i in range(1, int(period_max) + 1)
|
||
]
|
||
for i in range(1, int(period_max) + 1):
|
||
df_sorted_period = df_data_pbp_2.loc[df_data_pbp_2["period"] == i]
|
||
df_sorted_period_last = df_sorted_period[::-1].iloc[0]["sec"]
|
||
|
||
time_8_1 = df_sorted_period.loc[(df_sorted_period["play"] == 8)]
|
||
time_9_1 = df_sorted_period.loc[(df_sorted_period["play"] == 9)]
|
||
time_8_1 = (
|
||
time_8_1[["sec", "period", "startNum", "play"]]
|
||
.groupby(by="startNum")
|
||
.sum()
|
||
)
|
||
time_9_1 = (
|
||
time_9_1[["sec", "period", "startNum", "play"]]
|
||
.groupby(by="startNum")
|
||
.sum()
|
||
)
|
||
|
||
time_new_1 = pd.merge(
|
||
time_8_1,
|
||
time_9_1,
|
||
left_index=True,
|
||
right_index=True,
|
||
how="left",
|
||
)
|
||
time_new_1["last_sec"] = df_sorted_period_last
|
||
time_new_1["sec_y"] = time_new_1["sec_y"].fillna(0)
|
||
time_new_1["sec_y"] = time_new_1.apply(
|
||
lambda row: (
|
||
row["sec_y"] + row["last_sec"]
|
||
if (row["sec_y"] - row["sec_x"] < 0) or row["sec_y"] == 0
|
||
else row["sec_y"]
|
||
),
|
||
axis=1,
|
||
)
|
||
time_new_1["q_time"] = "0:00"
|
||
time_new_1["q_time"] = time_new_1.apply(
|
||
lambda row: format_time((row["sec_y"] - row["sec_x"]) // 10),
|
||
axis=1,
|
||
)
|
||
df_person_2 = pd.DataFrame(index=players_uniq, columns=plays_uniq)
|
||
# print(df_person_2)
|
||
df_person = (
|
||
df_sorted_period.groupby(["startNum", "play"])
|
||
.size()
|
||
.unstack(fill_value=0)
|
||
)
|
||
for startNum in players_uniq:
|
||
if startNum in df_person.index:
|
||
for play in plays_uniq:
|
||
if play in df_person.columns:
|
||
df_person_2.loc[startNum, play] = df_person.loc[
|
||
startNum, play
|
||
]
|
||
else:
|
||
df_person_2.loc[startNum, play] = 0
|
||
else:
|
||
for play in plays_uniq:
|
||
df_person_2.loc[startNum, play] = 0
|
||
df_person_2 = pd.merge(
|
||
df_person_2,
|
||
df_info_players,
|
||
how="left",
|
||
left_index=True,
|
||
right_on="startNum",
|
||
)
|
||
df_person_2 = pd.merge(
|
||
df_person_2,
|
||
time_new_1["q_time"],
|
||
how="left",
|
||
left_on="startNum",
|
||
right_on="startNum",
|
||
)
|
||
|
||
df_fouls_on = (
|
||
df_sorted_period.loc[
|
||
(df_sorted_period["play"].isin([50, 51, 52, 53, 54]))
|
||
]
|
||
.groupby(["startNum", "play"])
|
||
.size()
|
||
.unstack(fill_value=0)
|
||
)
|
||
df_fouls_on["q_f_on"] = df_fouls_on.sum(axis=1)
|
||
|
||
df_assists_no_goal = (
|
||
df_sorted_period.loc[
|
||
(df_sorted_period["play"] == 25)
|
||
& (df_sorted_period["play_parent"].isin([4, 5, 6, 27]))
|
||
]
|
||
.groupby(["startNum", "play"])
|
||
.size()
|
||
.unstack(fill_value=0)
|
||
)
|
||
df_assists_no_goal["q_ast_NO"] = df_assists_no_goal.sum(axis=1)
|
||
|
||
df_person_2 = pd.merge(
|
||
df_person_2,
|
||
df_assists_no_goal["q_ast_NO"],
|
||
how="left",
|
||
left_on="startNum",
|
||
right_on="startNum",
|
||
).fillna(0)
|
||
df_person_2 = pd.merge(
|
||
df_person_2,
|
||
df_fouls_on["q_f_on"],
|
||
how="left",
|
||
left_on="startNum",
|
||
right_on="startNum",
|
||
).fillna(0)
|
||
|
||
df_person_2_copy = df_person_2.copy()
|
||
# Concatenate columns and calculate q_pts
|
||
new_columns = {
|
||
"q_pts": df_person_2_copy[1]
|
||
+ df_person_2_copy[2] * 2
|
||
+ df_person_2_copy[3] * 3,
|
||
"q_to": df_person_2[10]
|
||
+ df_person_2[11]
|
||
+ df_person_2[12]
|
||
+ df_person_2[13]
|
||
+ df_person_2[14]
|
||
+ df_person_2[15]
|
||
+ df_person_2[16]
|
||
+ df_person_2[17]
|
||
+ df_person_2[18]
|
||
+ df_person_2[19]
|
||
+ df_person_2[20],
|
||
}
|
||
df_person_2 = pd.concat(
|
||
[df_person_2, pd.DataFrame(new_columns)], axis=1
|
||
)
|
||
df_person_2 = df_person_2.rename(
|
||
columns={
|
||
1: "q_ft",
|
||
2: "q_pt2",
|
||
3: "q_pt3",
|
||
4: "q_ft_t",
|
||
5: "q_pt2_t",
|
||
6: "q_pt3_t",
|
||
7: "q_ch",
|
||
8: "q_ch_in",
|
||
9: "q_ch_out",
|
||
10: "q_to_",
|
||
11: "q_to_pass",
|
||
12: "q_to_travel",
|
||
13: "q_to_out",
|
||
14: "q_to_zone",
|
||
15: "q_to_double_dribble",
|
||
16: "q_to_3_sec",
|
||
17: "q_to_5_sec",
|
||
18: "q_to_8_sec",
|
||
19: "q_to_24_sec",
|
||
20: "q_to_ball",
|
||
25: "q_ast",
|
||
26: "q_stl",
|
||
27: "q_blk",
|
||
28: "q_reb",
|
||
40: "q_f",
|
||
41: "q_foul_u",
|
||
42: "q_foul_t",
|
||
43: "q_foul_d",
|
||
44: "q_foul_c",
|
||
45: "q_foul_b",
|
||
47: "q_to_foul",
|
||
50: "q_to_foul_2",
|
||
}
|
||
)
|
||
df_person_2["q_ast"] = df_person_2["q_ast"] - df_person_2["q_ast_NO"]
|
||
columns_to_sum = [
|
||
"q_pts",
|
||
"q_ast",
|
||
"q_stl",
|
||
"q_blk",
|
||
"q_reb",
|
||
"q_f_on",
|
||
]
|
||
columns_to_subtract = [
|
||
"q_ft_t",
|
||
"q_pt2_t",
|
||
"q_pt3_t",
|
||
"q_f",
|
||
"q_to",
|
||
]
|
||
sum_df = df_person_2[columns_to_sum].sum(axis=1)
|
||
subtract_df = -df_person_2[columns_to_subtract].sum(axis=1)
|
||
df_person_2["q_rnk"] = pd.concat([sum_df, subtract_df], axis=1).sum(
|
||
axis=1
|
||
)
|
||
df_person_2 = df_person_2.sort_values(
|
||
["q_pts", "q_rnk"],
|
||
ascending=[False, False],
|
||
)
|
||
df_person_2["q_ft"] = (
|
||
df_person_2["q_ft"].astype(str)
|
||
+ "/"
|
||
+ (df_person_2["q_ft_t"] + df_person_2["q_ft"]).astype(str)
|
||
)
|
||
df_person_2["q_pt2"] = (
|
||
df_person_2["q_pt2"].astype(str)
|
||
+ "/"
|
||
+ (df_person_2["q_pt2_t"] + df_person_2["q_pt2"]).astype(str)
|
||
)
|
||
df_person_2["q_pt3"] = (
|
||
df_person_2["q_pt3"].astype(str)
|
||
+ "/"
|
||
+ (df_person_2["q_pt3_t"] + df_person_2["q_pt3"]).astype(str)
|
||
)
|
||
df_person_2["q_pt23"] = (
|
||
(
|
||
df_person_2["q_pt2"].apply(lambda x: int(x.split("/")[0]))
|
||
+ df_person_2["q_pt3"].apply(lambda x: int(x.split("/")[0]))
|
||
).astype(str)
|
||
+ "/"
|
||
+ (
|
||
df_person_2["q_pt2"].apply(lambda x: int(x.split("/")[1]))
|
||
+ df_person_2["q_pt3"].apply(lambda x: int(x.split("/")[1]))
|
||
).astype(str)
|
||
)
|
||
df_person_2["num"] = df_person_2["playerNumber"]
|
||
df_person_2["NameGFX"] = (
|
||
df_person_2["firstName"] + " " + df_person_2["lastName"]
|
||
)
|
||
df_person_2["role"] = df_person_2["positionName"]
|
||
df_person_2["teamName"] = df_person_2["teamNumber"].apply(
|
||
lambda x: data["team1"] if x == 1 else data["team2"]
|
||
)
|
||
role_list = [
|
||
("Center", "C"),
|
||
("Guard", "G"),
|
||
("Forward", "F"),
|
||
("Power forward", "PF"),
|
||
("Small forward", "SF"),
|
||
("Shooting guard", "SG"),
|
||
("Point guard", "PG"),
|
||
("Forward-center", "FC"),
|
||
]
|
||
role_dict = dict(role_list)
|
||
df_person_2["roleShort"] = df_person_2["role"].map(role_dict)
|
||
df_person_2["roleShort"] = df_person_2["roleShort"].fillna("")
|
||
df_person_2["photoGFX"] = df_person_2.apply(
|
||
lambda row: (
|
||
f"D:\\Photos\\{LEAGUE}\\{row['teamName']}\\{row['displayNumber']}.png"
|
||
if row["startRole"] == "Player"
|
||
else ""
|
||
),
|
||
axis=1,
|
||
)
|
||
|
||
df_person_2["Name1GFX"] = df_person_2["firstName"]
|
||
df_person_2["Name2GFX"] = df_person_2["lastName"]
|
||
columns_short = [
|
||
# "startNum",
|
||
"num",
|
||
"NameGFX",
|
||
"q_time",
|
||
"q_rnk",
|
||
"q_pts",
|
||
"q_reb",
|
||
"q_ast",
|
||
# "q_ast_NO",
|
||
"q_stl",
|
||
"q_blk",
|
||
"q_f",
|
||
"q_f_on",
|
||
"q_to",
|
||
"q_ft",
|
||
"q_pt2",
|
||
"q_pt3",
|
||
"q_pt23",
|
||
"age",
|
||
"height",
|
||
"weight",
|
||
"role",
|
||
"roleShort",
|
||
"photoGFX",
|
||
"Name1GFX",
|
||
"Name2GFX",
|
||
# "flag",
|
||
]
|
||
columns_to_int = [
|
||
"q_rnk",
|
||
"q_ast",
|
||
"q_pts",
|
||
"q_reb",
|
||
"q_stl",
|
||
"q_blk",
|
||
"q_f",
|
||
"q_f_on",
|
||
"q_to",
|
||
]
|
||
# print(list(df_person_2.columns))
|
||
df_person_2[columns_to_int] = df_person_2[columns_to_int].astype(int)
|
||
df_person_2_team_1 = df_person_2[columns_short].loc[
|
||
(df_person_2["startNum"].isin(players_start_num_1))
|
||
& (df_person_2["role"] != "Coach")
|
||
& (df_person_2["q_time"] != 0)
|
||
]
|
||
df_person_2_team_2 = df_person_2[columns_short].loc[
|
||
(df_person_2["startNum"].isin(players_start_num_2))
|
||
& (df_person_2["role"] != "Coach")
|
||
& (df_person_2["q_time"] != 0)
|
||
]
|
||
|
||
df_person_2_team_1.to_json(
|
||
f"JSON/team1_{i}.json",
|
||
orient="records",
|
||
force_ascii=False,
|
||
indent=4,
|
||
)
|
||
df_person_2_team_2.to_json(
|
||
f"JSON/team2_{i}.json",
|
||
orient="records",
|
||
force_ascii=False,
|
||
indent=4,
|
||
)
|
||
|
||
logger.debug("успешная запись данных players_stats_per_quarter в файл")
|
||
time.sleep(0.5)
|
||
|
||
|
||
def main():
|
||
data = get_season_and_schedule()
|
||
How_To_Play_Quarter(data)
|
||
logger.info(
|
||
f"{myhost}\n<b>{data['team1']}</b> VS {data['team2']}\n<i>{data['when']} {data['time']}</i>"
|
||
)
|
||
logger.debug(data)
|
||
|
||
team1_event = Event()
|
||
team2_event = Event()
|
||
teams_stat_event = Event()
|
||
referee_event = Event()
|
||
scores_quarter_event = Event()
|
||
standings_event = Event()
|
||
status_online_event = Event()
|
||
play_by_play_event = Event()
|
||
players_quarter_event = Event()
|
||
|
||
team1_monitor_thread = Thread(
|
||
target=restartable_thread,
|
||
args=(Json_Team_Generation, ("team1", data, team1_event), team1_event),
|
||
)
|
||
team2_monitor_thread = Thread(
|
||
target=restartable_thread,
|
||
args=(Json_Team_Generation, ("team2", data, team2_event), team2_event),
|
||
)
|
||
teams_stat_monitor_thread = Thread(
|
||
target=restartable_thread,
|
||
args=(Team_Both_Stat, (data, teams_stat_event), teams_stat_event),
|
||
)
|
||
referee_monitor_thread = Thread(
|
||
target=restartable_thread,
|
||
args=(Referee, (data, referee_event), referee_event),
|
||
)
|
||
scores_quarter_monitor_thread = Thread(
|
||
target=restartable_thread,
|
||
args=(Scores_Quarter, (data, scores_quarter_event), scores_quarter_event),
|
||
)
|
||
standings_monitor_thread = Thread(
|
||
target=restartable_thread,
|
||
args=(Standing_func, (data, standings_event), standings_event),
|
||
)
|
||
status_online_monitor_thread = Thread(
|
||
target=restartable_thread,
|
||
args=(Status_Online, (data, status_online_event), status_online_event),
|
||
)
|
||
play_by_play_monitor_thread = Thread(
|
||
target=restartable_thread,
|
||
args=(Play_By_Play, (data, play_by_play_event), play_by_play_event),
|
||
)
|
||
players_quarter_monitor_thread = Thread(
|
||
target=restartable_thread,
|
||
args=(
|
||
Player_Stats_Online_Per_Quarter,
|
||
(data, players_quarter_event),
|
||
players_quarter_event,
|
||
),
|
||
)
|
||
|
||
try:
|
||
team1_monitor_thread.start()
|
||
team2_monitor_thread.start()
|
||
teams_stat_monitor_thread.start()
|
||
referee_monitor_thread.start()
|
||
scores_quarter_monitor_thread.start()
|
||
standings_monitor_thread.start()
|
||
status_online_monitor_thread.start()
|
||
play_by_play_monitor_thread.start()
|
||
players_quarter_monitor_thread.start()
|
||
while True:
|
||
time.sleep(1)
|
||
except KeyboardInterrupt:
|
||
logger.info("Прерывание программы пользователем. Завершаем потоки...")
|
||
team1_event.set()
|
||
team2_event.set()
|
||
teams_stat_event.set()
|
||
referee_event.set()
|
||
scores_quarter_event.set()
|
||
standings_event.set()
|
||
status_online_event.set()
|
||
play_by_play_event.set()
|
||
players_quarter_event.set()
|
||
finally:
|
||
team1_monitor_thread.join()
|
||
team2_monitor_thread.join()
|
||
teams_stat_monitor_thread.join()
|
||
referee_monitor_thread.join()
|
||
scores_quarter_monitor_thread.join()
|
||
standings_monitor_thread.join()
|
||
status_online_monitor_thread.join()
|
||
play_by_play_monitor_thread.join()
|
||
players_quarter_monitor_thread.join()
|
||
logger.info("Все потоки завершены.")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
start = time.perf_counter()
|
||
main()
|
||
end = time.perf_counter()
|
||
delta = end - start
|
||
print("=" * 20)
|
||
print(
|
||
f"выполнено за {delta:.2f} секунд = {int(end - start)//60}м{int(end - start)%60}с"
|
||
)
|