Skip to content

Commit

Permalink
add method sync_current_user to determine locale
Browse files Browse the repository at this point in the history
not all list locales are in the userlistsettings, only if a
language was explicitly set by the user. The users default locale
is get from sync_current_user. If it  still fails, fall-back
to the APIs default locale.
  • Loading branch information
tr4nt0r committed Feb 19, 2024
1 parent ff73f43 commit a44a6dd
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 19 deletions.
92 changes: 73 additions & 19 deletions bring_api/bring.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
BringListResponse,
BringNotificationsConfigType,
BringNotificationType,
BringSyncCurrentUserResponse,
BringUserListSettings,
BringUserSettings,
BringUserSettingsResponse,
Expand All @@ -44,6 +45,7 @@ def __init__(
self.password = password
self.public_uuid = ""
self.userlistsettings: dict[str, dict[str, str]] = {}
self.user_locale = "de-CH"
self.supported_locales = [
"en-AU",
"de-DE",
Expand Down Expand Up @@ -166,8 +168,12 @@ async def login(self) -> BringAuthResponse:
self.headers["X-BRING-USER-UUID"] = self.uuid
self.headers["Authorization"] = f'Bearer {data["access_token"]}'

locale = (await self.sync_current_user())["userLocale"]
self.headers["X-BRING-COUNTRY"] = locale["country"]
self.user_locale = f"{locale["country"]}-{locale["language"]}"

if len(self.__translations) == 0:
await self.__load_article_locales()
await self.__load_article_translations()

if len(self.userlistsettings) == 0:
await self.__load_user_list_settings()
Expand Down Expand Up @@ -266,7 +272,7 @@ async def get_list(self, list_uuid: str) -> BringItemsResponse:
for item in lst: # type: ignore[attr-defined]
item["itemId"] = self.__translate(
item["itemId"],
to_locale=self.__list_locale(list_uuid),
to_locale=self.__locale(list_uuid),
)

return data
Expand Down Expand Up @@ -400,7 +406,7 @@ async def save_item(
data = {
"purchase": self.__translate(
item_name,
from_locale=self.__list_locale(list_uuid),
from_locale=self.__locale(list_uuid),
),
"specification": specification,
}
Expand Down Expand Up @@ -463,7 +469,7 @@ async def update_item(
data = {
"purchase": self.__translate(
item_name,
from_locale=self.__list_locale(list_uuid),
from_locale=self.__locale(list_uuid),
),
"specification": specification,
}
Expand Down Expand Up @@ -524,7 +530,7 @@ async def remove_item(
data = {
"remove": self.__translate(
item_name,
from_locale=self.__list_locale(list_uuid),
from_locale=self.__locale(list_uuid),
),
}
try:
Expand Down Expand Up @@ -584,7 +590,7 @@ async def complete_item(
data = {
"recently": self.__translate(
item_name,
from_locale=self.__list_locale(list_uuid),
from_locale=self.__locale(list_uuid),
)
}
try:
Expand Down Expand Up @@ -754,8 +760,8 @@ async def does_user_exist(self, mail: Optional[str] = None) -> bool:

return True

async def __load_article_locales(self) -> None:
"""Load all translation dictionaries.
async def __load_article_translations(self) -> None:
"""Load all translation dictionaries into memory.
Raises
------
Expand Down Expand Up @@ -864,7 +870,7 @@ def __translate(
) from e

async def __load_user_list_settings(self) -> None:
"""Load user list settings.
"""Load user list settings into memory.
Raises
------
Expand Down Expand Up @@ -986,28 +992,76 @@ async def get_all_user_settings(self) -> BringUserSettingsResponse:
"Loading user settings failed due to request exception."
) from e

def __list_locale(self, list_uuid: str) -> str:
"""Get locale for list.
def __locale(self, list_uuid: str) -> str:
"""Get list or user locale.
Returns
-------
str
The locale from userlistsettings.
The locale from userlistsettings or user.
Raises
------
BringTranslationException
If list locale could not be determined from the userlistsettings.
If list locale could not be determined from the userlistsettings or user.
"""
try:
if list_uuid in self.userlistsettings:
return self.userlistsettings[list_uuid]["listArticleLanguage"]
except KeyError as e:
return self.user_locale

async def sync_current_user(self) -> BringSyncCurrentUserResponse:
"""Sync current user.
Returns
-------
dict
The JSON response as a dict.
Raises
------
BringRequestException
If the request fails.
BringParseException
If the parsing of the request response fails.
"""
try:
url = f"{self.url}v2/bringusers/{self.uuid}"
async with self._session.get(url, headers=self.headers) as r:
_LOGGER.debug("Response from %s: %s", url, r.status)
r.raise_for_status()

try:
data = cast(
BringSyncCurrentUserResponse,
{
key: val
for key, val in (await r.json()).items()
if key in BringSyncCurrentUserResponse.__annotations__
},
)
return data
except JSONDecodeError as e:
_LOGGER.error(
"Exception: Cannot get lists:\n %s", traceback.format_exc()
)
raise BringParseException(
"Loading lists failed during parsing of request response."
) from e
except asyncio.TimeoutError as e:
_LOGGER.error(
"Exception: Cannot determine locale for list %s:\n%s",
list_uuid,
"Exception: Cannot get current user settings:\n %s",
traceback.format_exc(),
)
raise BringTranslationException(
"Translation failed due to error determining locale for list"
raise BringRequestException(
"Loading current user settings failed due to connection timeout."
) from e
except aiohttp.ClientError as e:
_LOGGER.error(
"Exception: Cannot current user settings:\n %s", traceback.format_exc()
)
raise BringRequestException(
"Loading current user settings failed due to request exception."
) from e
10 changes: 10 additions & 0 deletions bring_api/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,13 @@ class BringUserSettingsResponse(TypedDict):

usersettings: List[BringUserSettings]
userlistsettings: List[BringUserListSettings]


class BringSyncCurrentUserResponse(TypedDict):
"""A sync current user response class."""

email: str
name: str
publicUuid: str
userLocale: dict[str, str]
userUuid: str

0 comments on commit a44a6dd

Please sign in to comment.