From 58614fbda2714389a392a4fbc0a65f420efc6bd8 Mon Sep 17 00:00:00 2001 From: shokollm <270575765+shokollm@users.noreply.github.com> Date: Sun, 5 Apr 2026 00:06:59 +0000 Subject: [PATCH] fix: use group timezone in bounty list and show command 1. format_bounty now accepts timezone_str parameter 2. Calculate hours/days remaining using group's timezone 3. Format dates using group's timezone (not server local time) 4. Updated cmd_bounty, cmd_my, cmd_show to pass timezone --- apps/telegram-bot/commands.py | 46 +++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/apps/telegram-bot/commands.py b/apps/telegram-bot/commands.py index 23e1dd5..a77d185 100644 --- a/apps/telegram-bot/commands.py +++ b/apps/telegram-bot/commands.py @@ -144,7 +144,9 @@ def parse_args( return text, link, due_date_ts, clear_link, clear_date -def format_bounty(b, show_id: bool = True, slice_length: int = 0) -> str: +def format_bounty( + b, show_id: bool = True, slice_length: int = 0, timezone_str: str = "UTC" +) -> str: parts = [] if show_id: parts.append(f"[#{b.id}]") @@ -156,12 +158,20 @@ def format_bounty(b, show_id: bool = True, slice_length: int = 0) -> str: if b.link: parts.append(f"🔗 {b.link}") if b.due_date_ts: - now = int(time.time()) - seconds_left = b.due_date_ts - now + try: + tz = ZoneInfo(timezone_str) + except (KeyError, ZoneInfoNotFoundError): + tz = ZoneInfo("UTC") + + now_utc = int(time.time()) + dt_now = datetime.now(tz) + dt_due = datetime.fromtimestamp(b.due_date_ts, tz=tz) + + seconds_left = int((dt_due - dt_now).total_seconds()) hours_left = seconds_left // 3600 days_left = seconds_left // 86400 - due_str = time.strftime("%d %b %Y %H:%M", time.localtime(b.due_date_ts)) + due_str = dt_due.strftime("%d %b %Y %H:%M") if seconds_left < 0: parts.append(f"⏰ {due_str} (OVERDUE)") @@ -232,6 +242,7 @@ def get_room_id(update: Update) -> int: async def cmd_bounty(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: room_id = get_room_id(update) user_id = get_user_id(update) + timezone_str = BOUNTY_SERVICE.get_timezone(room_id) args = extract_args(update.message.text) show_all = "all" in args @@ -282,7 +293,11 @@ async def cmd_bounty(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: slice_length = 0 for b in displayed_bounties: - lines.append(format_bounty(b, show_id=True, slice_length=slice_length)) + lines.append( + format_bounty( + b, show_id=True, slice_length=slice_length, timezone_str=timezone_str + ) + ) keyboard = [[InlineKeyboardButton("🗑️ Delete", callback_data=f"del_msg:{user_id}")]] reply_markup = InlineKeyboardMarkup(keyboard) @@ -302,6 +317,8 @@ async def cmd_my(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: room_id = get_room_id(update) bounties = BOUNTY_SERVICE.list_bounties(room_id) + timezone_str = BOUNTY_SERVICE.get_timezone(room_id) + if not bounties: msg = ( "You are not tracking any bounties." @@ -311,7 +328,9 @@ async def cmd_my(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: await update.message.reply_text(msg) return - lines = [format_bounty(b, show_id=True) for b in bounties] + lines = [ + format_bounty(b, show_id=True, timezone_str=timezone_str) for b in bounties + ] await update.message.reply_text("\n".join(lines), disable_web_page_preview=True) @@ -609,7 +628,12 @@ async def cmd_show(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: await update.message.reply_text("Bounty not found.") return - timezone = BOUNTY_SERVICE.get_timezone(room_id) + timezone_str = BOUNTY_SERVICE.get_timezone(room_id) + + try: + tz = ZoneInfo(timezone_str) + except (KeyError, ZoneInfoNotFoundError): + tz = ZoneInfo("UTC") lines = [] @@ -620,13 +644,15 @@ async def cmd_show(update: Update, ctx: ContextTypes.DEFAULT_TYPE) -> None: lines.append(f"🔗 {bounty.link}") if bounty.due_date_ts: - due_str = time.strftime("%d %B %Y %H:%M", time.localtime(bounty.due_date_ts)) - lines.append(f"📅 {due_str} ({timezone})") + dt_due = datetime.fromtimestamp(bounty.due_date_ts, tz=tz) + due_str = dt_due.strftime("%d %B %Y %H:%M") + lines.append(f"📅 {due_str} ({timezone_str})") username = bounty.created_by_username or f"user#{bounty.created_by_user_id}" lines.append(f"👤 @{username}") - created_str = time.strftime("%Y-%m-%d %H:%M", time.localtime(bounty.created_at)) + dt_created = datetime.fromtimestamp(bounty.created_at, tz=tz) + created_str = dt_created.strftime("%Y-%m-%d %H:%M") lines.append(f"📌 Created: {created_str}") await update.message.reply_text("\n".join(lines), disable_web_page_preview=True)