Skip to content

Commit e2f8e63

Browse files
authored
fix: add intermediate page for project-language upload (#17534)
This doesn't provide upload, but tells users where to perform it. Temporary solution util #4283 is implemented. Fixes #15695
1 parent 8dc7571 commit e2f8e63

File tree

3 files changed

+63
-22
lines changed

3 files changed

+63
-22
lines changed

weblate/auth/permissions.py

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,9 @@ def check_unit_review(
312312

313313
@register_perm("unit.edit", "suggestion.accept")
314314
def check_edit_approved(
315-
user: User, permission: str, obj: Unit | Translation | Component | Project
315+
user: User,
316+
permission: str,
317+
obj: Unit | Translation | Component | Project | ProjectLanguage,
316318
) -> bool | PermissionResult:
317319
component = None
318320
if isinstance(obj, Unit):
@@ -460,7 +462,7 @@ def check_suggestion_vote(
460462

461463
@register_perm("suggestion.add")
462464
def check_suggestion_add(
463-
user: User, permission: str, obj: Unit | Translation
465+
user: User, permission: str, obj: Unit | Translation | ProjectLanguage
464466
) -> bool | PermissionResult:
465467
if isinstance(obj, Unit):
466468
obj = obj.translation
@@ -469,6 +471,7 @@ def check_suggestion_add(
469471
# Check contributor license agreement
470472
if (
471473
not user.is_bot
474+
and isinstance(obj, Translation)
472475
and obj.component.agreement
473476
and not ContributorAgreement.objects.has_agreed(user, obj.component)
474477
):
@@ -478,37 +481,41 @@ def check_suggestion_add(
478481

479482
@register_perm("upload.perform")
480483
def check_upload(
481-
user: User, permission: str, translation: Translation
484+
user: User, permission: str, obj: Translation | ProjectLanguage
482485
) -> bool | PermissionResult:
483486
"""
484487
Check whether user can perform any upload operation.
485488
486489
The actual check for the method is implemented in
487490
weblate.trans.util.check_upload_method_permissions.
488491
"""
489-
# Source upload
490-
if translation.is_source and not user.has_perm("source.edit", translation):
491-
return Denied(gettext("Insufficient privileges for editing source strings."))
492-
# Bilingual source translations
493-
if (
494-
translation.is_source
495-
and not translation.is_template
496-
and not issubclass(translation.component.file_format_cls, BilingualUpdateMixin)
497-
):
498-
return Denied(
499-
gettext("The file format does not support updating source strings.")
500-
)
501-
if translation.component.is_glossary:
502-
permission = "glossary.upload"
503-
return check_can_edit(user, permission, translation) and (
492+
if isinstance(obj, Translation):
493+
# Source upload
494+
if obj.is_source and not user.has_perm("source.edit", obj):
495+
return Denied(
496+
gettext("Insufficient privileges for editing source strings.")
497+
)
498+
# Bilingual source translations
499+
if (
500+
obj.is_source
501+
and not obj.is_template
502+
and not issubclass(obj.component.file_format_cls, BilingualUpdateMixin)
503+
):
504+
return Denied(
505+
gettext("The file format does not support updating source strings.")
506+
)
507+
if obj.component.is_glossary:
508+
permission = "glossary.upload"
509+
510+
return check_can_edit(user, permission, obj) and (
504511
# Normal upload
505-
check_edit_approved(user, "unit.edit", translation)
512+
check_edit_approved(user, "unit.edit", obj)
506513
# Suggestion upload
507-
or check_suggestion_add(user, "suggestion.add", translation)
514+
or check_suggestion_add(user, "suggestion.add", obj)
508515
# Add upload
509-
or check_suggestion_add(user, "unit.add", translation)
516+
or check_suggestion_add(user, "unit.add", obj)
510517
# Source upload
511-
or translation.is_source
518+
or (isinstance(obj, Translation) and obj.is_source)
512519
)
513520

514521

weblate/templates/language-project.html

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
{% block nav_pills %}
66
{% perm 'project.edit' object.project as user_can_edit_project %}
7+
{% perm 'upload.perform' object as user_can_upload_translation %}
78

89
<ul class="nav nav-pills">
910
<li class="nav-item">
@@ -63,6 +64,11 @@
6364
href="{% url 'download' path=object.get_url_path %}?format=zip:xlsx"
6465
title="{% translate "Download for offline translation." %}">{% blocktranslate %}Download translations as XLSX in a ZIP file{% endblocktranslate %}</a>
6566
</li>
67+
{% if user_can_upload_translation %}
68+
<li>
69+
<a class="dropdown-item" data-bs-target="#upload" data-bs-toggle="tab">{% translate "Upload translation" %}</a>
70+
</li>
71+
{% endif %}
6672
</ul>
6773
</li>
6874
<li class="nav-item dropdown">
@@ -127,6 +133,7 @@
127133
{% announcements language=language project=project %}
128134
{% perm 'project.edit' object.project as user_can_edit_project %}
129135
{% get_translate_url object as translate_url %}
136+
{% perm 'upload.perform' object as user_can_upload_translation %}
130137

131138
<div class="tab-content">
132139

@@ -212,6 +219,29 @@ <h4 class="card-title">
212219
</div>
213220
{% endif %}
214221

222+
{% if user_can_upload_translation %}
223+
<div class="tab-pane" id="upload">
224+
<div class="card">
225+
<div class="card-header">
226+
<h4 class="card-title">
227+
{% documentation_icon 'user/files' 'upload' right=True %}
228+
{% translate "Upload" %}
229+
</h4>
230+
</div>
231+
<div class="card-body">
232+
<p>
233+
{% blocktranslate trimmed %}
234+
Project-wide uploads are currently not supported. Translation
235+
files need to be uploaded on the individual translations. Switch
236+
to the "Components" tab above, open the desired component, and
237+
perform the upload there.
238+
{% endblocktranslate %}
239+
</p>
240+
</div>
241+
</div>
242+
</div>
243+
{% endif %}
244+
215245
{% if announcement_form %}
216246
<div class="tab-pane" id="announcement">
217247
<form action="{% url 'announcement' path=object.get_url_path %}" method="post">

weblate/utils/stats.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,10 @@ def __str__(self) -> str:
11061106
def enable_review(self) -> bool:
11071107
return self.project.enable_review
11081108

1109+
@property
1110+
def enable_suggestions(self) -> bool:
1111+
return True
1112+
11091113
@property
11101114
def is_readonly(self) -> bool:
11111115
return False

0 commit comments

Comments
 (0)