Skip to content

Commit 6649d5b

Browse files
author
Konstantinos Bairaktaris
committed
Refactor language management in TxNative
1 parent 65d1848 commit 6649d5b

5 files changed

Lines changed: 88 additions & 110 deletions

File tree

tests/native/core/test_cds.py

Lines changed: 9 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ def test_fetch_translations(self, patched_logger):
202202
responses.GET, cds_host + '/content/fr', status=404
203203
)
204204

205-
resp = cds_handler.fetch_translations()
205+
resp = cds_handler.fetch_translations('el')
206206
assert resp == {
207207
'el': (True, {
208208
'key1': {
@@ -212,6 +212,9 @@ def test_fetch_translations(self, patched_logger):
212212
'string': 'key2_el'
213213
},
214214
}),
215+
}
216+
resp = cds_handler.fetch_translations('en')
217+
assert resp == {
215218
'en': (True, {
216219
'key1': {
217220
'string': 'key1_en'
@@ -220,58 +223,16 @@ def test_fetch_translations(self, patched_logger):
220223
'string': 'key2_en'
221224
},
222225
}),
223-
'fr': (False, {}) # that is due to the error status in response
224226
}
225-
226-
responses.reset()
227-
228-
# test fetch_languages fails with connection error
229-
responses.add(responses.GET, cds_host + '/languages', status=500)
230-
resp = cds_handler.fetch_translations()
231-
assert resp == {}
232-
233-
patched_logger.error.assert_called_with(
234-
'Error retrieving languages from CDS: UnknownError '
235-
'(`500 Server Error: Internal Server Error for url: '
236-
'https://some.host/languages`)'
237-
)
238-
responses.reset()
239-
patched_logger.reset_mock()
240-
241-
# test language code
242-
responses.add(
243-
responses.GET, cds_host + '/content/el',
244-
json={
245-
'data': {
246-
'key1': {
247-
'string': 'key1_el'
248-
},
249-
'key2': {
250-
'string': 'key2_el'
251-
},
252-
},
253-
'meta': {
254-
"some_key": "some_value"
255-
}
256-
}, status=200
257-
)
258-
259-
resp = cds_handler.fetch_translations(language_code='el')
227+
resp = cds_handler.fetch_translations('fr')
260228
assert resp == {
261-
'el': (True, {
262-
'key1': {
263-
'string': 'key1_el'
264-
},
265-
'key2': {
266-
'string': 'key2_el'
267-
},
268-
})
229+
'fr': (False, {}) # that is due to the error status in response
269230
}
231+
270232
responses.reset()
271-
assert patched_logger.error.call_count == 0
272233

273234
# test connection_error
274-
resp = cds_handler.fetch_translations(language_code='el')
235+
resp = cds_handler.fetch_translations('el')
275236
patched_logger.error.assert_called_with(
276237
'Error retrieving translations from CDS: ConnectionError'
277238
)
@@ -331,7 +292,7 @@ def test_fetch_translations_etags_management(self, patched_logger):
331292
status=304
332293
)
333294

334-
resp = cds_handler.fetch_translations()
295+
resp = cds_handler.fetch_translations('el')
335296
assert resp == {
336297
'el': (True, {
337298
'key1': {
@@ -341,7 +302,6 @@ def test_fetch_translations_etags_management(self, patched_logger):
341302
'string': 'key2_el'
342303
},
343304
}),
344-
'en': (False, {})
345305
}
346306
assert cds_handler.etags.get('el') == 'some_unique_tag_is_here'
347307

tests/native/core/test_core.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ def test_push_strings_reaches_cds_handler(self, mock_push_strings):
195195
def test_fetch_translations_reaches_cds_handler_and_cache(self, mock_cds,
196196
mock_cache):
197197
mytx = self._get_tx()
198+
mytx.remote_languages = [{'code': "el"}]
198199
mytx.fetch_translations()
199200
assert mock_cds.call_count == 1
200201
assert mock_cache.call_count > 0

tests/native/core/test_init.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ def test_init_uses_given_params(self):
1212
missing_policy=PseudoTranslationPolicy())
1313
assert _tx._cds_handler.token == 'mytoken'
1414
assert _tx._cds_handler.host == 'myhost'
15-
assert _tx._languages == ['lang1', 'lang2']
15+
assert _tx.hardcoded_language_codes == ['lang1', 'lang2']
1616
assert isinstance(_tx._missing_policy, PseudoTranslationPolicy)

transifex/native/cds.py

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def fetch_languages(self):
118118

119119
return languages
120120

121-
def fetch_translations(self, language_code=None):
121+
def fetch_translations(self, language_code):
122122
"""Fetch all translations for the given organization/project/(resource)
123123
associated with the current token. Returns a tuple of refresh flag and
124124
a dictionary of the fetched translations per language.
@@ -133,61 +133,53 @@ def fetch_translations(self, language_code=None):
133133

134134
translations = {}
135135

136-
if not language_code:
137-
languages = [lang['code'] for lang in self.fetch_languages()]
138-
else:
139-
languages = [language_code]
140-
141-
for language_code in set(languages) & \
142-
set(self.configured_language_codes):
143-
144-
try:
145-
last_response_status = 202
146-
while last_response_status == 202:
147-
response = requests.get(
148-
(self.host +
149-
cds_url.format(language_code=language_code)),
150-
headers=self._get_headers(
151-
etag=self.etags.get(language_code)
152-
)
136+
try:
137+
last_response_status = 202
138+
while last_response_status == 202:
139+
response = requests.get(
140+
(self.host +
141+
cds_url.format(language_code=language_code)),
142+
headers=self._get_headers(
143+
etag=self.etags.get(language_code)
153144
)
154-
last_response_status = response.status_code
145+
)
146+
last_response_status = response.status_code
155147

156-
if not response.ok:
157-
logger.error(
158-
'Error retrieving translations from CDS: `{}`'.format(
159-
response.reason
160-
)
161-
)
162-
response.raise_for_status()
163-
164-
# etags indicate that no translation have been updated
165-
if response.status_code == 304:
166-
translations[language_code] = (False, {})
167-
else:
168-
self.etags.set(
169-
language_code, response.headers.get('ETag', ''))
170-
json_content = response.json()
171-
translations[language_code] = (
172-
True, json_content['data']
148+
if not response.ok:
149+
logger.error(
150+
'Error retrieving translations from CDS: `{}`'.format(
151+
response.reason
173152
)
153+
)
154+
response.raise_for_status()
174155

175-
except (KeyError, ValueError):
176-
# Compatibility with python2.7 where `JSONDecodeError` doesn't
177-
# exist
178-
logger.error('Error retrieving translations from CDS: '
179-
'Malformed response') # pragma no cover
180-
translations[language_code] = (False, {}) # pragma no cover
181-
except requests.ConnectionError:
182-
logger.error(
183-
'Error retrieving translations from CDS: ConnectionError')
184-
translations[language_code] = (False, {})
185-
except Exception as e:
186-
logger.error(
187-
'Error retrieving translations from CDS: UnknownError '
188-
'(`{}`)'.format(str(e))
189-
) # pragma no cover
156+
# etags indicate that no translation have been updated
157+
if response.status_code == 304:
190158
translations[language_code] = (False, {})
159+
else:
160+
self.etags.set(
161+
language_code, response.headers.get('ETag', ''))
162+
json_content = response.json()
163+
translations[language_code] = (
164+
True, json_content['data']
165+
)
166+
167+
except (KeyError, ValueError):
168+
# Compatibility with python2.7 where `JSONDecodeError` doesn't
169+
# exist
170+
logger.error('Error retrieving translations from CDS: '
171+
'Malformed response') # pragma no cover
172+
translations[language_code] = (False, {}) # pragma no cover
173+
except requests.ConnectionError:
174+
logger.error(
175+
'Error retrieving translations from CDS: ConnectionError')
176+
translations[language_code] = (False, {})
177+
except Exception as e:
178+
logger.error(
179+
'Error retrieving translations from CDS: UnknownError '
180+
'(`{}`)'.format(str(e))
181+
) # pragma no cover
182+
translations[language_code] = (False, {})
191183

192184
return translations
193185

transifex/native/core.py

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,21 @@ class TxNative(object):
1515
behavior."""
1616

1717
def __init__(self, **kwargs):
18-
self._languages = []
18+
self.source_language_code = None
19+
self.current_language_code = None
20+
self.hardcoded_language_codes = None
21+
self.remote_languages = None
22+
1923
self._missing_policy = SourceStringPolicy()
2024
self._cds_handler = CDSHandler()
2125
self._cache = MemoryCache()
2226
self._error_policy = SourceStringErrorPolicy()
2327

2428
self.setup(**kwargs)
2529

26-
def setup(self, languages=None, token=None, secret=None, cds_host=None,
30+
def setup(self,
31+
source_language=None, current_language=None, languages=None,
32+
token=None, secret=None, cds_host=None,
2733
missing_policy=None, error_policy=None):
2834
"""Create an instance of the core framework class.
2935
@@ -41,18 +47,41 @@ def setup(self, languages=None, token=None, secret=None, cds_host=None,
4147
:param AbstractErrorPolicy error_policy: an optional policy
4248
to determine how to handle rendering errors
4349
"""
50+
if source_language is not None:
51+
self.source_language_code = source_language
52+
if current_language is not None:
53+
self.current_language_code = current_language
4454
if languages is not None:
45-
self._languages = languages
55+
self.hardcoded_language_codes = languages
4656
if missing_policy is not None:
4757
self._missing_policy = missing_policy
4858
if error_policy is not None:
4959
self._error_policy = error_policy
5060

51-
self._cds_handler.setup(configured_languages=languages,
52-
token=token,
61+
self._cds_handler.setup(token=token,
5362
secret=secret,
5463
host=cds_host)
5564

65+
def fetch_languages(self, force=False):
66+
if self.remote_languages is None or force:
67+
self.remote_languages = self._cds_handler.fetch_languages()
68+
69+
if self.hardcoded_language_codes is not None:
70+
return [language
71+
for language in self.remote_languages
72+
if language['code'] in self.hardcoded_language_codes]
73+
else:
74+
return self.remote_languages
75+
76+
def fetch_translations(self, language_code=None, force=False):
77+
"""Fetch fresh content from the CDS."""
78+
if language_code is None:
79+
for language in self.fetch_languages():
80+
self.fetch_translations(language['code'], force=force)
81+
else:
82+
translations = self._cds_handler.fetch_translations(language_code)
83+
self._cache.update(translations)
84+
5685
def translate(
5786
self, source_string, language_code, is_source=False,
5887
_context=None, escape=True, params=None
@@ -133,10 +162,6 @@ def render_translation(self, translation_template, params, source_string,
133162
escape=escape, params=params,
134163
)
135164

136-
def fetch_translations(self):
137-
"""Fetch fresh content from the CDS."""
138-
self._cache.update(self._cds_handler.fetch_translations())
139-
140165
def push_source_strings(self, strings, purge=False):
141166
"""Push the given source strings to the CDS.
142167

0 commit comments

Comments
 (0)