import logging
import re
import httpx
from httpcore import ConnectError
logger = logging.getLogger("audible.localization")
LOCALE_TEMPLATES = {
"germany": {
"country_code": "de",
"domain": "de",
"market_place_id": "AN7V1F1VY261K",
},
"united_states": {
"country_code": "us",
"domain": "com",
"market_place_id": "AF2M0KC94RCEA",
},
"united_kingdom": {
"country_code": "uk",
"domain": "co.uk",
"market_place_id": "A2I9A3Q2GNFNGQ",
},
"france": {
"country_code": "fr",
"domain": "fr",
"market_place_id": "A2728XDNODOQ8T",
},
"canada": {
"country_code": "ca",
"domain": "ca",
"market_place_id": "A2CQZ5RBY40XE",
},
"italy": {
"country_code": "it",
"domain": "it",
"market_place_id": "A2N7FU2W2BU2ZC",
},
"australia": {
"country_code": "au",
"domain": "com.au",
"market_place_id": "AN7EY7DTAW63G",
},
"india": {
"country_code": "in",
"domain": "in",
"market_place_id": "AJO3FBRUE6J4S",
},
"japan": {
"country_code": "jp",
"domain": "co.jp",
"market_place_id": "A1QAP3MOU4173J",
},
"spain": {
"country_code": "es",
"domain": "es",
"market_place_id": "ALMIKO4SZCSAR",
},
"brazil": {
"country_code": "br",
"domain": "com.br",
"market_place_id": "A10J1VAYUDTYRN",
},
}
[docs]
def search_template(key: str, value: str) -> dict[str, str] | None:
for country, locale in LOCALE_TEMPLATES.items():
if locale.get(key, "") == value:
logger.debug("found locale for %s", country)
return locale
logger.info("do not found %s in %s", value, key)
return None
[docs]
def autodetect_locale(domain: str) -> dict[str, str]:
"""Try to automatically detect correct settings for marketplace.
Needs the top level domain of the audible page to continue with
(e.g. co.uk, co.jp) and returns results found.
Args:
domain: The top level domain for the Audible marketplace to
detect settings for (e.g. com).
Returns:
The settings for the found Audible marketplace.
Raises:
ConnectError: If site does not exist or network error raises.
Exception: If marketplace or country code can't be found.
"""
domain = domain.lstrip(".")
site = f"https://www.audible.{domain}"
params = {"ipRedirectOverride": True, "overrideBaseCountry": True}
try:
resp = httpx.get(site, params=params)
except ConnectError as e:
logger.warning("site %s does not exists or Network Error occurs", site)
raise e
marketplace_pattern = re.compile(r"ue_mid = \'(.*)\'")
marketplace_search = re.search(marketplace_pattern, resp.text)
if marketplace_search is None:
raise Exception("can't find marketplace")
market_place_id = marketplace_search.group(1)
alias_pattern = re.compile(r"autocomplete_config.searchAlias = \"(.*)\"")
alias_search = re.search(alias_pattern, resp.text)
if alias_search is None:
raise Exception("can't find country code")
country_code = alias_search.group(1).split("-")[-1]
return {
"country_code": country_code,
"domain": domain,
"market_place_id": market_place_id,
}
[docs]
class Locale:
"""Adjustments for the different marketplaces who are provided by Audible.
You can try to ``autodetect_locale`` if your marketplace is
not in templates`.
"""
def __init__(
self,
country_code: str | None = None,
domain: str | None = None,
market_place_id: str | None = None,
) -> None:
if country_code is None or domain is None or market_place_id is None:
locale = None
if country_code:
locale = search_template("country_code", country_code)
elif domain:
locale = search_template("domain", domain)
if locale is None:
raise Exception("can't find locale")
country_code = country_code or locale["country_code"]
domain = domain or locale["domain"]
market_place_id = market_place_id or locale["market_place_id"]
self._country_code = country_code
self._domain = domain
self._market_place_id = market_place_id
def __repr__(self) -> str:
return (
f"Locale class for domain: {self.domain}, "
f"marketplace: {self.market_place_id}"
)
[docs]
def to_dict(self) -> dict[str, str]:
return {
"country_code": self.country_code,
"domain": self.domain,
"market_place_id": self.market_place_id,
}
@property
def country_code(self) -> str:
return self._country_code
@property
def domain(self) -> str:
return self._domain
@property
def market_place_id(self) -> str:
return self._market_place_id