11import csv
22import logging
33
4+ from typing import cast
5+
46from django .conf import settings
57from django .contrib .auth .decorators import login_required
68from django .core .exceptions import PermissionDenied
3335from pontoon .pretranslation .tasks import pretranslate_task
3436from pontoon .sync .tasks import sync_project_task
3537
38+ from ..base .models .project import ProjectQuerySet
39+
3640
3741log = logging .getLogger (__name__ )
3842
@@ -127,6 +131,8 @@ def manage_project(request, slug=None, template="admin_project.html"):
127131 subtitle = "Add project"
128132 pk = None
129133 project = None
134+ prev_config_file = None
135+ prev_set_locales_from_repo = False
130136
131137 # Save project
132138 if request .method == "POST" :
@@ -143,7 +149,11 @@ def manage_project(request, slug=None, template="admin_project.html"):
143149 # Update existing project
144150 try :
145151 pk = request .POST ["pk" ]
146- project = Project .objects .visible_for (request .user ).get (pk = pk )
152+ project = (
153+ cast (ProjectQuerySet , Project .objects )
154+ .visible_for (request .user )
155+ .get (pk = pk )
156+ )
147157 form = ProjectForm (request .POST , instance = project )
148158 # Needed if form invalid
149159 repo_formset = RepositoryInlineFormSet (request .POST , instance = project )
@@ -156,6 +166,8 @@ def manage_project(request, slug=None, template="admin_project.html"):
156166 request .POST , instance = project
157167 )
158168 subtitle = "Edit project"
169+ prev_config_file = project .configuration_file
170+ prev_set_locales_from_repo = project .set_locales_from_repo
159171
160172 # Add a new project
161173 except MultiValueDictKeyError :
@@ -166,7 +178,7 @@ def manage_project(request, slug=None, template="admin_project.html"):
166178 tag_formset = None
167179
168180 if form .is_valid ():
169- project = form .save (commit = False )
181+ project = cast ( Project , form .save (commit = False ) )
170182 repo_formset = RepositoryInlineFormSet (request .POST , instance = project )
171183 external_resource_formset = ExternalResourceInlineFormSet (
172184 request .POST , instance = project
@@ -180,38 +192,43 @@ def manage_project(request, slug=None, template="admin_project.html"):
180192 )
181193 if formsets_valid :
182194 project .save ()
183-
184- # Manually save ProjectLocales due to intermediary model
185- locales_form = form .cleaned_data .get ("locales" , [])
186- locales_readonly_form = form .cleaned_data .get ("locales_readonly" , [])
187- locales = locales_form | locales_readonly_form
188-
189- (
190- ProjectLocale .objects .filter (project = project )
191- .exclude (locale__pk__in = [loc .pk for loc in locales ])
192- .delete ()
193- )
194-
195- for locale in locales :
196- # The implicit pre_save and post_save signals sent here are required
197- # to maintain django-guardian permissions.
198- ProjectLocale .objects .get_or_create (project = project , locale = locale )
199-
200- project_locales = ProjectLocale .objects .filter (project = project )
201-
202- # Update readonly flags
203- locales_readonly_pks = [loc .pk for loc in locales_readonly_form ]
204- project_locales .filter (readonly = True ).exclude (
205- locale__pk__in = locales_readonly_pks
206- ).update (readonly = False )
207- project_locales .filter (
208- locale__pk__in = locales_readonly_pks , readonly = False
209- ).update (readonly = True )
195+ pk = project .pk
196+ data = form .cleaned_data
197+
198+ set_locales_from_repo = data .get ("set_locales_from_repo" , False )
199+
200+ if set_locales_from_repo :
201+ project_locales = ProjectLocale .objects .filter (project = project )
202+ else :
203+ # Manually save ProjectLocales due to intermediary model
204+ locales_form = data .get ("locales" , set ())
205+ locales_readonly_form = data .get ("locales_readonly" , set ())
206+ locales = locales_form | locales_readonly_form
207+
208+ ProjectLocale .objects .filter (project = project ).exclude (
209+ locale__pk__in = [loc .pk for loc in locales ]
210+ ).delete ()
211+
212+ for locale in locales :
213+ # The implicit pre_save and post_save signals sent here are required
214+ # to maintain django-guardian permissions.
215+ ProjectLocale .objects .get_or_create (
216+ project = project , locale = locale
217+ )
218+
219+ project_locales = ProjectLocale .objects .filter (project = project )
220+
221+ # Update readonly flags
222+ locales_readonly_pks = [loc .pk for loc in locales_readonly_form ]
223+ project_locales .filter (readonly = True ).exclude (
224+ locale__pk__in = locales_readonly_pks
225+ ).update (readonly = False )
226+ project_locales .filter (
227+ locale__pk__in = locales_readonly_pks , readonly = False
228+ ).update (readonly = True )
210229
211230 # Update pretranslate flags
212- locales_pretranslate_form = form .cleaned_data .get (
213- "locales_pretranslate" , []
214- )
231+ locales_pretranslate_form = data .get ("locales_pretranslate" , [])
215232 locales_pretranslate_pks = [loc .pk for loc in locales_pretranslate_form ]
216233 project_locales .filter (pretranslation_enabled = True ).exclude (
217234 locale__pk__in = locales_pretranslate_pks ,
@@ -239,7 +256,14 @@ def manage_project(request, slug=None, template="admin_project.html"):
239256 if project .tags_enabled :
240257 tag_formset = TagInlineFormSet (instance = project )
241258 subtitle += ". Saved."
242- pk = project .pk
259+
260+ if project .data_source == Project .DataSource .REPOSITORY and (
261+ set_locales_from_repo
262+ and not prev_set_locales_from_repo
263+ or data .get ("configuration_file" ) != prev_config_file
264+ ):
265+ sync_project_task .delay (project .pk )
266+ subtitle += " Sync started."
243267 else :
244268 subtitle += ". Error."
245269 else :
0 commit comments