Change exp leveling system

This commit is contained in:
Rene Arumetsa
2026-05-13 22:43:34 +03:00
parent 15e3121d55
commit 8d7ac504ca
3 changed files with 45 additions and 16 deletions

View File

@@ -2,9 +2,11 @@
from __future__ import annotations
import calendar
import logging
from datetime import datetime, date
from dataclasses import dataclass, field
from zoneinfo import ZoneInfo
import discord
@@ -13,6 +15,20 @@ from . import sheets
log = logging.getLogger(__name__)
_PLACEHOLDER = {"-", "x", "n/a", "none", "ei"}
_TZ = ZoneInfo("Europe/Tallinn")
def today_local() -> date:
"""Today's date in Europe/Tallinn — the bot's operational timezone, independent of host TZ."""
return datetime.now(_TZ).date()
def _shift_year_safe(d: date, year: int) -> date:
"""Move `d` to `year`; Feb 29 falls back to Feb 28 when the target year is non-leap."""
try:
return d.replace(year=year)
except ValueError:
return d.replace(year=year, day=28)
def _is_placeholder(val: str) -> bool:
@@ -72,7 +88,7 @@ def _parse_birthday(raw: str) -> date | None:
raw = str(raw).strip()
if _is_placeholder(raw):
return None
today = date.today()
today = today_local()
for fmt, has_year in [("%d/%m/%Y", True), ("%Y-%m-%d", True), ("%m-%d", False)]:
try:
parsed = datetime.strptime(raw, fmt).date()
@@ -90,21 +106,32 @@ def _is_birthday_soon(birthday_str: str, window_days: int | None = None) -> bool
if bday is None:
return False
window = window_days or config.BIRTHDAY_WINDOW_DAYS
today = date.today()
this_year_bday = bday.replace(year=today.year)
today = today_local()
this_year_bday = _shift_year_safe(bday, today.year)
if this_year_bday < today:
this_year_bday = bday.replace(year=today.year + 1)
this_year_bday = _shift_year_safe(bday, today.year + 1)
delta = (this_year_bday - today).days
return 0 <= delta <= window
def is_birthday_today(birthday_str: str) -> bool:
"""Return True if today is the member's birthday (any supported date format)."""
"""Return True if today is the member's birthday (any supported date format).
Feb 29 babies are observed on Feb 28 in non-leap years.
"""
bday = _parse_birthday(birthday_str)
if bday is None:
return False
today = date.today()
return bday.month == today.month and bday.day == today.day
today = today_local()
if bday.month == today.month and bday.day == today.day:
return True
if (
bday.month == 2 and bday.day == 29
and today.month == 2 and today.day == 28
and not calendar.isleap(today.year)
):
return True
return False
async def sync_member(