Compare commits
12 Commits
ScraperV2
...
7b457475b4
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b457475b4 | |||
| 8fb2a22c2a | |||
| d1f5f8f3f4 | |||
| 56e68ed751 | |||
| f96a3ed1f1 | |||
| 416b2ccfe0 | |||
| 00bbe05b1c | |||
| e373c6b274 | |||
| e80ee6bf8f | |||
| a25be482b0 | |||
| 4e8cb48c82 | |||
| bc82fcd6b8 |
@@ -1,23 +1,13 @@
|
|||||||
from flask import session
|
from flask import session
|
||||||
from lewy_db import baza as ldb
|
from lewy_db import baza as ldb
|
||||||
from lewy_globals import colors as c
|
from lewy_globals import colors as c
|
||||||
|
from lewy_globals import safeTraverse as safe_traverse
|
||||||
import json
|
import json
|
||||||
import lewy_globals
|
import lewy_globals
|
||||||
import requests
|
import requests
|
||||||
import time
|
import time
|
||||||
from sqlalchemy import func
|
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:
|
class scraper:
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from flask import Flask, Response, render_template
|
from flask import Flask, Response, render_template
|
||||||
from flask_apscheduler import APScheduler
|
from flask_apscheduler import APScheduler
|
||||||
from fs_scraper import scraper as scr
|
from fs_scraper import scraper
|
||||||
from lewy_globals import colors as c
|
from lewy_globals import colors as c
|
||||||
import lewy_api
|
import lewy_api
|
||||||
import lewy_db
|
import lewy_db
|
||||||
@@ -13,7 +13,7 @@ import time
|
|||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app_host = "None"
|
app_host = "None"
|
||||||
app_port = "None"
|
app_port = "None"
|
||||||
scrape = None
|
scr = None
|
||||||
|
|
||||||
def setup():
|
def setup():
|
||||||
# sanity check: make sure config is set
|
# sanity check: make sure config is set
|
||||||
@@ -79,7 +79,7 @@ def setup():
|
|||||||
app.add_url_rule('/api/<path:received_request>', view_func=lewy_api.api_global_catchall)
|
app.add_url_rule('/api/<path:received_request>', view_func=lewy_api.api_global_catchall)
|
||||||
|
|
||||||
db = lewy_globals.setupDb(app, config)
|
db = lewy_globals.setupDb(app, config)
|
||||||
scraper = scr()
|
scr = scraper()
|
||||||
|
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
db.create_all()
|
db.create_all()
|
||||||
@@ -97,8 +97,7 @@ def every5seconds():
|
|||||||
|
|
||||||
def every2hours():
|
def every2hours():
|
||||||
# zaktualizuj bazę danych scrapując FS
|
# zaktualizuj bazę danych scrapując FS
|
||||||
# ...
|
scr.aktualizuj_dane()
|
||||||
# scraper.aktualizuj_dane()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@app.route('/<string:val>', methods=['GET'])
|
@app.route('/<string:val>', methods=['GET'])
|
||||||
|
|||||||
@@ -50,6 +50,16 @@ def not_implemented(data):
|
|||||||
# TODO: change list to string -> data, not data[0]
|
# TODO: change list to string -> data, not data[0]
|
||||||
return 501, f"not recognised/implemented: {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)
|
||||||
|
|
||||||
# GET /api/v1
|
# GET /api/v1
|
||||||
def stub_hello():
|
def stub_hello():
|
||||||
"""
|
"""
|
||||||
@@ -85,15 +95,42 @@ def stats():
|
|||||||
return 200, "ok", data_to_send
|
return 200, "ok", data_to_send
|
||||||
|
|
||||||
# GET /api/v1/matches
|
# GET /api/v1/matches
|
||||||
def get_matches(r):
|
def get_matches(r = None, id_zawodnika: str | 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 = []
|
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:
|
for mecz in mecze:
|
||||||
response_json.append(mecz.jsonify())
|
response_json.append(mecz.jsonify())
|
||||||
print(response_json)
|
# print(f"zwracam mecze: {response_json}")
|
||||||
return 200, "ok", response_json
|
return 200, "ok", response_json
|
||||||
|
|
||||||
# GET /api/v1/debugger_halt?token=XXX...
|
# GET /api/v1/debugger_halt?token=XXX...
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from sqlalchemy import ForeignKey, select, insert, update
|
from sqlalchemy import ForeignKey, select, insert, update, extract
|
||||||
from sqlalchemy.orm import Mapped, mapped_column, DeclarativeBase, Session, relationship
|
from sqlalchemy.orm import Mapped, mapped_column, DeclarativeBase, Session, relationship
|
||||||
from typing import List
|
from typing import List
|
||||||
import time
|
import time
|
||||||
@@ -95,7 +95,7 @@ class baza():
|
|||||||
id_zawodnika: Mapped[ int] = mapped_column(ForeignKey(f"{tnp}sportowcy.id_zawodnika"))
|
id_zawodnika: Mapped[ int] = mapped_column(ForeignKey(f"{tnp}sportowcy.id_zawodnika"))
|
||||||
zawodnik: Mapped[ "sportowcy"] = relationship(back_populates="mecze_zawodnika")
|
zawodnik: Mapped[ "sportowcy"] = relationship(back_populates="mecze_zawodnika")
|
||||||
zewnetrzne_id_meczu: Mapped[ str] = mapped_column(ForeignKey(f"{tnp}mecze.zewnetrzne_id_meczu"))
|
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()
|
czas_gry: Mapped[ int] = mapped_column()
|
||||||
goli: Mapped[ int] = mapped_column()
|
goli: Mapped[ int] = mapped_column()
|
||||||
asyst: Mapped[ int] = mapped_column()
|
asyst: Mapped[ int] = mapped_column()
|
||||||
@@ -159,6 +159,8 @@ class baza():
|
|||||||
skrocona_nazwa_turnieju: Mapped[ str] = mapped_column()
|
skrocona_nazwa_turnieju: Mapped[ str] = mapped_column()
|
||||||
flaga: Mapped[ int] = mapped_column()
|
flaga: Mapped[ int] = mapped_column()
|
||||||
|
|
||||||
|
# zawodnicy_w_meczu: Mapped[ List["sportowcy_w_meczach"]] = relationship(back_populates="mecz")
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<Mecz #{self.id_meczu} ({self.zewnetrzne_id_meczu}, {self.gospodarze.skrocona_nazwa} vs. {self.goscie.skrocona_nazwa})>"
|
return f"<Mecz #{self.id_meczu} ({self.zewnetrzne_id_meczu}, {self.gospodarze.skrocona_nazwa} vs. {self.goscie.skrocona_nazwa})>"
|
||||||
|
|
||||||
@@ -169,8 +171,10 @@ class baza():
|
|||||||
"data": self.data.strftime("%Y-%m-%d"),
|
"data": self.data.strftime("%Y-%m-%d"),
|
||||||
"gospodarze_id": self.gospodarze_id,
|
"gospodarze_id": self.gospodarze_id,
|
||||||
"gospodarze": self.gospodarze.skrocona_nazwa,
|
"gospodarze": self.gospodarze.skrocona_nazwa,
|
||||||
|
"gospodarze_pelna_nazwa": self.gospodarze.pelna_nazwa,
|
||||||
"goscie_id": self.goscie_id,
|
"goscie_id": self.goscie_id,
|
||||||
"goscie": self.goscie.skrocona_nazwa,
|
"goscie": self.goscie.skrocona_nazwa,
|
||||||
|
"goscie_pelna_nazwa": self.goscie.pelna_nazwa,
|
||||||
"gosp_wynik": self.gosp_wynik,
|
"gosp_wynik": self.gosp_wynik,
|
||||||
"gosc_wynik": self.gosc_wynik,
|
"gosc_wynik": self.gosc_wynik,
|
||||||
"sezon": self.sezon,
|
"sezon": self.sezon,
|
||||||
@@ -494,18 +498,58 @@ class baza():
|
|||||||
if zewnetrzne_id_zawodnika is not None:
|
if zewnetrzne_id_zawodnika is not None:
|
||||||
id_zawodnika = self.get_id_zawodnika_by_zewnetrzne_id(zewnetrzne_id_zawodnika)
|
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(
|
query = self.session.query(
|
||||||
self.entities["sportowcy_w_meczach"]
|
SportowcyWMeczach
|
||||||
).join(
|
).join(
|
||||||
self.entities["sportowcy_w_meczach"].zawodnik
|
SportowcyWMeczach.zawodnik
|
||||||
).filter(
|
).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":
|
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()
|
return query.all()
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ def safeTraverse(obj: dict, path: list, default=None):
|
|||||||
try:
|
try:
|
||||||
for x in path:
|
for x in path:
|
||||||
result = result[x]
|
result = result[x]
|
||||||
except KeyError:
|
except (KeyError, TypeError):
|
||||||
result = default
|
result = default
|
||||||
# print(f"error reading: {' -> '.join(path)} - returning: {default}")
|
print(f"error reading: {' -> '.join(path)} - returning: {default}")
|
||||||
finally:
|
finally:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import lewy_api_v1
|
|||||||
import lewy_db
|
import lewy_db
|
||||||
import lewy_globals
|
import lewy_globals
|
||||||
import json
|
import json
|
||||||
|
from lewy_api_v1 import get_matches
|
||||||
def get_lewy_stats():
|
def get_lewy_stats():
|
||||||
return {
|
return {
|
||||||
'all_time_stats': {
|
'all_time_stats': {
|
||||||
@@ -60,9 +60,13 @@ def index():
|
|||||||
def mecze():
|
def mecze():
|
||||||
# Możesz dostarczyć szczegóły dotyczące meczów
|
# Możesz dostarczyć szczegóły dotyczące meczów
|
||||||
selected_date = request.args.get("date", '2025')
|
selected_date = request.args.get("date", '2025')
|
||||||
with open("static/lewandowski_matches.json", "r") as file:
|
try:
|
||||||
data = json.load(file)
|
selected_date = int(selected_date)
|
||||||
matches = data["data"]
|
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)
|
return render_template('matches.html', matches=matches, selected_date=selected_date)
|
||||||
|
|
||||||
|
|||||||
@@ -386,6 +386,34 @@ header button {
|
|||||||
display: none;
|
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);
|
background-color: var(--barca-blue);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 2px solid white;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-box">
|
<div class="stat-box">
|
||||||
<h3>{{ player.assists}}</h3>
|
<h3>{{ player.matches}}</h3>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -36,20 +36,18 @@
|
|||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
{% for match in matches %}
|
{% for match in matches %}
|
||||||
{% if match.data[:4] == selected_date %}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ match.data }}</td>
|
<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.gosp_wynik }} : {{ match.gosc_wynik }}</td>
|
||||||
<td>{{ match.goscie_id }}</td>
|
<td>{{ match.goscie_pelna_nazwa }}</td>
|
||||||
<!--
|
<!--
|
||||||
<td>{{ match.goals }}</td>
|
<td>{{ match.goals }}</td>
|
||||||
<td>{{ match.assists }}</td>
|
<td>{{ match.assists }}</td>
|
||||||
<td>{{ match.minutes }}</td>
|
<td>{{ match.minutes }}</td>
|
||||||
-->
|
-->
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user