# What this PR does
- add user locale field to mobile app user settings table + add a test
that sends `PATCH` requests to this endpoint
- change "you're going on call" push notification text to include
localized shift time. The general format is now:
```python
f"You're going on call in {time_until_going_oncall} for schedule
{schedule.name}, {formatted_shift}"
```
- `time_until_going_oncall` is a "human-readable" format of the time
until the start)
- `schedule.name` is self-explanatory
- `formatted_shift` this depends on the shift. If the shift starts and
ends on the same day, the format will be "HH:mm - HH:mm". Otherwise, if
the shift starts and ends on different days, the format will be
"YYYY-MM-DD HH:mm - YYYY-MM-DD HH:mm". **Note** that all datetime
related formatting will use the new `locale` field that we are now
storing in the mobile app user settings table. If no locale is yet
present we will fallback to "en"
## Which issue(s) this PR fixes
closes https://github.com/grafana/oncall/issues/2024
https://github.com/grafana/oncall-mobile-app/issues/187
## Checklist
- [x] Unit, integration, and e2e (if applicable) tests updated
- [ ] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not
required)
34 lines
1.1 KiB
Python
34 lines
1.1 KiB
Python
import logging
|
|
import typing
|
|
|
|
from babel.core import UnknownLocaleError
|
|
from babel.dates import format_datetime, format_time
|
|
from django.utils import timezone
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
FALLBACK_LOCALE = "en"
|
|
|
|
|
|
def _format_dt(
|
|
func: typing.Callable[[timezone.datetime, typing.Optional[str]], str],
|
|
dt: timezone.datetime,
|
|
locale: typing.Optional[str],
|
|
) -> str:
|
|
format = "short"
|
|
try:
|
|
# can't pass in locale of None otherwise TypeError is raised
|
|
return func(dt, format=format, locale=locale if locale else FALLBACK_LOCALE)
|
|
except UnknownLocaleError:
|
|
logger.warning(
|
|
f"babel.core.UnknownLocaleError encountered, locale={locale}. Will retry with fallback locale of {FALLBACK_LOCALE}"
|
|
)
|
|
return func(dt, format=format, locale=FALLBACK_LOCALE)
|
|
|
|
|
|
def format_localized_datetime(dt: timezone.datetime, locale: typing.Optional[str]) -> str:
|
|
return _format_dt(format_datetime, dt, locale)
|
|
|
|
|
|
def format_localized_time(dt: timezone.datetime, locale: typing.Optional[str]) -> str:
|
|
return _format_dt(format_time, dt, locale)
|