fix: parse dates using group's timezone when adding/updating bounties
The parse_args function now accepts timezone_str parameter and uses it to localize parsed dates. This ensures dates are interpreted in the group's timezone, not the server's local timezone.
This commit is contained in:
@@ -59,6 +59,7 @@ def extract_args(text: str) -> list[str]:
|
||||
|
||||
def parse_args(
|
||||
args: list[str],
|
||||
timezone_str: str = "UTC",
|
||||
) -> tuple[Optional[str], Optional[str], Optional[int], bool, bool]:
|
||||
text = None
|
||||
link = None
|
||||
@@ -66,6 +67,11 @@ def parse_args(
|
||||
clear_link = False
|
||||
clear_date = False
|
||||
|
||||
try:
|
||||
tz = ZoneInfo(timezone_str)
|
||||
except (KeyError, ZoneInfoNotFoundError):
|
||||
tz = ZoneInfo("UTC")
|
||||
|
||||
def is_url(s: str) -> bool:
|
||||
if not s:
|
||||
return False
|
||||
@@ -87,6 +93,13 @@ def parse_args(
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
def parse_date_with_tz(date_str: str) -> int | None:
|
||||
parsed = dateparser.parse(date_str)
|
||||
if parsed:
|
||||
localized = parsed.replace(tzinfo=tz)
|
||||
return int(localized.timestamp())
|
||||
return None
|
||||
|
||||
i = 0
|
||||
while i < len(args):
|
||||
arg = args[i]
|
||||
@@ -100,9 +113,8 @@ def parse_args(
|
||||
i += 1
|
||||
elif arg == "-date":
|
||||
if i + 1 < len(args):
|
||||
parsed = dateparser.parse(args[i + 1])
|
||||
if parsed:
|
||||
due_date_ts = int(parsed.timestamp())
|
||||
due_date_ts = parse_date_with_tz(args[i + 1])
|
||||
if due_date_ts is not None:
|
||||
i += 2
|
||||
if i < len(args) and is_time(args[i]):
|
||||
time_parts = args[i].split(":")
|
||||
@@ -120,9 +132,8 @@ def parse_args(
|
||||
link = arg
|
||||
i += 1
|
||||
elif due_date_ts is None:
|
||||
parsed = dateparser.parse(arg)
|
||||
if parsed:
|
||||
due_date_ts = int(parsed.timestamp())
|
||||
due_date_ts = parse_date_with_tz(arg)
|
||||
if due_date_ts is not None:
|
||||
i += 1
|
||||
if i < len(args) and is_time(args[i]):
|
||||
time_parts = args[i].split(":")
|
||||
@@ -343,14 +354,15 @@ async def cmd_add(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
)
|
||||
return
|
||||
|
||||
text, link, due_date_ts, _, _ = parse_args(args)
|
||||
user_id = get_user_id(update)
|
||||
room_id = get_room_id(update)
|
||||
timezone_str = BOUNTY_SERVICE.get_timezone(room_id)
|
||||
|
||||
text, link, due_date_ts, _, _ = parse_args(args, timezone_str)
|
||||
if not text and not link:
|
||||
await update.message.reply_text("A bounty needs at least text or a link.")
|
||||
return
|
||||
|
||||
user_id = get_user_id(update)
|
||||
room_id = get_room_id(update)
|
||||
|
||||
try:
|
||||
bounty = BOUNTY_SERVICE.add_bounty(
|
||||
room_id=room_id,
|
||||
@@ -397,7 +409,11 @@ async def cmd_update(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
await update.message.reply_text("Invalid bounty ID.")
|
||||
return
|
||||
|
||||
text, link, due_date_ts, clear_link, clear_date = parse_args(args[1:])
|
||||
user_id = get_user_id(update)
|
||||
room_id = get_room_id(update)
|
||||
timezone_str = BOUNTY_SERVICE.get_timezone(room_id)
|
||||
|
||||
text, link, due_date_ts, clear_link, clear_date = parse_args(args[1:], timezone_str)
|
||||
if (
|
||||
not text
|
||||
and not link
|
||||
@@ -408,9 +424,6 @@ async def cmd_update(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
await update.message.reply_text("Nothing to update.")
|
||||
return
|
||||
|
||||
user_id = get_user_id(update)
|
||||
room_id = get_room_id(update)
|
||||
|
||||
old_bounty = BOUNTY_SERVICE.get_bounty(room_id, bounty_id)
|
||||
if not old_bounty:
|
||||
await update.message.reply_text("Bounty not found.")
|
||||
|
||||
Reference in New Issue
Block a user