Coverage for baibu/core/branding.py: 100%

38 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2026-10-06 13:07 +0000

1"""Language configuration for white-label deployments. 

2 

3Settings import these helpers, so they must not import Django models or 

4settings themselves. 

5""" 

6 

7from django.conf.locale import LANG_INFO 

8 

9 

10class LanguageConfigError(ValueError): 

11 """Raised when the language settings cannot be turned into LANGUAGES.""" 

12 

13 

14def parse_extra_languages(spec: str) -> dict[str, dict]: 

15 """Parse ``"code:English name:Local name; ..."`` into Django LANG_INFO entries. 

16 

17 The local name is optional and defaults to the English name. 

18 """ 

19 languages: dict[str, dict] = {} 

20 for raw_entry in (spec or "").split(";"): 

21 entry = raw_entry.strip() 

22 if not entry: 

23 continue 

24 parts = [part.strip() for part in entry.split(":")] 

25 code = parts[0].lower() 

26 if not code or len(parts) < 2 or not parts[1]: 

27 msg = f"Extra language entry {entry!r} must look like 'code:English name[:Local name]'." 

28 raise LanguageConfigError(msg) 

29 name = parts[1] 

30 name_local = parts[2] if len(parts) > 2 and parts[2] else name 

31 languages[code] = {"bidi": False, "code": code, "name": name, "name_local": name_local} 

32 return languages 

33 

34 

35def register_extra_languages(spec: str) -> dict[str, dict]: 

36 """Teach Django about languages it does not ship so they can be activated.""" 

37 languages = parse_extra_languages(spec) 

38 LANG_INFO.update(languages) 

39 return languages 

40 

41 

42def build_languages(codes: list[str], *, default: str) -> list[tuple[str, str]]: 

43 """Build the LANGUAGES setting from language codes. 

44 

45 Each code must be known to Django, either built in or registered with 

46 ``register_extra_languages``. The default language must be one of them. 

47 """ 

48 languages: list[tuple[str, str]] = [] 

49 seen: set[str] = set() 

50 for raw_code in codes: 

51 code = raw_code.strip().lower() 

52 if not code or code in seen: 

53 continue 

54 info = LANG_INFO.get(code) 

55 if info is None: 

56 msg = ( 

57 f"Unknown language code {code!r}. Declare it in PLATFORM_EXTRA_LANGUAGES " 

58 "as 'code:English name:Local name'." 

59 ) 

60 raise LanguageConfigError(msg) 

61 languages.append((code, info.get("name_local") or info["name"])) 

62 seen.add(code) 

63 if default not in seen: 

64 msg = f"PLATFORM_DEFAULT_LANGUAGE {default!r} must be listed in PLATFORM_LANGUAGES." 

65 raise LanguageConfigError(msg) 

66 return languages