oblalex /
verboselib
| Conditions | 2 |
| Total Lines | 5 |
| Code Lines | 5 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
| Metric | Value |
|---|---|
| eloc | 5 |
| dl | 0 |
| loc | 5 |
| rs | 10 |
| c | 0 |
| b | 0 |
| f | 0 |
| cc | 2 |
| nop | 1 |
| 1 | import argparse |
||
|
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
| 2 | |||
| 3 | from pathlib import Path |
||
| 4 | |||
| 5 | from typing import Callable |
||
|
0 ignored issues
–
show
|
|||
| 6 | from typing import Iterable |
||
| 7 | from typing import List |
||
| 8 | from typing import Optional |
||
| 9 | from typing import Set |
||
| 10 | from typing import Text |
||
| 11 | from typing import Type |
||
|
0 ignored issues
–
show
|
|||
| 12 | |||
| 13 | try: |
||
| 14 | from typing import Literal |
||
|
0 ignored issues
–
show
|
|||
| 15 | MODE = Literal["w", "a"] |
||
|
0 ignored issues
–
show
|
|||
| 16 | except ImportError: |
||
| 17 | MODE = Text |
||
|
0 ignored issues
–
show
|
|||
| 18 | |||
| 19 | from .command_base import BaseCommand |
||
| 20 | from .command_base import BaseCommandExecutor |
||
| 21 | |||
| 22 | from .gettext_tools import extract_translations |
||
| 23 | from .gettext_tools import extract_unique_messages |
||
| 24 | from .gettext_tools import merge_new_and_existing_translations |
||
| 25 | from .gettext_tools import remove_obsolete_translations |
||
| 26 | from .gettext_tools import strip_translations_header |
||
| 27 | from .gettext_tools import validate_gettext_tools_exist |
||
| 28 | |||
| 29 | from .paths import ensure_dir_exists |
||
| 30 | from .paths import find_source_files_paths |
||
| 31 | from .paths import get_names_of_immediate_subdirectories |
||
| 32 | from .paths import make_messages_dir_path |
||
|
0 ignored issues
–
show
|
|||
| 33 | from .paths import make_po_file_path |
||
| 34 | from .paths import make_pot_file_path |
||
| 35 | |||
| 36 | from .text import flatten_comma_separated_values |
||
| 37 | from .text import stringify_path |
||
| 38 | |||
| 39 | from .utils import print_err |
||
| 40 | from .utils import print_out |
||
| 41 | from .utils import show_usage_error_and_halt |
||
| 42 | |||
| 43 | from . import defaults |
||
| 44 | |||
| 45 | |||
| 46 | class ExtractCommandExecutor(BaseCommandExecutor): |
||
|
0 ignored issues
–
show
|
|||
| 47 | |||
| 48 | def __init__(self, args=argparse.Namespace) -> None: |
||
|
0 ignored issues
–
show
The
__init__ method of the super-class BaseCommandExecutor is not called.
It is generally advisable to initialize the super-class by calling its class SomeParent:
def __init__(self):
self.x = 1
class SomeChild(SomeParent):
def __init__(self):
# Initialize the super class
SomeParent.__init__(self)
Loading history...
|
|||
| 49 | self._domain = args.domain |
||
|
0 ignored issues
–
show
|
|||
| 50 | self._validate_domain(self._domain) |
||
|
0 ignored issues
–
show
|
|||
| 51 | |||
| 52 | self._process_all_locales = args.all |
||
|
0 ignored issues
–
show
|
|||
| 53 | |||
| 54 | self._locales_dir_path = self._handle_locales_dir_path(args.output_dir) |
||
|
0 ignored issues
–
show
|
|||
| 55 | self._validate_locales_dir_path(self._locales_dir_path) |
||
|
0 ignored issues
–
show
|
|||
| 56 | |||
| 57 | self._pot_file_path = make_pot_file_path(self._locales_dir_path, self._domain) |
||
|
0 ignored issues
–
show
|
|||
| 58 | |||
| 59 | self._locales = self._handle_locales( |
||
|
0 ignored issues
–
show
|
|||
| 60 | locales=args.locale, |
||
|
0 ignored issues
–
show
|
|||
| 61 | process_all=self._process_all_locales, |
||
|
0 ignored issues
–
show
|
|||
| 62 | locales_dir_path=self._locales_dir_path, |
||
|
0 ignored issues
–
show
|
|||
| 63 | ) |
||
| 64 | self._validate_locales(self._locales) |
||
|
0 ignored issues
–
show
|
|||
| 65 | |||
| 66 | self._keywords = self._handle_keywords( |
||
|
0 ignored issues
–
show
|
|||
| 67 | keywords=args.keyword, |
||
|
0 ignored issues
–
show
|
|||
| 68 | no_defaults=args.no_default_keywords, |
||
|
0 ignored issues
–
show
|
|||
| 69 | ) |
||
| 70 | self._extensions = self._handle_extensions(args.extensions) |
||
|
0 ignored issues
–
show
|
|||
| 71 | self._follow_links = args.follow_links |
||
|
0 ignored issues
–
show
|
|||
| 72 | self._ignore_patterns = self._handle_ignore_patterns( |
||
|
0 ignored issues
–
show
|
|||
| 73 | ignore_patterns=args.ignore_patterns, |
||
|
0 ignored issues
–
show
|
|||
| 74 | no_defaults=args.no_default_ignore_patterns, |
||
|
0 ignored issues
–
show
|
|||
| 75 | ) |
||
| 76 | self._no_wrap = args.no_wrap |
||
|
0 ignored issues
–
show
|
|||
| 77 | self._no_location = args.no_location |
||
|
0 ignored issues
–
show
|
|||
| 78 | self._no_obsolete = args.no_obsolete |
||
|
0 ignored issues
–
show
|
|||
| 79 | self._keep_pot = args.keep_pot |
||
|
0 ignored issues
–
show
|
|||
| 80 | self._xgettext_extra_args = flatten_comma_separated_values(args.xgettext_extra_args) |
||
|
0 ignored issues
–
show
|
|||
| 81 | self._msguniq_extra_args = flatten_comma_separated_values(args.msguniq_extra_args) |
||
|
0 ignored issues
–
show
|
|||
| 82 | self._msgmerge_extra_args = flatten_comma_separated_values(args.msgmerge_extra_args) |
||
|
0 ignored issues
–
show
|
|||
| 83 | self._msgattrib_extra_args = flatten_comma_separated_values(args.msgattrib_extra_args) |
||
|
0 ignored issues
–
show
|
|||
| 84 | self._verbose = args.verbose |
||
|
0 ignored issues
–
show
|
|||
| 85 | |||
| 86 | @staticmethod |
||
|
0 ignored issues
–
show
|
|||
| 87 | def _handle_keywords( |
||
|
0 ignored issues
–
show
|
|||
| 88 | keywords: Optional[Iterable[Text]]=None, |
||
|
0 ignored issues
–
show
|
|||
| 89 | no_defaults: bool=False, |
||
|
0 ignored issues
–
show
|
|||
| 90 | ) -> List[Text]: |
||
| 91 | |||
| 92 | keywords = ( |
||
|
0 ignored issues
–
show
|
|||
| 93 | list(keywords) |
||
|
0 ignored issues
–
show
|
|||
| 94 | if keywords is not None |
||
|
0 ignored issues
–
show
|
|||
| 95 | else [] |
||
|
0 ignored issues
–
show
|
|||
| 96 | ) |
||
| 97 | |||
| 98 | if not no_defaults: |
||
|
0 ignored issues
–
show
|
|||
| 99 | keywords.extend(defaults.DEFAULT_KEYWORDS) |
||
|
0 ignored issues
–
show
|
|||
| 100 | |||
| 101 | return list(sorted(set(keywords))) |
||
|
0 ignored issues
–
show
|
|||
| 102 | |||
| 103 | @staticmethod |
||
|
0 ignored issues
–
show
|
|||
| 104 | def _handle_extensions( |
||
|
0 ignored issues
–
show
|
|||
| 105 | extensions: Optional[Iterable[Text]]=None, |
||
|
0 ignored issues
–
show
|
|||
| 106 | ignored: Optional[Iterable[Text]]=None, |
||
|
0 ignored issues
–
show
|
|||
| 107 | ) -> Set[Text]: |
||
| 108 | |||
| 109 | extensions = ( |
||
|
0 ignored issues
–
show
|
|||
| 110 | list(extensions) |
||
|
0 ignored issues
–
show
|
|||
| 111 | if extensions is not None |
||
|
0 ignored issues
–
show
|
|||
| 112 | else [] |
||
|
0 ignored issues
–
show
|
|||
| 113 | ) |
||
| 114 | |||
| 115 | ignored = ( |
||
|
0 ignored issues
–
show
|
|||
| 116 | set(ignored) |
||
|
0 ignored issues
–
show
|
|||
| 117 | if ignored is not None |
||
|
0 ignored issues
–
show
|
|||
| 118 | else set() |
||
|
0 ignored issues
–
show
|
|||
| 119 | ) |
||
| 120 | |||
| 121 | ext_list = [] |
||
|
0 ignored issues
–
show
|
|||
| 122 | |||
| 123 | for ext in extensions: |
||
|
0 ignored issues
–
show
|
|||
| 124 | ext_list.extend(ext.replace(" ", "").split(",")) |
||
|
0 ignored issues
–
show
|
|||
| 125 | |||
| 126 | for i, ext in enumerate(ext_list): |
||
|
0 ignored issues
–
show
|
|||
| 127 | if not ext.startswith("."): |
||
|
0 ignored issues
–
show
|
|||
| 128 | ext_list[i] = ".%s" % ext_list[i] |
||
|
0 ignored issues
–
show
|
|||
| 129 | |||
| 130 | ext_list.append(".py") |
||
|
0 ignored issues
–
show
|
|||
| 131 | |||
| 132 | return { |
||
|
0 ignored issues
–
show
|
|||
| 133 | x |
||
|
0 ignored issues
–
show
|
|||
| 134 | for x in ext_list |
||
|
0 ignored issues
–
show
|
|||
| 135 | if x.strip(".") not in ignored |
||
|
0 ignored issues
–
show
|
|||
| 136 | } |
||
| 137 | |||
| 138 | @staticmethod |
||
|
0 ignored issues
–
show
|
|||
| 139 | def _handle_ignore_patterns( |
||
|
0 ignored issues
–
show
|
|||
| 140 | ignore_patterns: Optional[Iterable[Text]]=None, |
||
|
0 ignored issues
–
show
|
|||
| 141 | no_defaults: bool=False, |
||
|
0 ignored issues
–
show
|
|||
| 142 | ) -> List[Text]: |
||
| 143 | |||
| 144 | ignore_patterns = ( |
||
|
0 ignored issues
–
show
|
|||
| 145 | list(ignore_patterns) |
||
|
0 ignored issues
–
show
|
|||
| 146 | if ignore_patterns is not None |
||
|
0 ignored issues
–
show
|
|||
| 147 | else [] |
||
|
0 ignored issues
–
show
|
|||
| 148 | ) |
||
| 149 | |||
| 150 | if not no_defaults: |
||
|
0 ignored issues
–
show
|
|||
| 151 | ignore_patterns.extend(defaults.DEFAULT_IGNORE_PATTERNS) |
||
|
0 ignored issues
–
show
|
|||
| 152 | |||
| 153 | return list(sorted(set(ignore_patterns))) |
||
|
0 ignored issues
–
show
|
|||
| 154 | |||
| 155 | @staticmethod |
||
|
0 ignored issues
–
show
|
|||
| 156 | def _validate_domain(domain: Optional[Text]) -> None: |
||
|
0 ignored issues
–
show
|
|||
| 157 | if not domain: |
||
|
0 ignored issues
–
show
|
|||
| 158 | print_err(f"invalid domain value: '{domain}'") |
||
|
0 ignored issues
–
show
|
|||
| 159 | show_usage_error_and_halt() |
||
|
0 ignored issues
–
show
|
|||
| 160 | |||
| 161 | @staticmethod |
||
|
0 ignored issues
–
show
|
|||
| 162 | def _handle_locales_dir_path(path: Text) -> Path: |
||
|
0 ignored issues
–
show
|
|||
| 163 | return Path(path).absolute() |
||
|
0 ignored issues
–
show
|
|||
| 164 | |||
| 165 | @staticmethod |
||
|
0 ignored issues
–
show
|
|||
| 166 | def _validate_locales_dir_path(path: Path) -> None: |
||
|
0 ignored issues
–
show
|
|||
| 167 | if path.exists() and not path.is_dir(): |
||
|
0 ignored issues
–
show
|
|||
| 168 | print_err( |
||
|
0 ignored issues
–
show
|
|||
| 169 | f"locales dir already exists but it is not a directory " |
||
|
0 ignored issues
–
show
|
|||
| 170 | f"(path={stringify_path(path)})" |
||
| 171 | ) |
||
| 172 | show_usage_error_and_halt() |
||
|
0 ignored issues
–
show
|
|||
| 173 | |||
| 174 | @staticmethod |
||
|
0 ignored issues
–
show
|
|||
| 175 | def _handle_locales( |
||
|
0 ignored issues
–
show
|
|||
| 176 | locales: Optional[List[Text]], |
||
|
0 ignored issues
–
show
|
|||
| 177 | process_all: bool, |
||
|
0 ignored issues
–
show
|
|||
| 178 | locales_dir_path: Path, |
||
|
0 ignored issues
–
show
|
|||
| 179 | ) -> List[Text]: |
||
| 180 | |||
| 181 | if locales: |
||
|
0 ignored issues
–
show
|
|||
| 182 | return flatten_comma_separated_values(locales) |
||
|
0 ignored issues
–
show
|
|||
| 183 | elif process_all: |
||
|
0 ignored issues
–
show
|
|||
| 184 | return get_names_of_immediate_subdirectories(locales_dir_path) |
||
|
0 ignored issues
–
show
|
|||
| 185 | else: |
||
|
0 ignored issues
–
show
|
|||
| 186 | return [] |
||
|
0 ignored issues
–
show
|
|||
| 187 | |||
| 188 | @staticmethod |
||
|
0 ignored issues
–
show
|
|||
| 189 | def _validate_locales(locales: List[Text]) -> None: |
||
|
0 ignored issues
–
show
|
|||
| 190 | if not locales: |
||
|
0 ignored issues
–
show
|
|||
| 191 | print_err( |
||
|
0 ignored issues
–
show
|
|||
| 192 | "specify at least 1 locale or specify processing of all existing locales" |
||
|
0 ignored issues
–
show
|
|||
| 193 | ) |
||
| 194 | show_usage_error_and_halt() |
||
|
0 ignored issues
–
show
|
|||
| 195 | |||
| 196 | def __call__(self) -> None: |
||
|
0 ignored issues
–
show
|
|||
| 197 | validate_gettext_tools_exist() |
||
|
0 ignored issues
–
show
|
|||
| 198 | |||
| 199 | if self._verbose: |
||
|
0 ignored issues
–
show
|
|||
| 200 | self._print_input_args( |
||
|
0 ignored issues
–
show
|
|||
| 201 | domain=self._domain, |
||
|
0 ignored issues
–
show
|
|||
| 202 | locales_dir_path=stringify_path(self._locales_dir_path), |
||
|
0 ignored issues
–
show
|
|||
| 203 | process_all_locales=self._process_all_locales, |
||
|
0 ignored issues
–
show
|
|||
| 204 | locales=self._locales, |
||
|
0 ignored issues
–
show
|
|||
| 205 | keywords=self._keywords, |
||
|
0 ignored issues
–
show
|
|||
| 206 | extensions=self._extensions, |
||
|
0 ignored issues
–
show
|
|||
| 207 | follow_links=self._follow_links, |
||
|
0 ignored issues
–
show
|
|||
| 208 | ignore_patterns=self._ignore_patterns, |
||
|
0 ignored issues
–
show
|
|||
| 209 | no_wrap=self._no_wrap, |
||
|
0 ignored issues
–
show
|
|||
| 210 | no_location=self._no_location, |
||
|
0 ignored issues
–
show
|
|||
| 211 | no_obsolete=self._no_obsolete, |
||
|
0 ignored issues
–
show
|
|||
| 212 | keep_pot=self._keep_pot, |
||
|
0 ignored issues
–
show
|
|||
| 213 | xgettext_extra_args=self._xgettext_extra_args, |
||
|
0 ignored issues
–
show
|
|||
| 214 | msguniq_extra_args=self._msguniq_extra_args, |
||
|
0 ignored issues
–
show
|
|||
| 215 | msgmerge_extra_args=self._msgmerge_extra_args, |
||
|
0 ignored issues
–
show
|
|||
| 216 | msgattrib_extra_args=self._msgattrib_extra_args, |
||
|
0 ignored issues
–
show
|
|||
| 217 | verbose=self._verbose, |
||
|
0 ignored issues
–
show
|
|||
| 218 | ) |
||
| 219 | |||
| 220 | ensure_dir_exists(self._locales_dir_path) |
||
|
0 ignored issues
–
show
|
|||
| 221 | |||
| 222 | try: |
||
|
0 ignored issues
–
show
|
|||
| 223 | self._make_pot_file() |
||
|
0 ignored issues
–
show
|
|||
| 224 | self._ensure_no_duplicates_in_pot_file() |
||
|
0 ignored issues
–
show
|
|||
| 225 | self._make_all_po_files() |
||
|
0 ignored issues
–
show
|
|||
| 226 | finally: |
||
|
0 ignored issues
–
show
|
|||
| 227 | if not self._keep_pot: |
||
|
0 ignored issues
–
show
|
|||
| 228 | self._maybe_remove_pot_file() |
||
|
0 ignored issues
–
show
|
|||
| 229 | |||
| 230 | def _make_pot_file(self) -> None: |
||
|
0 ignored issues
–
show
|
|||
| 231 | if self._verbose: |
||
|
0 ignored issues
–
show
|
|||
| 232 | print_out(f"making '.pot' file") |
||
|
0 ignored issues
–
show
|
|||
| 233 | |||
| 234 | self._maybe_remove_pot_file() |
||
|
0 ignored issues
–
show
|
|||
| 235 | |||
| 236 | sources_root_dir_path = Path(".") # explicitly use relative path |
||
|
0 ignored issues
–
show
|
|||
| 237 | |||
| 238 | for file_path in find_source_files_paths( |
||
|
0 ignored issues
–
show
|
|||
| 239 | root_dir_path=sources_root_dir_path, |
||
|
0 ignored issues
–
show
|
|||
| 240 | ignore_patterns=self._ignore_patterns, |
||
|
0 ignored issues
–
show
|
|||
| 241 | extensions=self._extensions, |
||
|
0 ignored issues
–
show
|
|||
| 242 | follow_links=self._follow_links, |
||
|
0 ignored issues
–
show
|
|||
| 243 | verbose=self._verbose, |
||
|
0 ignored issues
–
show
|
|||
| 244 | ): |
||
| 245 | self._process_source_file(file_path) |
||
|
0 ignored issues
–
show
|
|||
| 246 | |||
| 247 | def _process_source_file(self, source_file_path: Path) -> None: |
||
|
0 ignored issues
–
show
|
|||
| 248 | if self._verbose: |
||
|
0 ignored issues
–
show
|
|||
| 249 | print_out(f"processing source '{stringify_path(source_file_path.absolute())}'") |
||
|
0 ignored issues
–
show
|
|||
| 250 | |||
| 251 | content = extract_translations( |
||
|
0 ignored issues
–
show
|
|||
| 252 | source_file_path=source_file_path, |
||
|
0 ignored issues
–
show
|
|||
| 253 | domain=self._domain, |
||
|
0 ignored issues
–
show
|
|||
| 254 | keywords=self._keywords, |
||
|
0 ignored issues
–
show
|
|||
| 255 | no_wrap=self._no_wrap, |
||
|
0 ignored issues
–
show
|
|||
| 256 | no_location=self._no_location, |
||
|
0 ignored issues
–
show
|
|||
| 257 | xgettext_extra_args=self._xgettext_extra_args, |
||
|
0 ignored issues
–
show
|
|||
| 258 | ) |
||
| 259 | |||
| 260 | if content: |
||
|
0 ignored issues
–
show
|
|||
| 261 | if self._pot_file_path.exists(): |
||
|
0 ignored issues
–
show
|
|||
| 262 | content = strip_translations_header(content) |
||
|
0 ignored issues
–
show
|
|||
| 263 | else: |
||
|
0 ignored issues
–
show
|
|||
| 264 | content = content.replace("charset=CHARSET", "charset=UTF-8") |
||
|
0 ignored issues
–
show
|
|||
| 265 | |||
| 266 | self._write_translations_file( |
||
|
0 ignored issues
–
show
|
|||
| 267 | file_path=self._pot_file_path, |
||
|
0 ignored issues
–
show
|
|||
| 268 | content=content, |
||
|
0 ignored issues
–
show
|
|||
| 269 | mode="a", |
||
|
0 ignored issues
–
show
|
|||
| 270 | ) |
||
| 271 | |||
| 272 | def _ensure_no_duplicates_in_pot_file(self) -> None: |
||
|
0 ignored issues
–
show
|
|||
| 273 | unique_messages = self._extract_unique_messages() |
||
|
0 ignored issues
–
show
|
|||
| 274 | |||
| 275 | self._write_translations_file( |
||
|
0 ignored issues
–
show
|
|||
| 276 | file_path=self._pot_file_path, |
||
|
0 ignored issues
–
show
|
|||
| 277 | content=unique_messages, |
||
|
0 ignored issues
–
show
|
|||
| 278 | mode="w", |
||
|
0 ignored issues
–
show
|
|||
| 279 | ) |
||
| 280 | |||
| 281 | def _extract_unique_messages(self) -> Text: |
||
|
0 ignored issues
–
show
|
|||
| 282 | if self._verbose: |
||
|
0 ignored issues
–
show
|
|||
| 283 | print_out("extracting unique messages from '.pot' file") |
||
|
0 ignored issues
–
show
|
|||
| 284 | |||
| 285 | return extract_unique_messages( |
||
|
0 ignored issues
–
show
|
|||
| 286 | pot_file_path=self._pot_file_path, |
||
|
0 ignored issues
–
show
|
|||
| 287 | no_wrap=self._no_wrap, |
||
|
0 ignored issues
–
show
|
|||
| 288 | no_location=self._no_location, |
||
|
0 ignored issues
–
show
|
|||
| 289 | msguniq_extra_args=self._msguniq_extra_args, |
||
|
0 ignored issues
–
show
|
|||
| 290 | ) |
||
| 291 | |||
| 292 | def _make_all_po_files(self) -> None: |
||
|
0 ignored issues
–
show
|
|||
| 293 | if self._verbose: |
||
|
0 ignored issues
–
show
|
|||
| 294 | print_out(f"making '.po' files") |
||
|
0 ignored issues
–
show
|
|||
| 295 | |||
| 296 | for locale in self._locales: |
||
|
0 ignored issues
–
show
|
|||
| 297 | self._make_po_file_for_locale(locale=locale) |
||
|
0 ignored issues
–
show
|
|||
| 298 | |||
| 299 | def _make_po_file_for_locale(self, locale: Text) -> None: |
||
|
0 ignored issues
–
show
|
|||
| 300 | if self._verbose: |
||
|
0 ignored issues
–
show
|
|||
| 301 | print_out(f"processing locale '{locale}'") |
||
|
0 ignored issues
–
show
|
|||
| 302 | |||
| 303 | po_file_path = make_po_file_path( |
||
|
0 ignored issues
–
show
|
|||
| 304 | locales_dir_path=self._locales_dir_path, |
||
|
0 ignored issues
–
show
|
|||
| 305 | locale=locale, |
||
|
0 ignored issues
–
show
|
|||
| 306 | domain=self._domain, |
||
|
0 ignored issues
–
show
|
|||
| 307 | ) |
||
| 308 | |||
| 309 | ensure_dir_exists(po_file_path.parent) |
||
|
0 ignored issues
–
show
|
|||
| 310 | |||
| 311 | if po_file_path.exists(): |
||
|
0 ignored issues
–
show
|
|||
| 312 | content = self._merge_new_and_existing_translations(po_file_path) |
||
|
0 ignored issues
–
show
|
|||
| 313 | else: |
||
|
0 ignored issues
–
show
|
|||
| 314 | content = self._pot_file_path.read_text(encoding="utf-8") |
||
|
0 ignored issues
–
show
|
|||
| 315 | |||
| 316 | self._write_translations_file( |
||
|
0 ignored issues
–
show
|
|||
| 317 | file_path=po_file_path, |
||
|
0 ignored issues
–
show
|
|||
| 318 | content=content, |
||
|
0 ignored issues
–
show
|
|||
| 319 | mode="w", |
||
|
0 ignored issues
–
show
|
|||
| 320 | ) |
||
| 321 | |||
| 322 | if self._no_obsolete: |
||
|
0 ignored issues
–
show
|
|||
| 323 | self._remove_obsolete_translations(po_file_path) |
||
|
0 ignored issues
–
show
|
|||
| 324 | |||
| 325 | def _merge_new_and_existing_translations(self, po_file_path: Path) -> Text: |
||
|
0 ignored issues
–
show
|
|||
| 326 | if self._verbose: |
||
|
0 ignored issues
–
show
|
|||
| 327 | print_out("merging existing and new messages") |
||
|
0 ignored issues
–
show
|
|||
| 328 | |||
| 329 | return merge_new_and_existing_translations( |
||
|
0 ignored issues
–
show
|
|||
| 330 | po_file_path=po_file_path, |
||
|
0 ignored issues
–
show
|
|||
| 331 | pot_file_path=self._pot_file_path, |
||
|
0 ignored issues
–
show
|
|||
| 332 | no_wrap=self._no_wrap, |
||
|
0 ignored issues
–
show
|
|||
| 333 | no_location=self._no_location, |
||
|
0 ignored issues
–
show
|
|||
| 334 | msgmerge_extra_args=self._msgmerge_extra_args, |
||
|
0 ignored issues
–
show
|
|||
| 335 | ) |
||
| 336 | |||
| 337 | def _remove_obsolete_translations(self, file_path: Path) -> None: |
||
|
0 ignored issues
–
show
|
|||
| 338 | if self._verbose: |
||
|
0 ignored issues
–
show
|
|||
| 339 | print_out("removing obsolete translations") |
||
|
0 ignored issues
–
show
|
|||
| 340 | |||
| 341 | remove_obsolete_translations( |
||
|
0 ignored issues
–
show
|
|||
| 342 | po_file_path=file_path, |
||
|
0 ignored issues
–
show
|
|||
| 343 | no_wrap=self._no_wrap, |
||
|
0 ignored issues
–
show
|
|||
| 344 | no_location=self._no_location, |
||
|
0 ignored issues
–
show
|
|||
| 345 | msgattrib_extra_args=self._msgattrib_extra_args, |
||
|
0 ignored issues
–
show
|
|||
| 346 | ) |
||
| 347 | |||
| 348 | def _write_translations_file( |
||
|
0 ignored issues
–
show
|
|||
| 349 | self, |
||
|
0 ignored issues
–
show
|
|||
| 350 | file_path: Path, |
||
|
0 ignored issues
–
show
|
|||
| 351 | content=Text, |
||
|
0 ignored issues
–
show
|
|||
| 352 | mode=MODE, |
||
|
0 ignored issues
–
show
|
|||
| 353 | ) -> None: |
||
| 354 | |||
| 355 | if self._verbose: |
||
|
0 ignored issues
–
show
|
|||
| 356 | print_out(f"writing to '{stringify_path(file_path)}' file") |
||
|
0 ignored issues
–
show
|
|||
| 357 | |||
| 358 | # Force newlines to '\n' to work around |
||
| 359 | # https://savannah.gnu.org/bugs/index.php?52395 |
||
| 360 | with file_path.open(mode, encoding="utf-8", newline="\n") as f: |
||
|
0 ignored issues
–
show
Variable name "f" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)
This check looks for invalid names for a range of different identifiers. You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements. If your project includes a Pylint configuration file, the settings contained in that file take precedence. To find out more about Pylint, please refer to their site. Loading history...
|
|||
| 361 | f.write(content) |
||
|
0 ignored issues
–
show
|
|||
| 362 | |||
| 363 | def _maybe_remove_pot_file(self) -> None: |
||
|
0 ignored issues
–
show
|
|||
| 364 | if self._pot_file_path.exists(): |
||
|
0 ignored issues
–
show
|
|||
| 365 | if self._verbose: |
||
|
0 ignored issues
–
show
|
|||
| 366 | print_out(f"removing '.pot' file") |
||
|
0 ignored issues
–
show
|
|||
| 367 | |||
| 368 | self._pot_file_path.unlink() |
||
|
0 ignored issues
–
show
|
|||
| 369 | |||
| 370 | |||
| 371 | class ExtractCommand(BaseCommand): |
||
|
0 ignored issues
–
show
|
|||
| 372 | name = "extract" |
||
|
0 ignored issues
–
show
|
|||
| 373 | aliases = ["x", ] |
||
|
0 ignored issues
–
show
|
|||
| 374 | executor_class = ExtractCommandExecutor |
||
|
0 ignored issues
–
show
|
|||
| 375 | |||
| 376 | @classmethod |
||
|
0 ignored issues
–
show
|
|||
| 377 | def make_parser(cls, factory=argparse.ArgumentParser) -> argparse.ArgumentParser: |
||
|
0 ignored issues
–
show
|
|||
| 378 | description = "extract translatable strings from sources into '.po' files" |
||
|
0 ignored issues
–
show
|
|||
| 379 | parser = factory( |
||
|
0 ignored issues
–
show
|
|||
| 380 | prog=cls.name, |
||
|
0 ignored issues
–
show
|
|||
| 381 | description=description, |
||
|
0 ignored issues
–
show
|
|||
| 382 | add_help=True, |
||
|
0 ignored issues
–
show
|
|||
| 383 | help=description, |
||
|
0 ignored issues
–
show
|
|||
| 384 | formatter_class=argparse.ArgumentDefaultsHelpFormatter, |
||
|
0 ignored issues
–
show
|
|||
| 385 | ) |
||
| 386 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 387 | "-d", "--domain", |
||
|
0 ignored issues
–
show
|
|||
| 388 | dest="domain", |
||
|
0 ignored issues
–
show
|
|||
| 389 | default=defaults.DEFAULT_DOMAIN, |
||
|
0 ignored issues
–
show
|
|||
| 390 | help="domain of message files", |
||
|
0 ignored issues
–
show
|
|||
| 391 | ) |
||
| 392 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 393 | "-l", "--locale", |
||
|
0 ignored issues
–
show
|
|||
| 394 | dest="locale", |
||
|
0 ignored issues
–
show
|
|||
| 395 | action="append", |
||
|
0 ignored issues
–
show
|
|||
| 396 | help=( |
||
|
0 ignored issues
–
show
|
|||
| 397 | "create or update '.po' message files for the given locale(s), " |
||
|
0 ignored issues
–
show
|
|||
| 398 | "ex: 'en_US'; can be specified multiple times" |
||
| 399 | ), |
||
| 400 | ) |
||
| 401 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 402 | "-a", "--all", |
||
|
0 ignored issues
–
show
|
|||
| 403 | dest="all", |
||
|
0 ignored issues
–
show
|
|||
| 404 | action="store_true", |
||
|
0 ignored issues
–
show
|
|||
| 405 | default=False, |
||
|
0 ignored issues
–
show
|
|||
| 406 | help="update all '.po' message files for all existing locales", |
||
|
0 ignored issues
–
show
|
|||
| 407 | ) |
||
| 408 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 409 | "-o", "--output-dir", |
||
|
0 ignored issues
–
show
|
|||
| 410 | dest="output_dir", |
||
|
0 ignored issues
–
show
|
|||
| 411 | default=defaults.DEFAULT_LOCALE_DIR_NAME, |
||
|
0 ignored issues
–
show
|
|||
| 412 | help="path to the directory where locales will be stored, a.k.a. 'locale dir'", |
||
|
0 ignored issues
–
show
|
|||
| 413 | ) |
||
| 414 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 415 | "-k", "--keyword", |
||
|
0 ignored issues
–
show
|
|||
| 416 | action="append", |
||
|
0 ignored issues
–
show
|
|||
| 417 | dest="keyword", |
||
|
0 ignored issues
–
show
|
|||
| 418 | help="extra keyword to look for, ex: 'L_'; can be specified multiple times", |
||
|
0 ignored issues
–
show
|
|||
| 419 | ) |
||
| 420 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 421 | "--no-default-keywords", |
||
|
0 ignored issues
–
show
|
|||
| 422 | action="store_true", |
||
|
0 ignored issues
–
show
|
|||
| 423 | dest="no_default_keywords", |
||
|
0 ignored issues
–
show
|
|||
| 424 | default=False, |
||
|
0 ignored issues
–
show
|
|||
| 425 | help=( |
||
|
0 ignored issues
–
show
|
|||
| 426 | "do not use default keywords as {{{:}}}".format( |
||
|
0 ignored issues
–
show
|
|||
| 427 | ", ".join(map(repr, defaults.DEFAULT_KEYWORDS)) |
||
|
0 ignored issues
–
show
|
|||
| 428 | ) |
||
| 429 | ), |
||
| 430 | ) |
||
| 431 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 432 | "-e", "--extension", |
||
|
0 ignored issues
–
show
|
|||
| 433 | dest="extensions", |
||
|
0 ignored issues
–
show
|
|||
| 434 | action="append", |
||
|
0 ignored issues
–
show
|
|||
| 435 | help=( |
||
|
0 ignored issues
–
show
|
|||
| 436 | "extra file extension(s) to scan in addition to '.py'; separate multiple " |
||
|
0 ignored issues
–
show
|
|||
| 437 | "values with commas or specify the parameter multiple times" |
||
| 438 | ), |
||
| 439 | ) |
||
| 440 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 441 | "-s", "--links", |
||
|
0 ignored issues
–
show
|
|||
| 442 | action="store_true", |
||
|
0 ignored issues
–
show
|
|||
| 443 | dest="follow_links", |
||
|
0 ignored issues
–
show
|
|||
| 444 | default=False, |
||
|
0 ignored issues
–
show
|
|||
| 445 | help=( |
||
|
0 ignored issues
–
show
|
|||
| 446 | "follow links to files and directories when scanning sources for " |
||
|
0 ignored issues
–
show
|
|||
| 447 | "translation strings" |
||
| 448 | ), |
||
| 449 | ) |
||
| 450 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 451 | "-i", "--ignore", |
||
|
0 ignored issues
–
show
|
|||
| 452 | action="append", |
||
|
0 ignored issues
–
show
|
|||
| 453 | dest="ignore_patterns", |
||
|
0 ignored issues
–
show
|
|||
| 454 | metavar="PATTERN", |
||
|
0 ignored issues
–
show
|
|||
| 455 | help=( |
||
|
0 ignored issues
–
show
|
|||
| 456 | "extra glob-style patterns for ignoring files or directories; " |
||
|
0 ignored issues
–
show
|
|||
| 457 | "can be specified multiple times" |
||
| 458 | ), |
||
| 459 | ) |
||
| 460 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 461 | "--no-default-ignore", |
||
|
0 ignored issues
–
show
|
|||
| 462 | action="store_true", |
||
|
0 ignored issues
–
show
|
|||
| 463 | dest="no_default_ignore_patterns", |
||
|
0 ignored issues
–
show
|
|||
| 464 | default=False, |
||
|
0 ignored issues
–
show
|
|||
| 465 | help=( |
||
|
0 ignored issues
–
show
|
|||
| 466 | "do not ignore the common glob-style patterns as {{{:}}}".format( |
||
|
0 ignored issues
–
show
|
|||
| 467 | ", ".join(map(repr, defaults.DEFAULT_IGNORE_PATTERNS)) |
||
|
0 ignored issues
–
show
|
|||
| 468 | ) |
||
| 469 | ), |
||
| 470 | ) |
||
| 471 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 472 | "--no-wrap", |
||
|
0 ignored issues
–
show
|
|||
| 473 | action="store_true", |
||
|
0 ignored issues
–
show
|
|||
| 474 | dest="no_wrap", |
||
|
0 ignored issues
–
show
|
|||
| 475 | default=False, |
||
|
0 ignored issues
–
show
|
|||
| 476 | help="do not break long message lines into several lines", |
||
|
0 ignored issues
–
show
|
|||
| 477 | ) |
||
| 478 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 479 | "--no-location", |
||
|
0 ignored issues
–
show
|
|||
| 480 | action="store_true", |
||
|
0 ignored issues
–
show
|
|||
| 481 | dest="no_location", |
||
|
0 ignored issues
–
show
|
|||
| 482 | default=False, |
||
|
0 ignored issues
–
show
|
|||
| 483 | help="do not write location lines, ex: '#: filename:lineno'", |
||
|
0 ignored issues
–
show
|
|||
| 484 | ) |
||
| 485 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 486 | "--no-obsolete", |
||
|
0 ignored issues
–
show
|
|||
| 487 | action="store_true", |
||
|
0 ignored issues
–
show
|
|||
| 488 | dest="no_obsolete", |
||
|
0 ignored issues
–
show
|
|||
| 489 | default=False, |
||
|
0 ignored issues
–
show
|
|||
| 490 | help="remove obsolete message strings", |
||
|
0 ignored issues
–
show
|
|||
| 491 | ) |
||
| 492 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 493 | "--keep-pot", |
||
|
0 ignored issues
–
show
|
|||
| 494 | action="store_true", |
||
|
0 ignored issues
–
show
|
|||
| 495 | dest="keep_pot", |
||
|
0 ignored issues
–
show
|
|||
| 496 | default=False, |
||
|
0 ignored issues
–
show
|
|||
| 497 | help="keep '.pot' file after creating '.po' files (useful for debugging)", |
||
|
0 ignored issues
–
show
|
|||
| 498 | ) |
||
| 499 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 500 | "--xgettext-extra-args", |
||
|
0 ignored issues
–
show
|
|||
| 501 | action="append", |
||
|
0 ignored issues
–
show
|
|||
| 502 | dest="xgettext_extra_args", |
||
|
0 ignored issues
–
show
|
|||
| 503 | help=( |
||
|
0 ignored issues
–
show
|
|||
| 504 | "extra arguments for 'xgettext' utility; " |
||
|
0 ignored issues
–
show
|
|||
| 505 | "can be comma-separated or specified multiple times" |
||
| 506 | ), |
||
| 507 | ) |
||
| 508 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 509 | "--msguniq-extra-args", |
||
|
0 ignored issues
–
show
|
|||
| 510 | action="append", |
||
|
0 ignored issues
–
show
|
|||
| 511 | dest="msguniq_extra_args", |
||
|
0 ignored issues
–
show
|
|||
| 512 | help=( |
||
|
0 ignored issues
–
show
|
|||
| 513 | "extra arguments for 'msguniq' utility; " |
||
|
0 ignored issues
–
show
|
|||
| 514 | "can be comma-separated or specified multiple times" |
||
| 515 | ), |
||
| 516 | ) |
||
| 517 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 518 | "--msgmerge-extra-args", |
||
|
0 ignored issues
–
show
|
|||
| 519 | action="append", |
||
|
0 ignored issues
–
show
|
|||
| 520 | dest="msgmerge_extra_args", |
||
|
0 ignored issues
–
show
|
|||
| 521 | help=( |
||
|
0 ignored issues
–
show
|
|||
| 522 | "extra arguments for 'msgmerge' utility; " |
||
|
0 ignored issues
–
show
|
|||
| 523 | "can be comma-separated or specified multiple times" |
||
| 524 | ), |
||
| 525 | ) |
||
| 526 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 527 | "--msgattrib-extra-args", |
||
|
0 ignored issues
–
show
|
|||
| 528 | action="append", |
||
|
0 ignored issues
–
show
|
|||
| 529 | dest="msgattrib_extra_args", |
||
|
0 ignored issues
–
show
|
|||
| 530 | help=( |
||
|
0 ignored issues
–
show
|
|||
| 531 | "extra arguments for 'msgattrib' utility; " |
||
|
0 ignored issues
–
show
|
|||
| 532 | "can be comma-separated or specified multiple times" |
||
| 533 | ), |
||
| 534 | ) |
||
| 535 | parser.add_argument( |
||
|
0 ignored issues
–
show
|
|||
| 536 | "-v", "--verbose", |
||
|
0 ignored issues
–
show
|
|||
| 537 | action="store_true", |
||
|
0 ignored issues
–
show
|
|||
| 538 | dest="verbose", |
||
|
0 ignored issues
–
show
|
|||
| 539 | default=False, |
||
|
0 ignored issues
–
show
|
|||
| 540 | help="use verbose output", |
||
|
0 ignored issues
–
show
|
|||
| 541 | ) |
||
| 542 | return parser |
||
|
0 ignored issues
–
show
|
|||
| 543 |