05/23 Phase 12
This commit is contained in:
@@ -11,11 +11,31 @@ Sections:
|
||||
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
from datetime import date, timedelta
|
||||
|
||||
from db.database import get_db_stats
|
||||
from db.models import get_all_games, get_last_draw, get_draw_count, get_predictions
|
||||
from core.analyzer import frequency_analysis
|
||||
|
||||
# Weekday indices: Monday=0 … Sunday=6
|
||||
_DRAW_DAYS: dict[str, list[int]] = {
|
||||
"Powerball": [0, 2, 5], # Mon, Wed, Sat
|
||||
"Mega Millions": [1, 4], # Tue, Fri
|
||||
}
|
||||
|
||||
|
||||
def _next_draw_date(game_name: str, from_date: date | None = None) -> str:
|
||||
"""Return the next scheduled draw date as 'Day, Mon DD' (e.g. 'Sat, May 24')."""
|
||||
draw_days = _DRAW_DAYS.get(game_name)
|
||||
if not draw_days:
|
||||
return ""
|
||||
today = from_date or date.today()
|
||||
for delta in range(1, 8):
|
||||
candidate = today + timedelta(days=delta)
|
||||
if candidate.weekday() in draw_days:
|
||||
return f"{candidate.strftime('%a, %b')} {candidate.day}"
|
||||
return ""
|
||||
|
||||
_HEADER_FONT = ("TkDefaultFont", 10, "bold")
|
||||
_CARD_FONT = ("TkDefaultFont", 9)
|
||||
_NUMBER_FONT = ("TkDefaultFont", 12, "bold")
|
||||
@@ -122,6 +142,11 @@ class DashboardScreen(ttk.Frame):
|
||||
ttk.Label(card, text=f"Multiplier: {draw['multiplier']}",
|
||||
foreground="#777777", font=_CARD_FONT).pack(anchor="w")
|
||||
|
||||
next_draw = _next_draw_date(game["name"])
|
||||
if next_draw:
|
||||
ttk.Label(card, text=f"Next draw: {next_draw}",
|
||||
foreground="#117a65", font=_CARD_FONT).pack(anchor="w", pady=(6, 0))
|
||||
|
||||
def _refresh_db_summary(self):
|
||||
for w in self._db_body.winfo_children():
|
||||
w.destroy()
|
||||
|
||||
@@ -78,6 +78,12 @@ class HistoryScreen(ttk.Frame):
|
||||
self._to_entry.bind("<FocusIn>", lambda e: self._clear_hint(self._to_entry, "YYYY-MM-DD"))
|
||||
self._to_entry.bind("<FocusOut>", lambda e: self._restore_hint(self._to_entry, "YYYY-MM-DD"))
|
||||
|
||||
ttk.Label(bar, text="Number:", padding=(8, 0, 0, 0)).pack(side="left")
|
||||
self._number_var = tk.StringVar()
|
||||
self._number_entry = ttk.Entry(bar, textvariable=self._number_var, width=5)
|
||||
self._number_entry.pack(side="left", padx=(4, 14))
|
||||
self._number_entry.bind("<Return>", lambda e: self._apply_filter())
|
||||
|
||||
ttk.Button(bar, text="Search", command=self._apply_filter).pack(side="left", padx=(0, 4))
|
||||
ttk.Button(bar, text="Clear", command=self._clear_filter).pack(side="left")
|
||||
|
||||
@@ -147,6 +153,9 @@ class HistoryScreen(ttk.Frame):
|
||||
date_from = raw_from if raw_from and raw_from != "YYYY-MM-DD" else None
|
||||
date_to = raw_to if raw_to and raw_to != "YYYY-MM-DD" else None
|
||||
|
||||
raw_num = self._number_var.get().strip()
|
||||
number = int(raw_num) if raw_num.isdigit() else None
|
||||
|
||||
if game_name == "All Games":
|
||||
game_id = None
|
||||
else:
|
||||
@@ -158,6 +167,7 @@ class HistoryScreen(ttk.Frame):
|
||||
date_from=date_from,
|
||||
date_to=date_to,
|
||||
order="DESC" if not self._sort_asc else "ASC",
|
||||
number=number,
|
||||
)
|
||||
self._populate(rows)
|
||||
|
||||
@@ -214,6 +224,7 @@ class HistoryScreen(ttk.Frame):
|
||||
self._from_entry.insert(0, "YYYY-MM-DD")
|
||||
self._to_entry.delete(0, "end")
|
||||
self._to_entry.insert(0, "YYYY-MM-DD")
|
||||
self._number_var.set("")
|
||||
self._sort_col = "date"
|
||||
self._sort_asc = False
|
||||
for c in _COLUMNS:
|
||||
@@ -237,6 +248,10 @@ class HistoryScreen(ttk.Frame):
|
||||
date_to = raw_to if raw_to and raw_to != "YYYY-MM-DD" else None
|
||||
return game_id, date_from, date_to
|
||||
|
||||
def _active_number(self):
|
||||
raw = self._number_var.get().strip()
|
||||
return int(raw) if raw.isdigit() else None
|
||||
|
||||
def _export_excel(self):
|
||||
ensure_exports_dir()
|
||||
fp = filedialog.asksaveasfilename(
|
||||
|
||||
Reference in New Issue
Block a user