Skip to content

Commit

Permalink
feat(component): bilingual file upload (#12713)
Browse files Browse the repository at this point in the history
* bilingual file upload implementation
* document update
* clean debugging comment

Fixes #11085
  • Loading branch information
gersona authored Oct 9, 2024
1 parent 080ff64 commit 8b55e66
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 9 deletions.
1 change: 1 addition & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Not yet released.
* :kbd:`?` now displays available :ref:`keyboard`.
* Translation and language view in the project now include basic information about the language and plurals.
* :ref:`bulk-edit` shows a preview of matched strings.
* Creating component via file upload (Translate document) now supports bilingual files.

**Bug fixes**

Expand Down
7 changes: 7 additions & 0 deletions weblate/trans/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1850,6 +1850,13 @@ class ComponentDocCreateForm(ComponentProjectForm):
validators=[validate_file_extension],
)

target_language = forms.ModelChoiceField(
widget=SortedSelect,
label=gettext_lazy("Target language"),
help_text=gettext_lazy("Target language of the document for bilingual files"),
queryset=Language.objects.all(),
required=False,
)
field_order = ["docfile", "project", "name", "slug"]

def __init__(self, *args, **kwargs) -> None:
Expand Down
23 changes: 22 additions & 1 deletion weblate/trans/tests/test_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
from django.test.utils import modify_settings, override_settings
from django.urls import reverse

from weblate.lang.models import get_default_lang
from weblate.lang.models import Language, get_default_lang
from weblate.trans.tests.test_views import ViewTestCase
from weblate.trans.tests.utils import create_test_billing, get_test_file
from weblate.vcs.git import GitRepository

TEST_ZIP = get_test_file("translations.zip")
TEST_HTML = get_test_file("cs.html")
TEST_PO = get_test_file("cs.po")


class CreateTest(ViewTestCase):
Expand Down Expand Up @@ -370,6 +371,26 @@ def test_create_doc_category(self) -> None:
self.assertContains(response, "Adding new translation")
self.assertContains(response, "*.html")

@modify_settings(INSTALLED_APPS={"remove": "weblate.billing"})
def test_create_doc_bilingual(self) -> None:
self.user.is_superuser = True
self.user.save()

with open(TEST_PO) as handle, override_settings(CREATE_GLOSSARIES=False):
response = self.client.post(
reverse("create-component-doc"),
{
"docfile": handle,
"name": "Bilingual Component From Doc",
"slug": "bilingual-component-from-doc",
"project": self.project.pk,
"source_language": get_default_lang(),
"target_language": Language.objects.get(code="cs").id,
},
)
self.assertContains(response, "Choose translation files to import")
self.assertNotContains(response, "gettext PO file (monolingual)")

@modify_settings(INSTALLED_APPS={"remove": "weblate.billing"})
def test_create_scratch(self) -> None:
@override_settings(CREATE_GLOSSARIES=self.CREATE_GLOSSARIES)
Expand Down
5 changes: 3 additions & 2 deletions weblate/trans/views/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,9 +415,10 @@ def form_valid(self, form):
return super().form_valid(form)

fake = create_component_from_doc(
form.cleaned_data, form.cleaned_data.pop("docfile")
form.cleaned_data,
form.cleaned_data.pop("docfile"),
form.cleaned_data.pop("target_language", None),
)

# Move to discover phase
self.stage = "discover"
self.initial = form.cleaned_data
Expand Down
17 changes: 11 additions & 6 deletions weblate/utils/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,26 +386,31 @@ def guess_filemask_from_doc(data, docfile=None) -> None:
data["filemask"] = "{}/{}{}".format(data.get("slug", "translations"), "*", ext)


def create_component_from_doc(data, docfile):
def create_component_from_doc(data, docfile, target_language: Language | None = None):
# Calculate filename
uploaded = docfile or data["docfile"]
guess_filemask_from_doc(data, uploaded)
filemask = data["filemask"]
filename = filemask.replace(
"*",
data["source_language"].code
file_language_code = (
target_language.code
if target_language # bilingual file
else data["source_language"].code
if "source_language" in data
else settings.DEFAULT_LANGUAGE,
else settings.DEFAULT_LANGUAGE
)
filename = filemask.replace("*", file_language_code)
# Create fake component (needed to calculate path)
fake = Component(
project=data["project"],
slug=data["slug"],
name=data["name"],
category=data.get("category", None),
template=filename,
filemask=filemask,
)

if not target_language:
fake.template = filename

# Create repository
LocalRepository.from_files(fake.full_path, {filename: uploaded.read()})
return fake
Expand Down

0 comments on commit 8b55e66

Please sign in to comment.