diff --git a/FlaskWebProject/FlaskWebProject/lewy_api_v1.py b/FlaskWebProject/FlaskWebProject/lewy_api_v1.py index 2457e2a..3075f33 100644 --- a/FlaskWebProject/FlaskWebProject/lewy_api_v1.py +++ b/FlaskWebProject/FlaskWebProject/lewy_api_v1.py @@ -139,7 +139,7 @@ def get_matches(r = None, id_zawodnika: str | None = None, rok: int | None = Non # GET /api/v1/player_stats def player_stats(r = None, id_zawodnika: str | None = None): """ - Zwraca mecze. + Zwraca statystyki gracza. 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 @@ -151,11 +151,10 @@ def player_stats(r = None, id_zawodnika: str | None = None): id_zawodnika = r.args.get('id_zawodnika', 0) # 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. + # Gdy sportowiec istnieje, wypisz jego statystyki. else: staty = getDb().get_basic_stats(id_zawodnika=id_zawodnika) @@ -168,6 +167,9 @@ def player_stats(r = None, id_zawodnika: str | None = None): 'yellow_cards': staty[4], 'red_cards': staty[5], 'avg_score': staty[6], + 'wins': staty[7], + 'draws': staty[8], + 'losses': staty[9] } ) print(f"zwracam staty: {response_json}") @@ -176,27 +178,26 @@ def player_stats(r = None, id_zawodnika: str | None = None): # GET /api/v1/robert_stats def robert_stats(r = None, id_klubu: str | None = None): """ - Zwraca mecze. + Zwraca statystyki Roberta w danym klubie. Przykład wywołania: - robert_stats(r, id_zawodnika=1), tożsame z GET /api/v1/robert_stats?id_klubu=barcelona - robert_stats(r), tożsame z GET /api/v1/robert_stats + robert_stats(r, id_klubu="barcelona"), tożsame z GET /api/v1/robert_stats?id_klubu=barcelona """ response_json = [] if id_klubu is None: # Gdy nie podano id wprost, sprawdź, czy podano je przez parametr. - id_klubu = r.args.get('id_klubu', 0) + id_klubu = r.args.get('id_klubu', "non-existent-club-id") - # Sprawdź, czy sportowiec o podanym (lub niepodanym) id istnieje. - # Jeśli nie istnieje, wypisz wszystkie mecze. - elif not czy_klub_istnieje(id_klubu=id_klubu): + # Sprawdź, czy klub o podanym (lub niepodanym) id istnieje. + if not czy_klub_istnieje(id_klubu=id_klubu): return 404, "error", {"error_msg": "This club has not been found in the database. Try: id_klubu=barcelona"} - # Gdy sportowiec istnieje, wypisz jego mecze. + # Gdy klub istnieje, wypisz statystyki z tego klubu. else: staty = getDb().get_sportsman_club_stats(id_zawodnika=1, id_klubu=id_klubu) # for stat in staty: + print(staty) response_json.append({ 'unique_items': staty[0], 'time_played': staty[1], @@ -205,11 +206,46 @@ def robert_stats(r = None, id_klubu: str | None = None): 'yellow_cards': staty[4], 'red_cards': staty[5], 'avg_score': staty[6], + 'wins': staty[7], + 'draws': staty[8], + 'losses': staty[9] } ) print(f"zwracam staty roberta: {response_json}") return 200, "ok", response_json +# GET /api/v1/clubs +def clubs(r, id_klubu: str = None): + """ + Zwraca informacje o klubach. + Przykład wywołania: + clubs(r, id_klubu="barcelona"), tożsame z GET /api/v1/clubs?id_klubu=barcelona + clubs(r), tożsame z GET /api/v1/clubs + """ + response_json = [] + + if id_klubu is None: + # Gdy nie podano id wprost, sprawdź, czy podano je przez parametr. + id_klubu = r.args.get('id_klubu', -1) + + if id_klubu == -1: + kluby = getDb().simple_select_all("kluby") + + # Sprawdź, czy sportowiec o podanym (lub niepodanym) id istnieje. + # Jeśli nie istnieje, wypisz wszystkie mecze. + elif not czy_klub_istnieje(id_klubu=id_klubu): + return 404, "error", {"error_msg": "This club has not been found in the database. Try: id_klubu=barcelona"} + + # Gdy sportowiec istnieje, wypisz jego mecze. + else: + kluby = getDb().simple_select_all("kluby", id_klubu=id_klubu) + + for klub in kluby: + response_json.append(klub.jsonify()) + + print(f"zwracam kluby: {response_json}") + return 200, "ok", response_json + # GET /api/v1/debugger_halt?token=XXX... @require_authentication def debugger_halt(r): @@ -266,6 +302,8 @@ def lookup(data, request): return player_stats(r = request) case 'robert_stats': return robert_stats(r = request) + case 'clubs': + return clubs(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 5039479..7adf6b1 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, func +from sqlalchemy import ForeignKey, select, insert, update, extract, func, case, literal_column from sqlalchemy.orm import Mapped, mapped_column, DeclarativeBase, Session, relationship from typing import List import time @@ -145,6 +145,13 @@ class baza(): def __repr__(self): return f"" + def jsonify(self): + return { + "id_klubu": self.id_klubu, + "pelna_nazwa": self.pelna_nazwa, + "skrocona_nazwa": self.skrocona_nazwa + } + class mecze(Base): __tablename__ = tnp + "mecze" id_meczu: Mapped[ int] = mapped_column(primary_key=True, autoincrement=True) @@ -568,6 +575,10 @@ class baza(): # Aliasy SportowcyWMeczach = self.entities["sportowcy_w_meczach"] + # Zlicz liczbę zwycięstw, remisów i przegranych. + # https://stackoverflow.com/a/3975328 + # https://stackoverflow.com/a/49064561 + # Czy da się to zrobić prościej? Nie wiem. ~ sherl query = self.session.query( func.count(SportowcyWMeczach.id_rekordu ).label('unique_items'), func.sum( SportowcyWMeczach.czas_gry ).label('time_played'), @@ -576,6 +587,31 @@ class baza(): func.sum( SportowcyWMeczach.zolte_kartki ).label('yellow_cards'), func.sum( SportowcyWMeczach.czerwone_kartki).label('red_cards'), func.avg( SportowcyWMeczach.wynik ).label('avg_score'), + + # Kompatybilne z każdą bazą. + # https://docs.sqlalchemy.org/en/20/core/sqlelement.html#sqlalchemy.sql.expression.case + # https://modern-sql.com/feature/filter + func.sum( + case( + (SportowcyWMeczach.wygrana == 1, 1), + else_ = 0 + ) + ).label('wins'), + + func.sum( + case( + (SportowcyWMeczach.wygrana == 0, 1), + else_ = 0 + ) + ).label('draws'), + + func.sum( + case( + (SportowcyWMeczach.wygrana == -1, 1), + else_ = 0 + ) + ).label('losses'), + ).where( SportowcyWMeczach.czas_gry > 0 ).where( @@ -603,6 +639,10 @@ class baza(): # Aliasy SportowcyWMeczach = self.entities["sportowcy_w_meczach"] + # Zlicz liczbę zwycięstw, remisów i przegranych. + # https://stackoverflow.com/a/3975328 + # https://stackoverflow.com/a/49064561 + # Czy da się to zrobić prościej? Nie wiem. ~ sherl query = self.session.query( func.count(SportowcyWMeczach.id_rekordu ).label('unique_items'), func.sum( SportowcyWMeczach.czas_gry ).label('time_played'), @@ -611,6 +651,34 @@ class baza(): func.sum( SportowcyWMeczach.zolte_kartki ).label('yellow_cards'), func.sum( SportowcyWMeczach.czerwone_kartki).label('red_cards'), func.avg( SportowcyWMeczach.wynik ).label('avg_score'), + + # Kompatybilne z każdą bazą. + # https://docs.sqlalchemy.org/en/20/core/sqlelement.html#sqlalchemy.sql.expression.case + # https://modern-sql.com/feature/filter + func.sum( + case( + (SportowcyWMeczach.wygrana == 1, 1), + else_ = 0 + ) + ).label('wins'), + + # UWAGA! Jeśli jest remis, to nie wiemy dla którego klubu grał sportowiec! + # Poniższe wyrażenie jest poprawne, to dane zwracane przez flashscore są + # niewystarczające, aby stwierdzić w którym klubie grał sportowiec! + func.sum( + case( + (SportowcyWMeczach.wygrana == 0, 1), + else_ = 0 + ) + ).label('draws'), + + func.sum( + case( + (SportowcyWMeczach.wygrana == -1, 1), + else_ = 0 + ) + ).label('losses'), + ).where( SportowcyWMeczach.czas_gry > 0 ).where( diff --git a/FlaskWebProject/FlaskWebProject/lewy_routes.py b/FlaskWebProject/FlaskWebProject/lewy_routes.py index 9a72e26..48ec3ef 100644 --- a/FlaskWebProject/FlaskWebProject/lewy_routes.py +++ b/FlaskWebProject/FlaskWebProject/lewy_routes.py @@ -3,7 +3,7 @@ import lewy_api_v1 import lewy_db import lewy_globals import json -from lewy_api_v1 import get_matches, player_stats, robert_stats +from lewy_api_v1 import get_matches, player_stats, robert_stats, clubs as get_clubs def get_lewy_stats(): stats = player_stats(id_zawodnika=1)[2][0] polska = robert_stats(id_klubu="polska")[2][0] @@ -37,6 +37,11 @@ def get_lewy_stats(): 'cards': { 'yellow': stats["yellow_cards"], # 86 'red': stats["red_cards"], # 2 + }, + 'wins_losses': { + 'wins': stats["wins"], + 'draws': stats["draws"], + 'losses': stats["losses"] } } @@ -78,28 +83,68 @@ def statystyki(): return render_template('stats.html', **dane) def clubs(): - selected_club = request.args.get("club","FC Barcelona") - clubs = [ - {'club': 'FC Barcelona', 'goals': 101,'assist':20, 'matches':147,'minutes_played': 11684,'yellow_card':12,'red_card': 1, 'wins':101, 'draws': 14,'lost': 32}, - {'club': 'Bayern Monachium', 'goals': 344,'assist':73,'matches':375,'minutes_played': 31759,'yellow_card':36,'red_card': 0, 'wins':307, 'draws': 35,'lost': 33}, - {'club': 'Borussia Dortmund', 'goals': 103,'assist':42,'matches':187,'minutes_played': 14374,'yellow_card':19,'red_card': 1, 'wins':120, 'draws': 40,'lost': 27}, - {'club': 'Lech Poznan', 'goals': 41,'assist':19,'matches':82,'minutes_played': 6858,'yellow_card':9,'red_card': 0, 'wins':'-', 'draws': '-','lost': '-'}, - ] - return render_template('club.html', clubs=clubs, selected_club=selected_club) + selected_club = request.args.get("club", "barcelona") + #clubs = [ + # {'club': 'FC Barcelona', 'goals': 101,'assist':20, 'matches':147,'minutes_played': 11684,'yellow_card':12,'red_card': 1, 'wins':101, 'draws': 14,'lost': 32}, + # {'club': 'Bayern Monachium', 'goals': 344,'assist':73,'matches':375,'minutes_played': 31759,'yellow_card':36,'red_card': 0, 'wins':307, 'draws': 35,'lost': 33}, + # {'club': 'Borussia Dortmund', 'goals': 103,'assist':42,'matches':187,'minutes_played': 14374,'yellow_card':19,'red_card': 1, 'wins':120, 'draws': 40,'lost': 27}, + # {'club': 'Lech Poznan', 'goals': 41,'assist':19,'matches':82,'minutes_played': 6858,'yellow_card':9,'red_card': 0, 'wins':'-', 'draws': '-','lost': '-'}, + #] + response_json = { + "club": "Błędny klub", + "goals": 0, + "assist": 0, + "matches": 0, + "minutes_played": 0, + "yellow_card": 0, + "red_card": 0, + "wins": 0, + "draws": 0, + "lost": 0 + } + + club = get_clubs(request, id_klubu=selected_club) + if club[1] == "ok": # gdy nie wystąpił bład, bo jest taki klub + club = club[2][0] + staty = robert_stats(id_klubu=club["id_klubu"])[2][0] + response_json["club"] = club["pelna_nazwa"] + response_json["goals"] = staty["goals"] + response_json["assist"] = staty["assists"] + response_json["matches"] = staty["unique_items"] + response_json["minutes_played"] = staty["time_played"] + response_json["yellow_card"] = staty["yellow_cards"] + response_json["red_card"] = staty["red_cards"] + response_json["wins"] = staty["wins"] + response_json["draws"] = staty["draws"] + response_json["lost"] = staty["losses"] + + return render_template('club.html', clubs=clubs, selected_club=selected_club, resp_json=response_json) def representation(): - nation_stats = { - 'goals': 85, - 'assists': 35, - 'matches': 158, - 'minutes_played': 12108, - 'yellow_card':10, - 'red_card': 0, - 'wins':75, - 'draws': 35, - 'lost': 48 - } - return render_template('representation.html', nation_stats=nation_stats) + # nation_stats = { + # 'goals': 85, + # 'assists': 35, + # 'matches': 158, + # 'minutes_played': 12108, + # 'yellow_card':10, + # 'red_card': 0, + # 'wins':75, + # 'draws': 35, + # 'lost': 48 + # } + response_json = {} + staty = robert_stats(id_klubu="polska")[2][0] + response_json["goals"] = staty["goals"] + response_json["assist"] = staty["assists"] + response_json["matches"] = staty["unique_items"] + response_json["minutes_played"] = staty["time_played"] + response_json["yellow_card"] = staty["yellow_cards"] + response_json["red_card"] = staty["red_cards"] + response_json["wins"] = staty["wins"] + response_json["draws"] = staty["draws"] + response_json["lost"] = staty["losses"] + return render_template('representation.html', nation_stats=response_json) + def compare(): selected_player = request.args.get("player","Leo Messi") lewy=get_lewy_stats() diff --git a/FlaskWebProject/FlaskWebProject/templates/club.html b/FlaskWebProject/FlaskWebProject/templates/club.html index 1000f31..f7ae429 100644 --- a/FlaskWebProject/FlaskWebProject/templates/club.html +++ b/FlaskWebProject/FlaskWebProject/templates/club.html @@ -4,59 +4,59 @@ {% block content %}
- + - + - + - +
-{% for stats in clubs %} - {% if stats.club == selected_club %} +{#{% for stats in clubs %}#} + {#{% if stats.club == selected_club %}#}
-

Statystyki dla {{selected_club}}

-
+

Statystyki dla {{resp_json.club}}

+
-

Gole:

{{ stats.goals }} +

Gole:

{{ resp_json.goals }}
-

Asysty:

{{ stats.assist }} +

Asysty:

{{ resp_json.assist }}
-

Występy:

{{ stats.matches }} +

Występy:

{{ resp_json.matches }}
-

Łączny czas gry:

{{ stats.minutes_played }} +

Łączny czas gry:

{{ resp_json.minutes_played }}
-

Żółte kartki:

{{ stats.yellow_card }} +

Żółte kartki:

{{ resp_json.yellow_card }}
-

Czerwone kartki:

{{ stats.red_card }} +

Czerwone kartki:

{{ resp_json.red_card }}
-

Zwycięstwa:

{{ stats.wins }} +

Zwycięstwa:

{{ resp_json.wins }}
-

Remisy:

{{ stats.draws }} +

Remisy:

{{ resp_json.draws }}
-

Porażki:

{{ stats.lost }} +

Porażki:

{{ resp_json.lost }}
- {% endif %} -{% endfor %} + {#{% endif %}#} +{#{% endfor %}#} {% endblock %} {% block footer %} diff --git a/FlaskWebProject/FlaskWebProject/templates/representation.html b/FlaskWebProject/FlaskWebProject/templates/representation.html index 7ba64d0..36ebe12 100644 --- a/FlaskWebProject/FlaskWebProject/templates/representation.html +++ b/FlaskWebProject/FlaskWebProject/templates/representation.html @@ -11,7 +11,7 @@

Gole:

{{ nation_stats.goals }}
-

Asysty:

{{ nation_stats.assists }} +

Asysty:

{{ nation_stats.assist }}

Występy:

{{ nation_stats.matches }} diff --git a/FlaskWebProject/FlaskWebProject/templates/stats.html b/FlaskWebProject/FlaskWebProject/templates/stats.html index eb263cf..0c344a9 100644 --- a/FlaskWebProject/FlaskWebProject/templates/stats.html +++ b/FlaskWebProject/FlaskWebProject/templates/stats.html @@ -56,7 +56,7 @@
-

Puchary międzynarodowe

+

(!) Puchary międzynarodowe

{{ international_cups.goals }}

@@ -73,7 +73,7 @@
-

Puchary krajowe

+

(!) Puchary krajowe

{{ national_cups.goals }}

@@ -103,4 +103,21 @@
+
+

Wygrane, remisy i przegrane

+
+
+

{{ wins_losses.wins }}

+

Wygrane

+
+
+

{{ wins_losses.draws }}

+

Remisy

+
+
+

{{ wins_losses.losses }}

+

Przegrane

+
+
+
{% endblock %} \ No newline at end of file