Add localizable metadata to ban notice#1085
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThis PR refactors ban message handling to separate rendered HTML from localizable message metadata. ChangesBan message localization infrastructure
🎯 2 (Simple) | ⏱️ ~12 minutes
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
server/exceptions.py (1)
47-54: ⚡ Quick winOptimize to avoid computing localization data twice.
localization()is called here to build the message text, then called again inlobbyconnection.py(line 229) when constructing the notice payload. This means_ban_duration_text()runs twice per ban event, performing redundant datetime calculations.Consider caching the localization data or refactoring to compute it once.
💡 Example approach
Option 1: Cache the localization result on the instance.
+def __init__(self, ban_expiry, ban_reason, *args, **kwargs): + super().__init__(*args, **kwargs) + self.ban_expiry = ban_expiry + self.ban_reason = ban_reason + self._localization_cache = None + def localization(self): + if self._localization_cache is None: + self._localization_cache = { + "i18n_key": BAN_NOTICE_I18N_KEY, + "i18n_args": { + "duration": self._ban_duration_text(), + "reason": self.ban_reason, + "appeal_email": BAN_APPEAL_EMAIL + } + } + return self._localization_cache - return { - "i18n_key": BAN_NOTICE_I18N_KEY, - "i18n_args": { - "duration": self._ban_duration_text(), - "reason": self.ban_reason, - "appeal_email": BAN_APPEAL_EMAIL - } - }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@server/exceptions.py` around lines 47 - 54, The message() property calls localization() and duplicates work already needed by lobbyconnection; modify the Ban/exception class to compute and cache localization() once (e.g., in __init__ or first access) and have message(), localization(), and any external callers like lobbyconnection.py use that cached result; specifically, add a private attribute (e.g., self._localization_cache) populated by a new method or in __init__, have localization() return the cached value, and update message() to read from that cache so that _ban_duration_text() and related datetime work run only once.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@server/exceptions.py`:
- Around line 37-45: The localization payload currently uses a pre-rendered
"duration" string from _ban_duration_text(); replace that with an ISO8601 UTC
timestamp field named expires_at (or null for permanent bans) so clients can
compute/localize durations. In the localization() method, stop including
"duration" and instead include "expires_at": compute the ban end as a
timezone-aware datetime in UTC (e.g., self.expires_at or derive from existing
ban end property), format it with .astimezone(timezone.utc).isoformat() (or
append 'Z' for UTC) and set None for permanent/forever bans; keep other keys
(BAN_NOTICE_I18N_KEY, ban_reason, BAN_APPEAL_EMAIL) unchanged and remove calls
to _ban_duration_text().
---
Nitpick comments:
In `@server/exceptions.py`:
- Around line 47-54: The message() property calls localization() and duplicates
work already needed by lobbyconnection; modify the Ban/exception class to
compute and cache localization() once (e.g., in __init__ or first access) and
have message(), localization(), and any external callers like lobbyconnection.py
use that cached result; specifically, add a private attribute (e.g.,
self._localization_cache) populated by a new method or in __init__, have
localization() return the cached value, and update message() to read from that
cache so that _ban_duration_text() and related datetime work run only once.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4ba4b1f4-91a4-461e-b1f6-778ec94bbe01
📒 Files selected for processing (4)
server/exceptions.pyserver/lobbyconnection.pytests/integration_tests/test_login.pytests/integration_tests/test_server.py
| def localization(self): | ||
| return { | ||
| "i18n_key": BAN_NOTICE_I18N_KEY, | ||
| "i18n_args": { | ||
| "duration": self._ban_duration_text(), | ||
| "reason": self.ban_reason, | ||
| "appeal_email": BAN_APPEAL_EMAIL | ||
| } | ||
| } |
There was a problem hiding this comment.
Include expires_at as an ISO timestamp instead of humanized duration text.
Issue #640 explicitly requires "timestamps are ISO-formatted in UTC (not timedeltas)" to enable client-side localization. The current implementation sends duration as pre-rendered English text (e.g., "for 3 hours" or "forever"), which prevents the client from localizing the duration into the user's language.
Replace duration with expires_at so the client can compute and localize the duration based on the user's locale and current time.
♻️ Proposed refactor
def localization(self):
+ ban_expiry_iso = None if self.ban_expiry.year > 9000 else self.ban_expiry.isoformat()
return {
"i18n_key": BAN_NOTICE_I18N_KEY,
"i18n_args": {
- "duration": self._ban_duration_text(),
+ "expires_at": ban_expiry_iso,
"reason": self.ban_reason,
"appeal_email": BAN_APPEAL_EMAIL
}
}Note: Permanent bans (year > 9000) can use None or a sentinel value to indicate "forever" rather than a far-future timestamp.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@server/exceptions.py` around lines 37 - 45, The localization payload
currently uses a pre-rendered "duration" string from _ban_duration_text();
replace that with an ISO8601 UTC timestamp field named expires_at (or null for
permanent bans) so clients can compute/localize durations. In the localization()
method, stop including "duration" and instead include "expires_at": compute the
ban end as a timezone-aware datetime in UTC (e.g., self.expires_at or derive
from existing ban end property), format it with
.astimezone(timezone.utc).isoformat() (or append 'Z' for UTC) and set None for
permanent/forever bans; keep other keys (BAN_NOTICE_I18N_KEY, ban_reason,
BAN_APPEAL_EMAIL) unchanged and remove calls to _ban_duration_text().
Summary
Verification
Closes #640
Summary by CodeRabbit