Coverage for ckanext/udc/solr/config.py: 59%
64 statements
« prev ^ index » next coverage.py v7.7.1, created at 2026-01-19 23:48 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2026-01-19 23:48 +0000
1from __future__ import annotations
2import logging
3from typing import Union
5from ckan.plugins.toolkit import config
6from ckan.lib.search.common import SolrSettings
7import ckan.lib.helpers as h
9log = logging.getLogger(__name__)
12def get_udc_langs():
13 # read dataset languages, ensure default locale is included
14 default_lang = config.get("ckan.locale_default", "en") or "en"
15 raw_langs = config.get("udc.multilingual.languages", default_lang)
17 # normalize and keep original order
18 langs = [l.strip() for l in raw_langs.split() if l.strip()]
20 # deduplicate while preserving order
21 seen = set()
22 ordered_langs = []
23 for lang in langs:
24 if lang not in seen:
25 ordered_langs.append(lang)
26 seen.add(lang)
28 # ensure default language is first
29 remaining_langs = [lang for lang in ordered_langs if lang != default_lang]
30 return [default_lang] + remaining_langs
32def get_default_lang():
33 """Get the default language from the config, defaulting to 'en'."""
34 return config.get("ckan.locale_default", "en") or "en"
37def get_current_lang():
38 """Get the current language from the request context or default to 'en'."""
39 lang = h.lang()
40 if not lang:
41 lang = config.get("ckan.locale_default", "en") or "en"
42 return lang
45def pick_locale(texts: Union[str, dict], lang: str = None) -> str:
46 """Pick the text in the specified language from a dict of texts.
48 If texts is a string, return it directly.
49 If texts is a dict, return the text in the specified language if available,
50 otherwise return the first text in the dict.
51 """
52 if not lang:
53 lang = h.lang() or "en"
54 if isinstance(texts, str):
55 return texts
56 elif isinstance(texts, dict):
57 if lang in texts:
58 return texts[lang]
59 elif "en" in texts:
60 return texts["en"]
61 elif len(texts) > 0:
62 return list(texts.values())[0]
63 return ""
66def pick_locale_with_fallback(texts: Union[str, dict], lang: str = None) -> tuple:
67 """Pick the text in the specified language from a dict of texts with fallback chain.
69 Returns a tuple of (text, actual_lang_used) where actual_lang_used is None if
70 the requested language was used, or the language code if a fallback was used.
72 If texts is a string, return (texts, None).
73 If texts is a dict, try requested language, then follow the precedence order
74 from get_udc_langs(). Empty strings are treated as missing values.
75 """
76 if not lang:
77 lang = h.lang() or get_default_lang()
79 if isinstance(texts, str):
80 return (texts, None)
82 if not isinstance(texts, dict):
83 return ("", None)
85 # Helper to check if value is non-empty
86 def is_non_empty(val):
87 if val is None:
88 return False
89 if isinstance(val, str) and not val.strip():
90 return False
91 if isinstance(val, (list, dict)) and not val:
92 return False
93 return True
95 # If requested language exists and is non-empty, return it with None (no fallback)
96 if lang in texts and is_non_empty(texts[lang]):
97 return (texts[lang], None)
99 # Otherwise, try fallback languages in order
100 lang_order = get_udc_langs()
101 for fallback_lang in lang_order:
102 if fallback_lang in texts and is_non_empty(texts[fallback_lang]):
103 # Return the value and the language code used
104 return (texts[fallback_lang], fallback_lang)
106 # Last resort: return any available non-empty value
107 for k, v in texts.items():
108 if is_non_empty(v):
109 return (v, k)
111 return ("", None)