WebApp
This commit is contained in:
parent
c9b4ee7af6
commit
844967f578
4 changed files with 501 additions and 7 deletions
303
6aus49APP/app.py
Normal file
303
6aus49APP/app.py
Normal file
|
|
@ -0,0 +1,303 @@
|
||||||
|
# app.py
|
||||||
|
import os
|
||||||
|
from datetime import date
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
|
from fastapi import FastAPI, Query, Request, HTTPException
|
||||||
|
from fastapi.responses import HTMLResponse
|
||||||
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
from fastapi.templating import Jinja2Templates
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from sqlalchemy import create_engine, text
|
||||||
|
from sqlalchemy.engine import Engine
|
||||||
|
from sqlalchemy.pool import NullPool
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
# 0) Konfiguration laden
|
||||||
|
# ------------------------------------------------------
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
DATABASE_URL = os.getenv("DATABASE_URL")
|
||||||
|
if not DATABASE_URL:
|
||||||
|
raise RuntimeError("DATABASE_URL nicht gesetzt (.env prüfen)")
|
||||||
|
|
||||||
|
PAGE_SIZE = int(os.getenv("PAGE_SIZE", "10")) # Standardlimit
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
# 1) App & DB initialisieren
|
||||||
|
# ------------------------------------------------------
|
||||||
|
engine: Engine = create_engine(DATABASE_URL, poolclass=NullPool, future=True)
|
||||||
|
|
||||||
|
app = FastAPI(title="Lotto-Auswertung (6aus49 / Eurojackpot)")
|
||||||
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||||
|
templates = Jinja2Templates(directory="templates")
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
# 2) Pydantic-Schemas
|
||||||
|
# ------------------------------------------------------
|
||||||
|
class Draw(BaseModel):
|
||||||
|
datum: date
|
||||||
|
# gemeinsame Felder; bei Euro bleiben z6/sz/super6/spiel77 leer
|
||||||
|
z1: int; z2: int; z3: int; z4: int; z5: int
|
||||||
|
z6: Optional[int] = None
|
||||||
|
sz: Optional[int] = None
|
||||||
|
sz1: Optional[int] = None
|
||||||
|
sz2: Optional[int] = None
|
||||||
|
super6: Optional[str] = None
|
||||||
|
spiel77: Optional[str] = None
|
||||||
|
|
||||||
|
class DrawList(BaseModel):
|
||||||
|
total: int
|
||||||
|
items: List[Draw]
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
# 3) Datumsparser (Template – Tabellename variabel)
|
||||||
|
# ------------------------------------------------------
|
||||||
|
DATE_EXPR_TMPL = (
|
||||||
|
"COALESCE("
|
||||||
|
" (CASE WHEN {tbl}.datum REGEXP '^[0-9]{{4}}-[0-9]{{2}}-[0-9]{{2}}$' THEN DATE({tbl}.datum) END),"
|
||||||
|
" STR_TO_DATE({tbl}.datum, '%d.%m.%Y'),"
|
||||||
|
" STR_TO_DATE({tbl}.datum, '%d.%m.%y'),"
|
||||||
|
" STR_TO_DATE(TRIM(SUBSTRING_INDEX({tbl}.datum, '/', -1)), '%d.%m.%Y'),"
|
||||||
|
" STR_TO_DATE(TRIM(SUBSTRING_INDEX({tbl}.datum, '/', -1)), '%d.%m.%y')"
|
||||||
|
")"
|
||||||
|
)
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
# 4) Helferfunktionen
|
||||||
|
# ------------------------------------------------------
|
||||||
|
def _normalize_game(s: str) -> str:
|
||||||
|
return "euro" if (s or "").lower() == "euro" else "6aus49"
|
||||||
|
|
||||||
|
def _to_date(s: Optional[str]):
|
||||||
|
if not s or s.strip() == "":
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return date.fromisoformat(s.strip())
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _rewrite_where_for_t_simple(where_parts):
|
||||||
|
if not where_parts:
|
||||||
|
return ""
|
||||||
|
return " WHERE " + " AND ".join(where_parts)
|
||||||
|
|
||||||
|
def _build_base_select(game: str) -> dict:
|
||||||
|
"""
|
||||||
|
Konfiguriert Spalten & Layout je nach Spiel.
|
||||||
|
Liefert:
|
||||||
|
- tbl: Tabellenname (mit Backticks)
|
||||||
|
- dx: Datumsausdruck
|
||||||
|
- base_select: Subquery-SELECT (liefert t.*)
|
||||||
|
- headers: Tabellenkopf (HTML)
|
||||||
|
- row_tpl: Zeilen-Template (HTML)
|
||||||
|
- link_prefix: Pfadpräfix für Detail-Link
|
||||||
|
"""
|
||||||
|
if game == "euro":
|
||||||
|
tbl = "`euro`"
|
||||||
|
dx = DATE_EXPR_TMPL.format(tbl=tbl)
|
||||||
|
base_select = """
|
||||||
|
SELECT
|
||||||
|
{dx} AS datum,
|
||||||
|
z1, z2, z3, z4, z5,
|
||||||
|
sz1, sz2
|
||||||
|
FROM {tbl}
|
||||||
|
""".format(dx=dx, tbl=tbl)
|
||||||
|
# 👇 Hier neue Spaltennamen
|
||||||
|
headers = "<tr><th>Datum</th><th>Zahlen (5)</th><th>Super 1</th><th>Super 2</th></tr>"
|
||||||
|
row_tpl = (
|
||||||
|
'<tr>'
|
||||||
|
'<td class="nowrap"><a href="{link}/{datum}" target="_blank">{datum}</a></td>'
|
||||||
|
'<td class="numbers">'
|
||||||
|
'<span class="badge">{z1}</span> <span class="badge">{z2}</span> <span class="badge">{z3}</span> '
|
||||||
|
'<span class="badge">{z4}</span> <span class="badge">{z5}</span>'
|
||||||
|
'</td>'
|
||||||
|
'<td class="nowrap"><strong>{sz1}</strong></td>'
|
||||||
|
'<td class="nowrap"><strong>{sz2}</strong></td>'
|
||||||
|
'</tr>'
|
||||||
|
)
|
||||||
|
link_prefix = "/api/draw/euro"
|
||||||
|
else:
|
||||||
|
tbl = "`6aus49`"
|
||||||
|
dx = DATE_EXPR_TMPL.format(tbl=tbl)
|
||||||
|
# super6/spiel77 als CHAR casten → Pydantic erwartet str
|
||||||
|
base_select = """
|
||||||
|
SELECT
|
||||||
|
{dx} AS datum,
|
||||||
|
z1, z2, z3, z4, z5, z6,
|
||||||
|
sz,
|
||||||
|
CAST(super6 AS CHAR) AS super6,
|
||||||
|
CAST(spiel77 AS CHAR) AS spiel77
|
||||||
|
FROM {tbl}
|
||||||
|
""".format(dx=dx, tbl=tbl)
|
||||||
|
headers = "<tr><th>Datum</th><th>Zahlen (6)</th><th>Superzahl</th><th>Super 6</th><th>Spiel 77</th></tr>"
|
||||||
|
row_tpl = (
|
||||||
|
'<tr>'
|
||||||
|
'<td class="nowrap"><a href="{link}/{datum}" target="_blank">{datum}</a></td>'
|
||||||
|
'<td class="numbers">'
|
||||||
|
'<span class="badge">{z1}</span> <span class="badge">{z2}</span> <span class="badge">{z3}</span> '
|
||||||
|
'<span class="badge">{z4}</span> <span class="badge">{z5}</span> <span class="badge">{z6}</span>'
|
||||||
|
'</td>'
|
||||||
|
'<td class="nowrap"><strong>{sz}</strong></td>'
|
||||||
|
'<td class="nowrap">{super6}</td>'
|
||||||
|
'<td class="nowrap">{spiel77}</td>'
|
||||||
|
'</tr>'
|
||||||
|
)
|
||||||
|
link_prefix = "/api/draw/6aus49"
|
||||||
|
return {
|
||||||
|
"tbl": tbl,
|
||||||
|
"dx": dx,
|
||||||
|
"base_select": base_select,
|
||||||
|
"headers": headers,
|
||||||
|
"row_tpl": row_tpl,
|
||||||
|
"link_prefix": link_prefix,
|
||||||
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
# 5) Startseite
|
||||||
|
# ------------------------------------------------------
|
||||||
|
@app.get("/", response_class=HTMLResponse)
|
||||||
|
async def index(request: Request):
|
||||||
|
return templates.TemplateResponse("index.html", {"request": request, "page_size": PAGE_SIZE})
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
# 6) Gemeinsamer HTML-Endpoint (HTMX)
|
||||||
|
# ------------------------------------------------------
|
||||||
|
@app.get("/ui/draws", response_class=HTMLResponse)
|
||||||
|
async def ui_draws(
|
||||||
|
request: Request,
|
||||||
|
game: str = Query("6aus49"),
|
||||||
|
date_from: Optional[str] = Query(None),
|
||||||
|
date_to: Optional[str] = Query(None),
|
||||||
|
limit: int = Query(10, ge=1, le=500),
|
||||||
|
offset: int = Query(0, ge=0),
|
||||||
|
order: str = Query("desc", pattern="^(asc|desc)$"),
|
||||||
|
):
|
||||||
|
game = _normalize_game(game)
|
||||||
|
cfg = _build_base_select(game)
|
||||||
|
|
||||||
|
d_from = _to_date(date_from)
|
||||||
|
d_to = _to_date(date_to)
|
||||||
|
|
||||||
|
where_parts = []
|
||||||
|
params = {}
|
||||||
|
if d_from:
|
||||||
|
where_parts.append("t.datum >= :date_from")
|
||||||
|
params["date_from"] = d_from
|
||||||
|
if d_to:
|
||||||
|
where_parts.append("t.datum <= :date_to")
|
||||||
|
params["date_to"] = d_to
|
||||||
|
|
||||||
|
where_sql = _rewrite_where_for_t_simple(where_parts)
|
||||||
|
if where_sql == "":
|
||||||
|
where_sql = " WHERE 1=1"
|
||||||
|
where_sql = where_sql + " AND t.datum IS NOT NULL"
|
||||||
|
|
||||||
|
order_sql = " ORDER BY t.datum DESC" if order.lower() == "desc" else " ORDER BY t.datum ASC"
|
||||||
|
|
||||||
|
count_sql = """
|
||||||
|
SELECT COUNT(*) AS cnt
|
||||||
|
FROM (
|
||||||
|
{base}
|
||||||
|
) AS t
|
||||||
|
{where_sql}
|
||||||
|
""".format(base=cfg["base_select"], where_sql=where_sql)
|
||||||
|
|
||||||
|
data_sql = """
|
||||||
|
SELECT *
|
||||||
|
FROM (
|
||||||
|
{base}
|
||||||
|
) AS t
|
||||||
|
{where_sql}
|
||||||
|
{order_sql}
|
||||||
|
LIMIT :limit OFFSET :offset
|
||||||
|
""".format(base=cfg["base_select"], where_sql=where_sql, order_sql=order_sql)
|
||||||
|
|
||||||
|
with engine.begin() as conn:
|
||||||
|
total = conn.execute(text(count_sql), params).scalar_one()
|
||||||
|
rows = conn.execute(text(data_sql), dict(params, limit=limit, offset=offset)).mappings()
|
||||||
|
|
||||||
|
body_rows = []
|
||||||
|
for r in rows:
|
||||||
|
d = dict(r)
|
||||||
|
d["link"] = cfg["link_prefix"]
|
||||||
|
body_rows.append(cfg["row_tpl"].format(**d))
|
||||||
|
|
||||||
|
html = """
|
||||||
|
<p class="muted">Treffer: {total}</p>
|
||||||
|
<table role="grid">
|
||||||
|
<thead>{headers}</thead>
|
||||||
|
<tbody>{rows}</tbody>
|
||||||
|
</table>
|
||||||
|
""".format(total=total, headers=cfg["headers"], rows="".join(body_rows))
|
||||||
|
|
||||||
|
return HTMLResponse(html)
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
# 7) Detail-Endpoint je Spiel (None-Felder ausblenden)
|
||||||
|
# ------------------------------------------------------
|
||||||
|
@app.get(
|
||||||
|
"/api/draw/{game}/{draw_date}",
|
||||||
|
response_model=Draw,
|
||||||
|
response_model_exclude_none=True
|
||||||
|
)
|
||||||
|
async def get_draw_game(game: str, draw_date: date):
|
||||||
|
game = _normalize_game(game)
|
||||||
|
if game == "euro":
|
||||||
|
dx = DATE_EXPR_TMPL.format(tbl="`euro`")
|
||||||
|
sql = text("""
|
||||||
|
SELECT t.datum,
|
||||||
|
t.z1, t.z2, t.z3, t.z4, t.z5,
|
||||||
|
NULL AS z6,
|
||||||
|
NULL AS sz,
|
||||||
|
t.sz1, t.sz2,
|
||||||
|
NULL AS super6,
|
||||||
|
NULL AS spiel77
|
||||||
|
FROM (
|
||||||
|
SELECT {dx} AS datum, z1, z2, z3, z4, z5, sz1, sz2
|
||||||
|
FROM `euro`
|
||||||
|
) AS t
|
||||||
|
WHERE t.datum = :d AND t.datum IS NOT NULL
|
||||||
|
""".format(dx=dx))
|
||||||
|
else:
|
||||||
|
dx = DATE_EXPR_TMPL.format(tbl="`6aus49`")
|
||||||
|
sql = text("""
|
||||||
|
SELECT t.datum,
|
||||||
|
t.z1, t.z2, t.z3, t.z4, t.z5, t.z6,
|
||||||
|
t.sz,
|
||||||
|
NULL AS sz1, NULL AS sz2,
|
||||||
|
t.super6, t.spiel77
|
||||||
|
FROM (
|
||||||
|
SELECT {dx} AS datum, z1, z2, z3, z4, z5, z6, sz,
|
||||||
|
CAST(super6 AS CHAR) AS super6,
|
||||||
|
CAST(spiel77 AS CHAR) AS spiel77
|
||||||
|
FROM `6aus49`
|
||||||
|
) AS t
|
||||||
|
WHERE t.datum = :d AND t.datum IS NOT NULL
|
||||||
|
""".format(dx=dx))
|
||||||
|
|
||||||
|
with engine.begin() as conn:
|
||||||
|
row = conn.execute(sql, {"d": draw_date}).mappings().first()
|
||||||
|
if not row:
|
||||||
|
raise HTTPException(status_code=404, detail="Ziehung nicht gefunden")
|
||||||
|
return Draw(**row)
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
# 8) Healthcheck
|
||||||
|
# ------------------------------------------------------
|
||||||
|
@app.get("/health")
|
||||||
|
async def health():
|
||||||
|
try:
|
||||||
|
with engine.begin() as conn:
|
||||||
|
conn.execute(text("SELECT 1"))
|
||||||
|
return {"status": "ok"}
|
||||||
|
except Exception as e:
|
||||||
|
return {"status": "error", "message": str(e)}
|
||||||
|
|
||||||
|
# ------------------------------------------------------
|
||||||
|
# 9) Lokaler Start
|
||||||
|
# ------------------------------------------------------
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import uvicorn
|
||||||
|
uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True)
|
||||||
15
6aus49APP/requirements.txt
Normal file
15
6aus49APP/requirements.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
fastapi==0.115.0
|
||||||
|
uvicorn[standard]==0.30.0
|
||||||
|
SQLAlchemy==2.0.34
|
||||||
|
PyMySQL==1.1.1
|
||||||
|
python-dotenv==1.0.1
|
||||||
|
jinja2==3.1.4
|
||||||
|
pydantic==2.9.2
|
||||||
|
fastapi==0.115.0
|
||||||
|
uvicorn[standard]==0.30.0
|
||||||
|
SQLAlchemy==2.0.34
|
||||||
|
psycopg2-binary==2.9.9
|
||||||
|
python-dotenv==1.0.1
|
||||||
|
jinja2==3.1.4
|
||||||
|
pydantic==2.9.2
|
||||||
|
|
||||||
133
6aus49APP/templates/index.html
Normal file
133
6aus49APP/templates/index.html
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Lotto-Ziehungen</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
|
||||||
|
<link rel="icon" href="/static/favicon.ico">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: "Segoe UI", Arial, sans-serif;
|
||||||
|
background: #f6f6f6;
|
||||||
|
color: #222;
|
||||||
|
margin: 0;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
max-width: 960px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
|
||||||
|
padding: 2rem 2.5rem;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
font-size: 1.9rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
}
|
||||||
|
p.service-note {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 0.3rem;
|
||||||
|
margin-bottom: 1.8rem;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
color: #666;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.6rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
label { font-weight: 500; }
|
||||||
|
input, select, button {
|
||||||
|
padding: 0.35rem 0.6rem;
|
||||||
|
border: 1px solid #bbb;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #fff;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background: #0a6;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
button:hover { background: #098557; }
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 0.45rem 0.5rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background: #efefef;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.numbers { text-align: left; }
|
||||||
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
background: #0a6;
|
||||||
|
color: white;
|
||||||
|
padding: 0.25em 0.5em;
|
||||||
|
border-radius: 0.4em;
|
||||||
|
margin: 0 0.1em;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.muted {
|
||||||
|
color: #555;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<h1>Lotto-Ziehungen</h1>
|
||||||
|
<p class="service-note">Ein Service der Hintergasse – Angaben ohne Gewähr!</p>
|
||||||
|
|
||||||
|
<form hx-get="/ui/draws" hx-target="#results" hx-trigger="change, submit" hx-swap="innerHTML">
|
||||||
|
<label for="game">Spiel:</label>
|
||||||
|
<select name="game" id="game">
|
||||||
|
<option value="6aus49">6 aus 49</option>
|
||||||
|
<option value="euro">Eurojackpot</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="date_from">von:</label>
|
||||||
|
<input type="date" name="date_from" />
|
||||||
|
|
||||||
|
<label for="date_to">bis:</label>
|
||||||
|
<input type="date" name="date_to" />
|
||||||
|
|
||||||
|
<label for="order">Sortierung:</label>
|
||||||
|
<select name="order">
|
||||||
|
<option value="desc" selected>neueste zuerst</option>
|
||||||
|
<option value="asc">älteste zuerst</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="limit">Limit:</label>
|
||||||
|
<input type="number" name="limit" value="{{ page_size }}" min="1" max="500" />
|
||||||
|
|
||||||
|
<button type="submit">Anzeigen</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div id="results" hx-get="/ui/draws" hx-trigger="load" hx-target="#results" hx-swap="innerHTML"></div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
57
lotto2py.py
57
lotto2py.py
|
|
@ -71,6 +71,10 @@ def Euro():
|
||||||
bb = 'Eurozahl' + str(aa)
|
bb = 'Eurozahl' + str(aa)
|
||||||
ZahlenEuro[Tag][bb] = int(c)
|
ZahlenEuro[Tag][bb] = int(c)
|
||||||
aa = aa + 1
|
aa = aa + 1
|
||||||
|
jahr = datetime.now().year
|
||||||
|
tag = datetime.now().day
|
||||||
|
monat = datetime.now().month
|
||||||
|
ZahlenEuro[Tag]['Datum'] = f"{jahr}-{monat}-{tag}"
|
||||||
Tag = 'Dienstag'
|
Tag = 'Dienstag'
|
||||||
for b in soup.find("p", string=lambda s: s and "dienstag" in s.lower()):
|
for b in soup.find("p", string=lambda s: s and "dienstag" in s.lower()):
|
||||||
ZahlenEuro[Tag]['Datum'] = b
|
ZahlenEuro[Tag]['Datum'] = b
|
||||||
|
|
@ -91,10 +95,16 @@ def Euro():
|
||||||
bb = 'Eurozahl' + str(aa)
|
bb = 'Eurozahl' + str(aa)
|
||||||
ZahlenEuro[Tag][bb] = int(i)
|
ZahlenEuro[Tag][bb] = int(i)
|
||||||
aa = aa + 1
|
aa = aa + 1
|
||||||
|
jahr = datetime.now().year
|
||||||
|
tag = datetime.now().day
|
||||||
|
monat = datetime.now().month
|
||||||
|
ZahlenEuro[Tag]['Datum'] = f"{jahr}-{monat}-{tag}"
|
||||||
return ZahlenEuro
|
return ZahlenEuro
|
||||||
def Normalziehung(a):
|
def Normalziehung(a):
|
||||||
wochentag = datetime.today().weekday()
|
wochentag = datetime.today().weekday()
|
||||||
jahr = datetime.now().year
|
jahr = datetime.now().year
|
||||||
|
tag = f"{datetime.now().day:02d}"
|
||||||
|
monat = datetime.now().month
|
||||||
|
|
||||||
url = "https://www.ard-text.de/mobil/" + str(a)
|
url = "https://www.ard-text.de/mobil/" + str(a)
|
||||||
|
|
||||||
|
|
@ -125,7 +135,7 @@ def Normalziehung(a):
|
||||||
datum_woche = line.strip()
|
datum_woche = line.strip()
|
||||||
break
|
break
|
||||||
# Regex: Hauptzahlen finden (z. B. Zeile enthält "11 20 28 30 35 41")
|
# Regex: Hauptzahlen finden (z. B. Zeile enthält "11 20 28 30 35 41")
|
||||||
match_haupt = re.search(r"\s(\d{1,2}(?:\s+\d{1,2}){5})\s", text)
|
match_haupt = re.search(r"\s(\d{1,2}(?:\s+\d{1,2}){6})\s", text)
|
||||||
if match_haupt:
|
if match_haupt:
|
||||||
lottozahlen = [int(n) for n in match_haupt.group(1).split()]
|
lottozahlen = [int(n) for n in match_haupt.group(1).split()]
|
||||||
|
|
||||||
|
|
@ -163,7 +173,7 @@ def Normalziehung(a):
|
||||||
ef = str((ab + str(cd)))
|
ef = str((ab + str(cd)))
|
||||||
Lottozahlen[ef] = i
|
Lottozahlen[ef] = i
|
||||||
cd = cd + 1
|
cd = cd + 1
|
||||||
Lottozahlen['Datum'] = str(jahr) + ' / ' + str(datum_woche)
|
Lottozahlen['Datum'] = f"{jahr}-{monat}-{tag}"
|
||||||
Lottozahlen['Superzahl'] = superzahl
|
Lottozahlen['Superzahl'] = superzahl
|
||||||
Lottozahlen['Spiel77'] = int(game77)
|
Lottozahlen['Spiel77'] = int(game77)
|
||||||
Lottozahlen['Super6'] = int(subber6)
|
Lottozahlen['Super6'] = int(subber6)
|
||||||
|
|
@ -184,12 +194,18 @@ def SQLnorm(data):
|
||||||
"','" + str(data['Super6']) + "','" + str(data['Spiel77']) + "')"
|
"','" + str(data['Super6']) + "','" + str(data['Spiel77']) + "')"
|
||||||
sql_q = "SELECT * FROM 6aus49 WHERE datum like '%" + data['Datum'] + "%'"
|
sql_q = "SELECT * FROM 6aus49 WHERE datum like '%" + data['Datum'] + "%'"
|
||||||
resp = cursor.execute(sql_q)
|
resp = cursor.execute(sql_q)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if resp == 0:
|
if resp == 0:
|
||||||
cursor.execute(sql)
|
cursor.execute(sql)
|
||||||
|
|
||||||
|
notify_telegram(str(data))
|
||||||
connection.commit()
|
connection.commit()
|
||||||
cursor.close()
|
cursor.close()
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
def SQLdienstag(data):
|
def SQLdienstag(data):
|
||||||
connection = pymysql.connect(db="hubobel",
|
connection = pymysql.connect(db="hubobel",
|
||||||
user="hubobel",
|
user="hubobel",
|
||||||
|
|
@ -206,6 +222,7 @@ def SQLdienstag(data):
|
||||||
resp = cursor.execute(sql_q)
|
resp = cursor.execute(sql_q)
|
||||||
if resp == 0:
|
if resp == 0:
|
||||||
cursor.execute(sql)
|
cursor.execute(sql)
|
||||||
|
notify_telegram(str(data))
|
||||||
#print(resp)
|
#print(resp)
|
||||||
connection.commit()
|
connection.commit()
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
|
@ -225,6 +242,7 @@ def SQLfreitag(data):
|
||||||
resp = cursor.execute(sql_q)
|
resp = cursor.execute(sql_q)
|
||||||
if resp == 0:
|
if resp == 0:
|
||||||
cursor.execute(sql)
|
cursor.execute(sql)
|
||||||
|
notify_telegram(str(data))
|
||||||
|
|
||||||
connection.commit()
|
connection.commit()
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
|
@ -264,30 +282,55 @@ def SQLmittwoch(data):
|
||||||
cursor.close()
|
cursor.close()
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
|
def datum():
|
||||||
|
sql = """UPDATE `6aus49`
|
||||||
|
SET datum = DATE_FORMAT(
|
||||||
|
COALESCE(
|
||||||
|
STR_TO_DATE(TRIM(SUBSTRING_INDEX(datum, '/', -1)), '%d.%m.%Y'),
|
||||||
|
STR_TO_DATE(TRIM(SUBSTRING_INDEX(datum, '/', -1)), '%d.%m.%y')
|
||||||
|
),
|
||||||
|
'%Y-%m-%d'
|
||||||
|
)
|
||||||
|
WHERE
|
||||||
|
COALESCE(
|
||||||
|
STR_TO_DATE(TRIM(SUBSTRING_INDEX(datum, '/', -1)), '%d.%m.%Y'),
|
||||||
|
STR_TO_DATE(TRIM(SUBSTRING_INDEX(datum, '/', -1)), '%d.%m.%y')
|
||||||
|
) IS NOT NULL;"""
|
||||||
|
connection = pymysql.connect(db="hubobel",
|
||||||
|
user="hubobel",
|
||||||
|
passwd="polier2003",
|
||||||
|
host='10.0.1.123', charset='utf8')
|
||||||
|
cursor = connection.cursor()
|
||||||
|
cursor.execute(sql)
|
||||||
|
connection.commit()
|
||||||
|
cursor.close()
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
|
||||||
passw = conf()
|
passw = conf()
|
||||||
telegram_chat_id = passw['Telegram']['Chat_ID']
|
telegram_chat_id = passw['Telegram']['Chat_ID']
|
||||||
telegram_token = passw['Telegram']['TOKEN']
|
telegram_token = passw['Telegram']['TOKEN']
|
||||||
|
|
||||||
wochentag = datetime.today().weekday()
|
wochentag = datetime.today().weekday()
|
||||||
wochentag = 1
|
wochentag = 5
|
||||||
|
|
||||||
if wochentag == 2:
|
if wochentag == 2:
|
||||||
Zahl = Normalziehung(582)
|
Zahl = Normalziehung(582)
|
||||||
SQLnorm(Zahl)
|
SQLnorm(Zahl)
|
||||||
SQLmittwoch(Zahl)
|
SQLmittwoch(Zahl)
|
||||||
notify_telegram(str(Zahl))
|
#notify_telegram(str(Zahl))
|
||||||
elif wochentag == 5:
|
elif wochentag == 5:
|
||||||
Zahl = Normalziehung(581)
|
Zahl = Normalziehung(581)
|
||||||
SQLnorm(Zahl)
|
SQLnorm(Zahl)
|
||||||
SQLsamstag(Zahl)
|
SQLsamstag(Zahl)
|
||||||
notify_telegram(str(Zahl))
|
#notify_telegram(str(Zahl))
|
||||||
elif wochentag == 1:
|
elif wochentag == 1:
|
||||||
Zahl = Euro()
|
Zahl = Euro()
|
||||||
SQLdienstag(Zahl['Dienstag'])
|
SQLdienstag(Zahl['Dienstag'])
|
||||||
notify_telegram(str(Zahl['Dienstag']))
|
#notify_telegram(str(Zahl['Dienstag']))
|
||||||
elif wochentag == 4:
|
elif wochentag == 4:
|
||||||
Zahl = Euro()
|
Zahl = Euro()
|
||||||
SQLfreitag(Zahl['Freitag'])
|
SQLfreitag(Zahl['Freitag'])
|
||||||
notify_telegram(str(Zahl['Freitag']))
|
#notify_telegram(str(Zahl['Freitag']))
|
||||||
else:
|
else:
|
||||||
quit()
|
quit()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue