From fce1b6989347ee908095ed6c70ebebb6620b817b Mon Sep 17 00:00:00 2001 From: sherl Date: Fri, 13 Jun 2025 11:09:18 +0200 Subject: [PATCH] chore: prepare for rescraping --- FlaskWebProject/FlaskWebProject/fs_scraper.py | 26 ++++++- .../FlaskWebProject/lewy_api_v1.py | 77 +++++++++++++++++++ FlaskWebProject/FlaskWebProject/lewy_db.py | 39 +++++++++- 3 files changed, 135 insertions(+), 7 deletions(-) diff --git a/FlaskWebProject/FlaskWebProject/fs_scraper.py b/FlaskWebProject/FlaskWebProject/fs_scraper.py index 20b1e04..d3ecae8 100644 --- a/FlaskWebProject/FlaskWebProject/fs_scraper.py +++ b/FlaskWebProject/FlaskWebProject/fs_scraper.py @@ -177,7 +177,25 @@ class scraper: stats = safe_traverse(match, ["stats"], default="") zewnetrzne_id_meczu = safe_traverse(match, ["eventEncodedId"], default="") + wygrana_str = safe_traverse(match, ["winLoseShort"], default="R").upper() + klub_zawodnika = "undefined" + # Zwycięstwo klubu zawodnika + if wygrana_str == "Z": + if safe_traverse(match, ["homeScore"], default=0) > safe_traverse(match, ["awayScore"], default=0): + klub_zawodnika = home_club_id + else: + klub_zawodnika = away_club_id + # Przegrana klubu zawodnika + elif wygrana_str == "P": + if safe_traverse(match, ["homeScore"], default=0) > safe_traverse(match, ["awayScore"], default=0): + klub_zawodnika = away_club_id + else: + klub_zawodnika = home_club_id + + #klub_z = getDb().simple_select_all("kluby", id_klubu=klub_zawodnika) + if stats != False: # gdy sportowiec był aktywny w meczu + safe_traverse(stats, ["596", "value"], default=None) # print("todo :)") self.db.simple_insert_one("sportowcy_w_meczach", id_zawodnika = id_zawodnika, @@ -193,7 +211,8 @@ class scraper: zolte_kartki = int("0" + safe_traverse(stats, ["599", "value"], default="0")), czerwone_kartki = int("0" + safe_traverse(stats, ["600", "value"], default="0")), wygrana = {"Z": 1, "R": 0, "P": -1}.get(safe_traverse(match, ["winLoseShort"], default=""), 0), - wynik = safe_traverse(match, ["rating"], default=0) or 0 + wynik = safe_traverse(match, ["rating"], default=0) or 0, + klub_id = klub_zawodnika ) # # analogicznie zinkrementuj statystyki_sportowcow: @@ -236,8 +255,9 @@ class scraper: zolte_kartki = int("0" + safe_traverse(stats, ["599", "value"], default="0")), czerwone_kartki = int("0" + safe_traverse(stats, ["600", "value"], default="0")), wygrana = {"Z": 1, "R": 0, "P": -1}.get(safe_traverse(match, ["winLoseShort"], default=""), 0), - wynik = safe_traverse(match, ["rating"], default=0) or 0 - ) + wynik = safe_traverse(match, ["rating"], default=0) or 0, + klub_id = klub_zawodnika + ) # TODO: Zaktualizuj statystyki sportowca diff --git a/FlaskWebProject/FlaskWebProject/lewy_api_v1.py b/FlaskWebProject/FlaskWebProject/lewy_api_v1.py index a4e0418..afbe4ba 100644 --- a/FlaskWebProject/FlaskWebProject/lewy_api_v1.py +++ b/FlaskWebProject/FlaskWebProject/lewy_api_v1.py @@ -133,6 +133,79 @@ def get_matches(r = None, id_zawodnika: str | None = None, rok: int | None = Non # print(f"zwracam mecze: {response_json}") return 200, "ok", response_json +# GET /api/v1/player_stats +def player_stats(r = None, id_zawodnika: str | None = None): + """ + Zwraca mecze. + Przykład wywołania: + player_stats(r, id_zawodnika=1), tożsame z GET /api/v1/player_stats?id_zawodnika=1 + player_stats(r), tożsame z GET /api/v1/player_stats + """ + response_json = [] + + if id_zawodnika is None: + # Gdy nie podano id wprost, sprawdź, czy podano je przez parametr. + id_zawodnika = r.args.get('id_zawodnika', -1) + + if rok is None: + # Gdy nie podano roku wprost, sprawdź, czy podano je przez parametr. + # Jeśli nie, przyjmij None (2025). + rok = r.args.get('rok', None) + + # Sprawdź, czy podano jakiekolwiek ID sportowca. Jeżeli nie, wypisz wszystkie mecze. + if id_zawodnika == -1: + mecze = getDb().get_sportsman_matches(year=rok) + + # Sprawdź, czy sportowiec o podanym (lub niepodanym) id istnieje. + # Jeśli nie istnieje, wypisz wszystkie mecze. + elif not czy_sportowiec_istnieje(id_zawodnika=id_zawodnika): + return 404, "error", {"error_msg": "This sportsman has not been found in the database. Try: id_zawodnika=1"} + + # Gdy sportowiec istnieje, wypisz jego mecze. + else: + mecze = getDb().get_sportsman_matches(id_zawodnika=id_zawodnika, year=rok) + + for mecz in mecze: + response_json.append(mecz.jsonify()) + # print(f"zwracam mecze: {response_json}") + return 200, "ok", response_json + +# GET /api/v1/player_stats +def robert_stats(r = None, id_zawodnika: str | None = None): + """ + Zwraca mecze. + Przykład wywołania: + robert_stats(r), tożsame z GET /api/v1/robert_stats + """ + response_json = [] + + if id_zawodnika is None: + # Gdy nie podano id wprost, sprawdź, czy podano je przez parametr. + id_zawodnika = r.args.get('id_zawodnika', -1) + + if rok is None: + # Gdy nie podano roku wprost, sprawdź, czy podano je przez parametr. + # Jeśli nie, przyjmij None (2025). + rok = r.args.get('rok', None) + + # Sprawdź, czy podano jakiekolwiek ID sportowca. Jeżeli nie, wypisz wszystkie mecze. + if id_zawodnika == -1: + mecze = getDb().get_sportsman_matches(year=rok) + + # Sprawdź, czy sportowiec o podanym (lub niepodanym) id istnieje. + # Jeśli nie istnieje, wypisz wszystkie mecze. + elif not czy_sportowiec_istnieje(id_zawodnika=id_zawodnika): + return 404, "error", {"error_msg": "This sportsman has not been found in the database. Try: id_zawodnika=1"} + + # Gdy sportowiec istnieje, wypisz jego mecze. + else: + mecze = getDb().get_sportsman_matches(id_zawodnika=id_zawodnika, year=rok) + + for mecz in mecze: + response_json.append(mecz.jsonify()) + # print(f"zwracam mecze: {response_json}") + return 200, "ok", response_json + # GET /api/v1/debugger_halt?token=XXX... @require_authentication def debugger_halt(r): @@ -185,6 +258,10 @@ def lookup(data, request): return debugger_halt(r = request) case 'matches': return get_matches(r = request) + case 'player_stats': + return player_stats(r = request) + case 'robert_stats': + return robert_stats(r = request) case _: increment_bad_requests() return not_implemented(data) \ No newline at end of file diff --git a/FlaskWebProject/FlaskWebProject/lewy_db.py b/FlaskWebProject/FlaskWebProject/lewy_db.py index 7c04692..6a154a0 100644 --- a/FlaskWebProject/FlaskWebProject/lewy_db.py +++ b/FlaskWebProject/FlaskWebProject/lewy_db.py @@ -1,7 +1,7 @@ from datetime import datetime from flask_sqlalchemy import SQLAlchemy from functools import wraps -from sqlalchemy import ForeignKey, select, insert, update, extract +from sqlalchemy import ForeignKey, select, insert, update, extract, func from sqlalchemy.orm import Mapped, mapped_column, DeclarativeBase, Session, relationship from typing import List import time @@ -105,6 +105,8 @@ class baza(): czerwone_kartki: Mapped[ int] = mapped_column() wygrana: Mapped[ int] = mapped_column() wynik: Mapped[ float] = mapped_column() + klub_id: Mapped[ int] = mapped_column(ForeignKey(f"{tnp}kluby.id_klubu")) + klub: Mapped[ "kluby"] = relationship() def __repr__(self): return f"<{self.zawodnik.imie} {self.zawodnik.nazwisko} w meczu {self.mecz.gospodarze.skrocona_nazwa} vs. {self.mecz.goscie.skrocona_nazwa}>" @@ -201,12 +203,12 @@ class baza(): with self.app.app_context(): self.session = Session(self.db.engine) - def exit_gracefully(func): - @wraps(func) + def exit_gracefully(fun): + @wraps(fun) def wrapper(self, *args, **kwargs): return_val = None try: - return_val = func(self, *args, **kwargs) + return_val = fun(self, *args, **kwargs) except: print(f"{c.FAIL}" f"Wystąpił błąd podczas wykonywania zapytania SQL:" @@ -553,6 +555,35 @@ class baza(): return query.all() + @exit_gracefully + def get_basic_stats(self, id_zawodnika = None, zewnetrzne_id_zawodnika = None): + + # Spróbuj otrzymać id zawodnika z zewnętrznego id. + if zewnetrzne_id_zawodnika is not None: + id_zawodnika = self.get_id_zawodnika_by_zewnetrzne_id(zewnetrzne_id_zawodnika) + + if id_zawodnika is None: + return [] + + # Aliasy + SportowcyWMeczach = self.entities["sportowcy_w_meczach"] + + query = self.session.query( + func.count(SportowcyWMeczach.id_rekordu ).label('unique_items'), + func.sum( SportowcyWMeczach.czas_gry ).label('time_played'), + func.sum( SportowcyWMeczach.goli ).label('goals'), + func.sum( SportowcyWMeczach.asyst ).label('assists'), + func.sum( SportowcyWMeczach.zolte_kartki ).label('yellow_cards'), + func.sum( SportowcyWMeczach.czerwone_kartki).label('red_cards'), + func.avg( SportowcyWMeczach.wynik ).label('avg_score'), + ).where( + SportowcyWMeczach.czas_gry > 0 + ).where( + SportowcyWMeczach.id_zawodnika == id_zawodnika + ) + + return query.all()[0] + @exit_gracefully def sample_data_init(self, override_safety_check=False): """