77
88from fluent .syntax import FluentParser
99from moz .l10n .formats import l10n_extensions
10+ from moz .l10n .message import message_to_json
1011from moz .l10n .model import Id as L10nId
1112from moz .l10n .paths import L10nConfigPaths , L10nDiscoverPaths , parse_android_locale
1213from moz .l10n .resource import parse_resource
3233from pontoon .checks .utils import bulk_run_checks
3334from pontoon .sync .core .checkout import Checkout , Checkouts
3435from pontoon .sync .core .paths import UploadPaths
35- from pontoon .sync .formats import as_vcs_translations
36+ from pontoon .sync .formats import RepoTranslation , as_repo_translations
3637
3738
3839log = logging .getLogger (__name__ )
3940
40- Updates = dict [tuple [int , int ], tuple [ str | None , bool ] ]
41- """ (entity.id, locale.id) -> (string, fuzzy) """
41+ Updates = dict [tuple [int , int ], RepoTranslation | None ]
42+ """ (entity.id, locale.id) -> RepoTranslation """
4243
4344
4445def sync_translations_from_repo (
@@ -129,7 +130,7 @@ def find_db_updates(
129130 db_changes : Iterable [ChangedEntityLocale ],
130131) -> Updates | None :
131132 """
132- `(entity.id, locale.id) -> (string|None, fuzzy) `
133+ `(entity.id, locale.id) -> RepoTranslation `
133134
134135 Translations in changed resources, excluding:
135136 - Exact matches with previous approved or pretranslated translations
@@ -140,8 +141,8 @@ def find_db_updates(
140141 resource_paths : set [str ] = set ()
141142 # db_path -> {locale.id}
142143 translated_resources : dict [str , set [int ]] = defaultdict (set )
143- # (db_path, tx.key, locale.id) -> (string |None, fuzzy)
144- translations : dict [tuple [str , L10nId , int ], tuple [ str | None , bool ] ] = {}
144+ # (db_path, tx.key, locale.id) -> RepoTranslation |None
145+ translations : dict [tuple [str , L10nId , int ], RepoTranslation | None ] = {}
145146 for target_path in changed_target_paths :
146147 ref = paths .find_reference (target_path )
147148 if ref :
@@ -161,8 +162,8 @@ def find_db_updates(
161162 resource_paths .add (db_path )
162163 translated_resources [db_path ].add (locale .pk )
163164 translations .update (
164- ((db_path , tx .key , locale .pk ), ( tx . string , tx . fuzzy ) )
165- for tx in as_vcs_translations (l10n_res )
165+ ((db_path , rt .key , locale .pk ), rt )
166+ for rt in as_repo_translations (l10n_res )
166167 )
167168 except Exception as error :
168169 scope = f"[{ project .slug } :{ db_path } , { locale .code } ]"
@@ -215,18 +216,18 @@ def find_db_updates(
215216 trans_values ["locale_id" ],
216217 )
217218 if key in translations :
218- string , _ = translations [key ]
219- if translations_equal (
219+ rt = translations [key ]
220+ if rt is not None and translations_equal (
220221 project ,
221222 key [0 ],
222223 trans_values ["entity__resource__format" ],
223- string ,
224+ rt . string ,
224225 trans_values ["string" ],
225226 ):
226227 del translations [key ]
227228 else :
228229 # The translation has been removed from the repo
229- translations [key ] = ( None , False )
230+ translations [key ] = None
230231 if paginator .num_pages > 3 :
231232 log .debug (
232233 f"[{ project .slug } ] Filtering matches from translations... { page_number } /{ paginator .num_pages } "
@@ -258,10 +259,10 @@ def find_db_updates(
258259 .iterator ()
259260 }
260261 updates : Updates = {}
261- for (db_path , ent_key , locale_id ), tx in translations .items ():
262+ for (db_path , ent_key , locale_id ), rt in translations .items ():
262263 entity_id = entities .get ((db_path , ent_key ), None )
263264 if entity_id is not None :
264- updates [(entity_id , locale_id )] = tx
265+ updates [(entity_id , locale_id )] = rt
265266 log .debug (f"[{ project .slug } ] Compiling updates... Found { len (updates )} " )
266267 return updates
267268
@@ -302,14 +303,14 @@ def update_db_translations(
302303 # Approve matching suggestions
303304 matching_suggestions_q = Q ()
304305 repo_rm_count = 0
305- for (entity_id , locale_id ), ( string , _ ) in repo_translations .items ():
306- if string is None :
306+ for (entity_id , locale_id ), rt in repo_translations .items ():
307+ if rt is None :
307308 # The translation has been removed from the repo
308309 translations_to_reject |= Q (entity_id = entity_id , locale_id = locale_id )
309310 repo_rm_count += 1
310311 else :
311312 matching_suggestions_q |= Q (
312- entity_id = entity_id , locale_id = locale_id , string = string
313+ entity_id = entity_id , locale_id = locale_id , string = rt . string
313314 )
314315 # (entity_id, locale_id) => translation
315316 suggestions : dict [tuple [int , int ], Translation ] = (
@@ -325,7 +326,8 @@ def update_db_translations(
325326 update_fields : set [str ] = set ()
326327 approve_count = 0
327328 for tx in suggestions .values ():
328- _ , fuzzy = repo_translations [(tx .entity_id , tx .locale_id )]
329+ rt = repo_translations [(tx .entity_id , tx .locale_id )]
330+ fuzzy = rt .fuzzy if rt is not None else False
329331 if fuzzy and tx .fuzzy :
330332 # Keep fuzzy suggestions unchanged
331333 continue
@@ -371,17 +373,24 @@ def update_db_translations(
371373 new_translations : list [Translation ] = []
372374 if repo_translations :
373375 # Add new approved translations for the remainder
374- for (entity_id , locale_id ), (string , fuzzy ) in repo_translations .items ():
375- if string is not None :
376+ for (entity_id , locale_id ), rt in repo_translations .items ():
377+ if rt is not None :
378+ json_properties = (
379+ {key : message_to_json (msg ) for key , msg in rt .properties .items ()}
380+ if rt .properties
381+ else None
382+ )
376383 tx = Translation (
377384 entity_id = entity_id ,
378385 locale_id = locale_id ,
379- string = string ,
386+ string = rt .string ,
387+ value = message_to_json (rt .value ),
388+ properties = json_properties ,
380389 date = now ,
381390 active = True ,
382391 user = user ,
383392 )
384- if fuzzy :
393+ if rt . fuzzy :
385394 tx .fuzzy = True
386395 else :
387396 tx .approved = True
0 commit comments