27 Commits

Author SHA1 Message Date
afa666d2fd fix: scraper fix, add club info 2025-06-20 03:50:07 +02:00
b0ea0a836b scraper fix attempt 2025-06-20 01:19:48 +02:00
327aabde78 fix for goals 2025-06-16 23:21:34 +02:00
7ed241bc00 deleting some sections 2025-06-16 23:07:40 +02:00
ac2335a3bc one more 2025-06-16 23:00:38 +02:00
45dfd38f9a one fix for club stats 2025-06-16 22:57:19 +02:00
04b12d4657 fix: readd missing imports and funcs II 2025-06-15 04:59:37 +02:00
687bdedf88 fix: readd missing import 2025-06-15 04:52:37 +02:00
323a8b4973 Merge branch 'routes_using_api' 2025-06-15 04:50:27 +02:00
8bc1dcb876 feat: general improvements, show wins, losses, draws (broken for clubs) 2025-06-15 04:47:24 +02:00
fc5acd28f7 Revert "chore: prepare for rescraping"
This reverts commit fce1b69893.
this time it works
2025-06-13 12:32:38 +02:00
19e100b4b2 fix 2025-06-13 12:15:04 +02:00
fcf11d4a0d Revert "chore: prepare for rescraping"
This reverts commit fce1b69893.
2025-06-13 12:12:10 +02:00
fc1e636cfd feat: use api for matches 2025-06-13 12:04:25 +02:00
fce1b69893 chore: prepare for rescraping 2025-06-13 11:09:18 +02:00
7b457475b4 Merge branch 'frontend-fix' 2025-06-13 00:34:11 +02:00
8fb2a22c2a another one 2025-06-13 00:32:13 +02:00
d1f5f8f3f4 Merge branch 'frontend' 2025-06-13 00:31:57 +02:00
56e68ed751 fix: show only relevant matches for a given year 2025-06-13 00:31:19 +02:00
f96a3ed1f1 fix 2025-06-12 23:42:55 +02:00
416b2ccfe0 changing responsive design 2025-06-12 23:08:58 +02:00
00bbe05b1c feat: include club's full name in matches view 2025-06-12 22:35:04 +02:00
e373c6b274 hotfix: fixes /mecze endpoint not working (cause of a wrong API call) 2025-06-12 20:43:22 +02:00
e80ee6bf8f feat: return matches with respect to received sportsman id
also include a comment in the database model to include a relation
2025-06-12 20:36:10 +02:00
a25be482b0 matches from DB 2025-06-12 16:23:14 +02:00
4e8cb48c82 fix: safe_traverse renaming issue 2025-06-11 00:38:55 +02:00
bc82fcd6b8 chore: depend on safe_traverse from lewy_globals, add scraper cron job 2025-06-11 00:35:48 +02:00
12 changed files with 589 additions and 119 deletions

View File

@@ -1,23 +1,13 @@
from flask import session
from lewy_db import baza as ldb
from lewy_globals import colors as c
from lewy_globals import safeTraverse as safe_traverse
import json
import lewy_globals
import requests
import time
from sqlalchemy import func
def safe_traverse(obj: dict, path: list, default=None):
result = obj
try:
for x in path:
result = result[x]
except (KeyError, TypeError):
result = default
print(f"safe_traverse: error reading {' -> '.join(path)} - returning: {default}")
finally:
return result
class scraper:
headers = {
@@ -187,6 +177,21 @@ 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
if stats != False: # gdy sportowiec był aktywny w meczu
# print("todo :)")
self.db.simple_insert_one("sportowcy_w_meczach",
@@ -203,7 +208,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:
@@ -246,7 +252,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
)
# TODO: Zaktualizuj statystyki sportowca

View File

@@ -1,7 +1,7 @@
from argparse import ArgumentParser
from flask import Flask, Response, render_template
from flask_apscheduler import APScheduler
from fs_scraper import scraper as scr
from fs_scraper import scraper
from lewy_globals import colors as c
import lewy_api
import lewy_db
@@ -13,12 +13,12 @@ import time
app = Flask(__name__)
app_host = "None"
app_port = "None"
scrape = None
scr = None
def setup():
# sanity check: make sure config is set
# required to make `flask --app lewy run --debug` work
global config, app_host, app_port, scrape
global config, app_host, app_port, scr
try:
if not config['general']:
lewy_globals.setConfig(lewy_globals.configfile)
@@ -79,7 +79,7 @@ def setup():
app.add_url_rule('/api/<path:received_request>', view_func=lewy_api.api_global_catchall)
db = lewy_globals.setupDb(app, config)
scraper = scr()
scr = scraper()
with app.app_context():
db.create_all()
@@ -97,8 +97,7 @@ def every5seconds():
def every2hours():
# zaktualizuj bazę danych scrapując FS
# ...
# scraper.aktualizuj_dane()
scr.aktualizuj_dane()
return
@app.route('/<string:val>', methods=['GET'])

View File

@@ -50,6 +50,19 @@ def not_implemented(data):
# TODO: change list to string -> data, not data[0]
return 501, f"not recognised/implemented: {data[0]}", []
def __czy_x_istnieje(typ, **id):
rekord = getDb().simple_select_all(typ, **id)
if rekord is not None and rekord != []:
return True
else:
return False
def czy_sportowiec_istnieje(id_zawodnika: str):
return __czy_x_istnieje("sportowcy", id_zawodnika=id_zawodnika)
def czy_klub_istnieje(id_klubu: str):
return __czy_x_istnieje("kluby", id_klubu=id_klubu)
# GET /api/v1
def stub_hello():
"""
@@ -85,15 +98,152 @@ def stats():
return 200, "ok", data_to_send
# GET /api/v1/matches
def get_matches(r):
def get_matches(r = None, id_zawodnika: int | None = None, rok: int | None = None):
"""
TODO: Zwraca mecze.
Zwraca mecze.
Przykład wywołania:
get_matches(r, id_zawodnika=1), tożsame z GET /api/v1/matches?id_zawodnika=1
get_matches(r, rok=2024), tożsame z GET /api/v1/matches?rok=2024
get_matches(r), tożsame z GET /api/v1/matches
"""
response_json = []
mecze = getDb().simple_select_all("mecze")
mecze = None
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(response_json)
# print(f"zwracam mecze: {response_json}")
return 200, "ok", response_json
# GET /api/v1/player_stats
def player_stats(r = None, id_zawodnika: int | None = None):
"""
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
"""
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', 0)
# Sprawdź, czy sportowiec o podanym (lub niepodanym) id istnieje.
if 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 statystyki.
else:
staty = getDb().get_basic_stats(id_zawodnika=id_zawodnika)
# for stat in staty:
response_json.append({
'unique_items': staty[0],
'time_played': staty[1],
'goals': staty[2],
'assists': staty[3],
'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}")
return 200, "ok", response_json
# GET /api/v1/robert_stats
def robert_stats(r = None, id_klubu: str | None = None):
"""
Zwraca statystyki Roberta w danym klubie.
Przykład wywołania:
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', "non-existent-club-id")
# 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 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],
'goals': staty[2],
'assists': staty[3],
'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...
@@ -148,6 +298,12 @@ 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 'clubs':
return clubs(r = request)
case _:
increment_bad_requests()
return not_implemented(data)
return not_implemented(data)

View File

@@ -1,7 +1,7 @@
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
from functools import wraps
from sqlalchemy import ForeignKey, select, insert, update
from sqlalchemy import ForeignKey, select, insert, update, extract, func, case
from sqlalchemy.orm import Mapped, mapped_column, DeclarativeBase, Session, relationship
from typing import List
import time
@@ -95,7 +95,7 @@ class baza():
id_zawodnika: Mapped[ int] = mapped_column(ForeignKey(f"{tnp}sportowcy.id_zawodnika"))
zawodnik: Mapped[ "sportowcy"] = relationship(back_populates="mecze_zawodnika")
zewnetrzne_id_meczu: Mapped[ str] = mapped_column(ForeignKey(f"{tnp}mecze.zewnetrzne_id_meczu"))
mecz: Mapped[ "mecze"] = relationship()
mecz: Mapped[ "mecze"] = relationship() # back_populates="zawodnicy_w_meczu", foreign_keys=[zewnetrzne_id_meczu])
czas_gry: Mapped[ int] = mapped_column()
goli: Mapped[ int] = mapped_column()
asyst: Mapped[ int] = mapped_column()
@@ -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}>"
@@ -143,6 +145,13 @@ class baza():
def __repr__(self):
return f"<Klub #{self.id_klubu} ({self.skrocona_nazwa})>"
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)
@@ -159,6 +168,8 @@ class baza():
skrocona_nazwa_turnieju: Mapped[ str] = mapped_column()
flaga: Mapped[ int] = mapped_column()
# zawodnicy_w_meczu: Mapped[ List["sportowcy_w_meczach"]] = relationship(back_populates="mecz")
def __repr__(self):
return f"<Mecz #{self.id_meczu} ({self.zewnetrzne_id_meczu}, {self.gospodarze.skrocona_nazwa} vs. {self.goscie.skrocona_nazwa})>"
@@ -169,8 +180,10 @@ class baza():
"data": self.data.strftime("%Y-%m-%d"),
"gospodarze_id": self.gospodarze_id,
"gospodarze": self.gospodarze.skrocona_nazwa,
"gospodarze_pelna_nazwa": self.gospodarze.pelna_nazwa,
"goscie_id": self.goscie_id,
"goscie": self.goscie.skrocona_nazwa,
"goscie_pelna_nazwa": self.goscie.pelna_nazwa,
"gosp_wynik": self.gosp_wynik,
"gosc_wynik": self.gosc_wynik,
"sezon": self.sezon,
@@ -197,12 +210,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:"
@@ -494,21 +507,188 @@ class baza():
if zewnetrzne_id_zawodnika is not None:
id_zawodnika = self.get_id_zawodnika_by_zewnetrzne_id(zewnetrzne_id_zawodnika)
# Aliasy (dla czytelności)
SportowcyWMeczach = self.entities["sportowcy_w_meczach"]
Sportowcy = self.entities["sportowcy"]
query = self.session.query(
self.entities["sportowcy_w_meczach"]
SportowcyWMeczach
).join(
self.entities["sportowcy_w_meczach"].zawodnik
SportowcyWMeczach.zawodnik
).filter(
self.entities["sportowcy"].id_zawodnika == id_zawodnika
Sportowcy.id_zawodnika == id_zawodnika
)
#print(query)
# print(f"get_sportowcy_w_meczach_by_sportsman_id: {query}")
if order.lower() == "desc":
query = query.order_by(self.entities["sportowcy_w_meczach"].id_rekordu.desc())
query = query.order_by(SportowcyWMeczach.id_rekordu.desc())
return query.all()
@exit_gracefully
def get_sportsman_matches(self, id_zawodnika = None, zewnetrzne_id_zawodnika = None, order = "DESC", year = 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)
# Aliasy
Mecze = self.entities["mecze"]
SportowcyWMeczach = self.entities["sportowcy_w_meczach"]
Sportowcy = self.entities["sportowcy"]
query = self.session.query(
Mecze
).join(
SportowcyWMeczach, Mecze.zewnetrzne_id_meczu == SportowcyWMeczach.zewnetrzne_id_meczu
)
if id_zawodnika is not None:
query = query.join(
Sportowcy, SportowcyWMeczach.id_zawodnika == Sportowcy.id_zawodnika
).filter(
Sportowcy.id_zawodnika == id_zawodnika
)
if year is not None:
query = query.filter(
extract("year", Mecze.data) == year
)
if order.lower() == "desc":
query = query.order_by(Mecze.data.desc())
# print(f"get_sportsman_matches: {query}")
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"]
# 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'),
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'),
# 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(
SportowcyWMeczach.id_zawodnika == id_zawodnika
)
return query.all()[0]
@exit_gracefully
def get_sportsman_club_stats(self, id_zawodnika = None, zewnetrzne_id_zawodnika = None, id_klubu = 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 []
if id_klubu is None:
return self.get_basic_stats(id_zawodnika=id_zawodnika)
else:
if self.simple_select_all("kluby", id_klubu=id_klubu) == []:
return []
# 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'),
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'),
# 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(
SportowcyWMeczach.id_zawodnika == id_zawodnika
).where(
SportowcyWMeczach.klub_id == id_klubu
)
return query.all()[0]
@exit_gracefully
def sample_data_init(self, override_safety_check=False):
"""

View File

@@ -23,9 +23,9 @@ def safeTraverse(obj: dict, path: list, default=None):
try:
for x in path:
result = result[x]
except KeyError:
except (KeyError, TypeError):
result = default
# print(f"error reading: {' -> '.join(path)} - returning: {default}")
print(f"error reading: {' -> '.join(path)} - returning: {default}")
finally:
return result

View File

@@ -3,39 +3,50 @@ import lewy_api_v1
import lewy_db
import lewy_globals
import json
from lewy_api_v1 import get_matches, player_stats, robert_stats, clubs as get_clubs
def get_lewy_stats():
return {
'all_time_stats': {
'goals': 589+85,
'assists':154+35,
'matches': 791+158,
},
'club_stats': {
'goals': 589,
'assists': 154,
'matches': 791,
},
'nation_stats': {
'goals': 85,
'assists': 35,
'matches': 158,
},
'international_cups': {
'goals': 110,
'assists': 19,
'matches': 152,
},
'national_cups': {
'goals': 58,
'assists': 4,
'matches': 74,
},
'cards': {
'yellow': 86,
'red': 2,
}
}
stats = player_stats(id_zawodnika=1)[2][0]
polska = robert_stats(id_klubu="polska")[2][0]
barcelona = robert_stats(id_klubu="barcelona")[2][0]
borussia = robert_stats(id_klubu="dortmund")[2][0]
bayern = robert_stats(id_klubu="bayern")[2][0]
und = robert_stats(id_klubu="undefined")[2][0]
return {
'all_time_stats': {
'goals': stats["goals"], # 589+85
'assists': stats["assists"], # 154+35
'matches': stats["unique_items"] # 791+158
},
'club_stats': {
'goals': barcelona["goals"] + borussia["goals"] + bayern["goals"]+ und["goals"], # 589
'assists': barcelona["assists"] + borussia["assists"] + bayern["assists"]+ und["assists"], # 154
'matches': barcelona["unique_items"] + borussia["unique_items"] + bayern["unique_items"]+ und["unique_items"] # 791 # to trochę na wyrost, bo w części meczy był kontuzjowany
},
'nation_stats': {
'goals': polska["goals"], # 85
'assists': polska["assists"], # 35
'matches': polska["unique_items"] # 158
},
'international_cups': {
'goals': 110,
'assists': 19,
'matches': 152,
},
'national_cups': {
'goals': 58,
'assists': 4,
'matches': 74,
},
'cards': {
'yellow': stats["yellow_cards"], # 86
'red': stats["red_cards"], # 2
},
'wins_losses': {
'wins': stats["wins"],
'draws': stats["draws"],
'losses': stats["losses"]
}
}
def index():
dark_mode = request.cookies.get('darkMode', 'disabled')
@@ -60,9 +71,13 @@ def index():
def mecze():
# Możesz dostarczyć szczegóły dotyczące meczów
selected_date = request.args.get("date", '2025')
with open("static/lewandowski_matches.json", "r") as file:
data = json.load(file)
matches = data["data"]
try:
selected_date = int(selected_date)
except:
selected_date = 2025
#with open("static/lewandowski_matches.json", "r") as file:
# data = json.load(file)
status, msg, matches = get_matches(None, id_zawodnika=1, rok=selected_date)
return render_template('matches.html', matches=matches, selected_date=selected_date)
@@ -71,28 +86,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()

View File

@@ -386,6 +386,34 @@ header button {
display: none;
}
}
@media (max-width: 600px){
.section__matches
{
font-size: 10px;
}
.section__matches th{
padding: 3px;
}
.club-stats-grid
{
grid-template-columns: 1fr 1fr !important;
}
.club-stats-grid .stat-box
{
width: 100%;
}
.section-stats-center .section-stats .stats
{
display: flex;
flex-direction: column;
align-items: center;
}
.section-stats-center .section-stats .stats .stat-box
{
width: 100%;
padding: 0;
}
}
@@ -878,4 +906,32 @@ select
background-color: var(--barca-blue);
border-radius: 10px;
border: 2px solid white;
}
@media (max-width: 600px){
.sectionmatches
{
font-size: 10px;
}
.sectionmatches th{
padding: 3px;
}
.club-stats-grid
{
grid-template-columns: 1fr 1fr !important;
}
.club-stats-grid .stat-box
{
width: 100%;
}
.section-stats-center .section-stats .stats
{
display: flex;
flex-direction: column;
align-items: center;
}
.section-stats-center .section-stats .stats .stat-box
{
width: 100%;
padding: 0;
}
}

View File

@@ -4,59 +4,59 @@
{% block content %}
<section class="choose-club">
<a href="{{ url_for('clubs', club='FC Barcelona') }}">
<a href="{{ url_for('clubs', club='barcelona') }}">
<button><img src="{{ url_for('static', filename='FC_Barcelona.png') }}"></button>
</a>
<a href="{{ url_for('clubs', club='Bayern Monachium') }}">
<a href="{{ url_for('clubs', club='bayern') }}">
<button><img src="{{ url_for('static', filename='FC_Bayern.png') }}"></button>
</a>
<a href="{{ url_for('clubs', club='Borussia Dortmund') }}">
<a href="{{ url_for('clubs', club='dortmund') }}">
<button><img src="{{ url_for('static', filename='Borussia_Dortmund.png') }}"></button>
</a>
<!--Jak nie będzie statysytk dla lecha to usunać-->
<a href="{{ url_for('clubs', club='Lech Poznan') }}">
<!-- <a href="{{ url_for('clubs', club='Lech Poznan') }}">
<button><img src="{{ url_for('static', filename='Lech_Poznan.png') }}"></button>
</a>
</a> -->
</section>
<!-- Wyświetlanie danych tylko dla wybranego klubu -->
{% for stats in clubs %}
{% if stats.club == selected_club %}
{#{% for stats in clubs %}#}
{#{% if stats.club == selected_club %}#}
<section class="club-stats">
<h2>Statystyki dla {{selected_club}}</h2>
<div class="wybrany{{selected_club}}"></div>
<h2>Statystyki dla {{resp_json.club}}</h2>
<div class="wybrany{{resp_json.club}}"></div>
<div class="club-stats-grid">
<div class="stat-box">
<p>Gole:</p> <span class="stat-box-special"> {{ stats.goals }} </span>
<p>Gole:</p> <span class="stat-box-special"> {{ resp_json.goals }} </span>
</div>
<div class="stat-box">
<p>Asysty:</p> <span class="stat-box-special"> {{ stats.assist }} </span>
<p>Asysty:</p> <span class="stat-box-special"> {{ resp_json.assist }} </span>
</div>
<div class="stat-box">
<p>Występy:</p> <span class="stat-box-special"> {{ stats.matches }} </span>
<p>Występy:</p> <span class="stat-box-special"> {{ resp_json.matches }} </span>
</div>
<div class="stat-box">
<p>Łączny czas gry:</p> <span class="stat-box-special"> {{ stats.minutes_played }}</span>
<p>Łączny czas gry:</p> <span class="stat-box-special"> {{ resp_json.minutes_played }}</span>
</div>
<div class="stat-box">
<p>Żółte kartki:</p> <span class="stat-box-special"> {{ stats.yellow_card }}</span>
<p>Żółte kartki:</p> <span class="stat-box-special"> {{ resp_json.yellow_card }}</span>
</div>
<div class="stat-box">
<p>Czerwone kartki:</p> <span class="stat-box-special"> {{ stats.red_card }}</span>
<p>Czerwone kartki:</p> <span class="stat-box-special"> {{ resp_json.red_card }}</span>
</div>
<div class="stat-box">
<p>Zwycięstwa:</p> <span class="stat-box-special"> {{ stats.wins }}</span>
<p>Zwycięstwa:</p> <span class="stat-box-special"> {{ resp_json.wins }}</span>
</div>
<div class="stat-box">
<p>Remisy:</p> <span class="stat-box-special"> {{ stats.draws }}</span>
<p>Remisy:</p> <span class="stat-box-special"> {{ resp_json.draws }}</span>
</div>
<div class="stat-box">
<p>Porażki:</p> <span class="stat-box-special"> {{ stats.lost }}</span>
<p>Porażki:</p> <span class="stat-box-special"> {{ resp_json.lost }}</span>
</div>
</div>
</section>
{% endif %}
{% endfor %}
{#{% endif %}#}
{#{% endfor %}#}
{% endblock %}
{% block footer %}

View File

@@ -51,7 +51,7 @@
</div>
<div class="stat-box">
<h3>{{ player.assists}}</h3>
<h3>{{ player.matches}}</h3>
</div>
</div>

View File

@@ -36,20 +36,18 @@
<th></th>
</tr>
{% for match in matches %}
{% if match.data[:4] == selected_date %}
<tr>
<td>{{ match.data }}</td>
<td>{{ match.gospodarze_id }}</td>
<td>{{ match.gospodarze_pelna_nazwa }}</td>
<td>{{ match.gosp_wynik }} : {{ match.gosc_wynik }}</td>
<td>{{ match.goscie_id }}</td>
<td>{{ match.goscie_pelna_nazwa }}</td>
<!--
<td>{{ match.goals }}</td>
<td>{{ match.assists }}</td>
<td>{{ match.minutes }}</td>
-->
</tr>
{% endif %}
{% endfor %}
</table>
</section>

View File

@@ -11,7 +11,7 @@
<p>Gole:</p> <span class="stat-box-special"> {{ nation_stats.goals }} </span>
</div>
<div class="stat-box">
<p>Asysty:</p> <span class="stat-box-special"> {{ nation_stats.assists }} </span>
<p>Asysty:</p> <span class="stat-box-special"> {{ nation_stats.assist }} </span>
</div>
<div class="stat-box">
<p>Występy:</p> <span class="stat-box-special"> {{ nation_stats.matches }} </span>

View File

@@ -55,8 +55,9 @@
<p>Występy</p>
</div>
</section>
<!--
<section class="section-stats">
<h2>Puchary międzynarodowe</h2>
<h2>(!) Puchary międzynarodowe</h2>
<div class="stats">
<div class="stat-box">
<h3>{{ international_cups.goals }}</h3>
@@ -73,7 +74,7 @@
</div>
</section>
<section class="section-stats">
<h2>Puchary krajowe</h2>
<h2>(!) Puchary krajowe</h2>
<div class="stats">
<div class="stat-box">
<h3>{{ national_cups.goals }}</h3>
@@ -89,6 +90,7 @@
</div>
</div>
</section>
-->
<section class="section-stats">
<h2>Kartki</h2>
<div class="stats">
@@ -103,4 +105,21 @@
</div>
</div>
</section>
<section class="section-stats">
<h2>Wygrane, remisy i przegrane</h2>
<div class="stats">
<div class="stat-box">
<h3>{{ wins_losses.wins }}</h3>
<p>Wygrane</p>
</div>
<div class="stat-box">
<h3>{{ wins_losses.draws }}</h3>
<p>Remisy</p>
</div>
<div class="stat-box">
<h3>{{ wins_losses.losses }}</h3>
<p>Przegrane</p>
</div>
</div>
</section>
{% endblock %}