Coverage for app/venv/lib/python3.14/site-packages/weblate/trans/management/commands/auto_translate.py: 0%
53 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 07:15 +0000
1# Copyright © Michal Čihař <michal@weblate.org>
2#
3# SPDX-License-Identifier: GPL-3.0-or-later
5from __future__ import annotations
7from typing import TYPE_CHECKING
9from django.core.management.base import CommandError
11from weblate.auth.models import User
12from weblate.machinery.models import MACHINERY
13from weblate.trans.autotranslate import AutoTranslate
14from weblate.trans.management.commands import WeblateTranslationCommand
15from weblate.trans.models import Component
17if TYPE_CHECKING:
18 from django.core.management.base import CommandParser
21class Command(WeblateTranslationCommand):
22 """Command for mass automatic translation."""
24 help = "performs automatic translation based on other components"
26 def add_arguments(self, parser: CommandParser) -> None:
27 super().add_arguments(parser)
28 parser.add_argument(
29 "--user", default="anonymous", help=("User performing the change")
30 )
31 parser.add_argument(
32 "--source", default="", help=("Source component <project/component>")
33 )
34 parser.add_argument(
35 "--add",
36 default=False,
37 action="store_true",
38 help=("Add translations if they do not exist"),
39 )
40 parser.add_argument(
41 "--overwrite",
42 default=False,
43 action="store_true",
44 help=("Overwrite existing translations in target component"),
45 )
46 parser.add_argument(
47 "--inconsistent",
48 default=False,
49 action="store_true",
50 help=("Process only inconsistent translations"),
51 )
52 parser.add_argument(
53 "--mt", action="append", default=[], help=("Add machine translation source")
54 )
55 parser.add_argument(
56 "--threshold",
57 default=80,
58 type=int,
59 help=("Set machine translation threshold"),
60 )
61 parser.add_argument(
62 "--mode",
63 default="translate",
64 help=("Translation mode; translate, fuzzy or suggest"),
65 )
67 def handle(self, *args, **options) -> None:
68 # Get translation object
69 translation = self.get_translation(**options)
71 # Get user
72 try:
73 user = User.objects.get(username=options["user"])
74 except User.DoesNotExist as error:
75 msg = "User does not exist!"
76 raise CommandError(msg) from error
78 source = None
79 if options["source"]:
80 try:
81 component = Component.objects.get_by_path(options["source"])
82 except Component.DoesNotExist as error:
83 msg = "No matching source component found!"
84 raise CommandError(msg) from error
85 source = component.id
87 if options["mt"]:
88 for translator in options["mt"]:
89 if translator not in MACHINERY:
90 msg = f"Machine translation {translator} is not available"
91 raise CommandError(msg)
93 if options["mode"] not in {"translate", "fuzzy", "suggest"}:
94 msg = "Invalid translation mode specified!"
95 raise CommandError(msg)
97 if options["inconsistent"]:
98 q = "check:inconsistent"
99 elif options["overwrite"]:
100 q = ""
101 else:
102 q = "state:<translated"
104 auto = AutoTranslate(
105 user=user,
106 translation=translation,
107 mode=options["mode"],
108 q=q,
109 )
111 message = auto.perform(
112 auto_source="mt" if options["mt"] else "others",
113 source=source,
114 engines=options["mt"],
115 threshold=options["threshold"],
116 )
117 self.stdout.write(message)