mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-03 20:32:07 -04:00
fix(i18n): capture missing strings and add pt-BR translations (#1654)
This commit is contained in:
@@ -6773,6 +6773,12 @@
|
||||
"reference": "Modules/Settings/DesktopWidgetBrowser.qml:459",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "No widgets added. Click \"Add Widget\" to get started.",
|
||||
"context": "No widgets added. Click \"Add Widget\" to get started.",
|
||||
"reference": "Modules/Settings/DesktopWidgetsTab.qml:603",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "No widgets match your search",
|
||||
"context": "No widgets match your search",
|
||||
|
||||
@@ -1,44 +1,74 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import ast
|
||||
import re
|
||||
import json
|
||||
from pathlib import Path
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
def decode_string_literal(content, quote):
|
||||
try:
|
||||
return ast.literal_eval(f"{quote}{content}{quote}")
|
||||
except (ValueError, SyntaxError):
|
||||
return content
|
||||
|
||||
|
||||
def spans_overlap(a, b):
|
||||
return a[0] < b[1] and b[0] < a[1]
|
||||
|
||||
|
||||
def extract_qstr_strings(root_dir):
|
||||
translations = defaultdict(lambda: {'contexts': set(), 'occurrences': []})
|
||||
qstr_pattern_double = re.compile(r'qsTr\("([^"]+)"\)')
|
||||
qstr_pattern_single = re.compile(r"qsTr\('([^']+)'\)")
|
||||
i18n_pattern_with_context_double = re.compile(r'I18n\.tr\("([^"]+)"\s*,\s*"([^"]+)"\)')
|
||||
i18n_pattern_with_context_single = re.compile(r"I18n\.tr\('([^']+)'\s*,\s*'([^']+)'\)")
|
||||
i18n_pattern_simple_double = re.compile(r'I18n\.tr\("([^"]+)"\)')
|
||||
i18n_pattern_simple_single = re.compile(r"I18n\.tr\('([^']+)'\)")
|
||||
qstr_patterns = [
|
||||
(re.compile(r'qsTr\(\s*"((?:\\.|[^"\\])*)"\s*\)'), '"'),
|
||||
(re.compile(r"qsTr\(\s*'((?:\\.|[^'\\])*)'\s*\)"), "'")
|
||||
]
|
||||
i18n_context_patterns = [
|
||||
(
|
||||
re.compile(r'I18n\.tr\(\s*"((?:\\.|[^"\\])*)"\s*,\s*"((?:\\.|[^"\\])*)"\s*\)'),
|
||||
'"'
|
||||
),
|
||||
(
|
||||
re.compile(r"I18n\.tr\(\s*'((?:\\.|[^'\\])*)'\s*,\s*'((?:\\.|[^'\\])*)'\s*\)"),
|
||||
"'"
|
||||
)
|
||||
]
|
||||
i18n_simple_patterns = [
|
||||
(re.compile(r'I18n\.tr\(\s*"((?:\\.|[^"\\])*)"\s*\)'), '"'),
|
||||
(re.compile(r"I18n\.tr\(\s*'((?:\\.|[^'\\])*)'\s*\)"), "'")
|
||||
]
|
||||
|
||||
for qml_file in Path(root_dir).rglob('*.qml'):
|
||||
relative_path = qml_file.relative_to(root_dir)
|
||||
|
||||
with open(qml_file, 'r', encoding='utf-8') as f:
|
||||
for line_num, line in enumerate(f, 1):
|
||||
qstr_matches = qstr_pattern_double.findall(line) + qstr_pattern_single.findall(line)
|
||||
for match in qstr_matches:
|
||||
translations[match]['occurrences'].append({
|
||||
'file': str(relative_path),
|
||||
'line': line_num
|
||||
})
|
||||
for pattern, quote in qstr_patterns:
|
||||
for match in pattern.finditer(line):
|
||||
term = decode_string_literal(match.group(1), quote)
|
||||
translations[term]['occurrences'].append({
|
||||
'file': str(relative_path),
|
||||
'line': line_num
|
||||
})
|
||||
|
||||
i18n_with_context = i18n_pattern_with_context_double.findall(line) + i18n_pattern_with_context_single.findall(line)
|
||||
for term, context in i18n_with_context:
|
||||
translations[term]['contexts'].add(context)
|
||||
translations[term]['occurrences'].append({
|
||||
'file': str(relative_path),
|
||||
'line': line_num
|
||||
})
|
||||
context_spans = []
|
||||
for pattern, quote in i18n_context_patterns:
|
||||
for match in pattern.finditer(line):
|
||||
term = decode_string_literal(match.group(1), quote)
|
||||
context = decode_string_literal(match.group(2), quote)
|
||||
translations[term]['contexts'].add(context)
|
||||
translations[term]['occurrences'].append({
|
||||
'file': str(relative_path),
|
||||
'line': line_num
|
||||
})
|
||||
context_spans.append(match.span())
|
||||
|
||||
has_context = i18n_pattern_with_context_double.search(line) or i18n_pattern_with_context_single.search(line)
|
||||
if not has_context:
|
||||
i18n_simple = i18n_pattern_simple_double.findall(line) + i18n_pattern_simple_single.findall(line)
|
||||
for match in i18n_simple:
|
||||
translations[match]['occurrences'].append({
|
||||
for pattern, quote in i18n_simple_patterns:
|
||||
for match in pattern.finditer(line):
|
||||
if any(spans_overlap(match.span(), span) for span in context_spans):
|
||||
continue
|
||||
term = decode_string_literal(match.group(1), quote)
|
||||
translations[term]['occurrences'].append({
|
||||
'file': str(relative_path),
|
||||
'line': line_num
|
||||
})
|
||||
|
||||
@@ -3231,6 +3231,9 @@
|
||||
"No variants created. Click Add to create a new monitor widget.": {
|
||||
"No variants created. Click Add to create a new monitor widget.": "Nenhuma variante criada. Clique Adicionar para criar um novo widget de monitor."
|
||||
},
|
||||
"No widgets added. Click \"Add Widget\" to get started.": {
|
||||
"No widgets added. Click \"Add Widget\" to get started.": "Nenhum widget adicionado. Clique em \"Adicionar widget\" para começar."
|
||||
},
|
||||
"No widgets available": {
|
||||
"No widgets available": ""
|
||||
},
|
||||
@@ -3521,7 +3524,7 @@
|
||||
"Make sure KDE Connect or Valent is running on your other devices": ""
|
||||
},
|
||||
"Phone Connect no devices status | bluetooth status": {
|
||||
"No devices": ""
|
||||
"No devices": "Nenhum dispositivo"
|
||||
},
|
||||
"Phone Connect pairing action": {
|
||||
"Device paired": "",
|
||||
@@ -5297,7 +5300,7 @@
|
||||
"Charging": "",
|
||||
"Discharging": "",
|
||||
"Empty": "",
|
||||
"Fully Charged": "",
|
||||
"Fully Charged": "Totalmente carregada",
|
||||
"No Battery": "",
|
||||
"Pending Charge": "",
|
||||
"Pending Discharge": "",
|
||||
@@ -5306,13 +5309,15 @@
|
||||
"bluetooth status": {
|
||||
"Bluetooth": "",
|
||||
"Connected Device": "",
|
||||
"Enabled": "",
|
||||
"Disabled": "Desativado",
|
||||
"Enabled": "Ativado",
|
||||
"No adapter": "",
|
||||
"No adapters": "",
|
||||
"No devices": "Nenhum dispositivo",
|
||||
"Off": ""
|
||||
},
|
||||
"bluetooth status | lock screen notification mode option": {
|
||||
"Disabled": ""
|
||||
"Disabled": "Desativado"
|
||||
},
|
||||
"border color": {
|
||||
"Color": ""
|
||||
@@ -5364,16 +5369,16 @@
|
||||
"Select Wallpaper": "Selecionar Papel de Parede"
|
||||
},
|
||||
"date format option": {
|
||||
"Custom...": "",
|
||||
"Day Date": "",
|
||||
"Day Month Date": "",
|
||||
"Full Day & Month": "",
|
||||
"Full with Year": "",
|
||||
"ISO Date": "",
|
||||
"Month Date": "",
|
||||
"Numeric (D/M)": "",
|
||||
"Numeric (M/D)": "",
|
||||
"System Default": ""
|
||||
"Custom...": "Personalizado...",
|
||||
"Day Date": "Dia e data",
|
||||
"Day Month Date": "Dia, mês e data",
|
||||
"Full Day & Month": "Dia completo e mês",
|
||||
"Full with Year": "Completo com ano",
|
||||
"ISO Date": "Data ISO",
|
||||
"Month Date": "Mês e data",
|
||||
"Numeric (D/M)": "Numérico (D/M)",
|
||||
"Numeric (M/D)": "Numérico (M/D)",
|
||||
"System Default": "Padrão do sistema"
|
||||
},
|
||||
"days": {
|
||||
"days": "dias"
|
||||
@@ -5406,8 +5411,8 @@
|
||||
"dms/outputs config exists but is not included in your compositor config. Display changes won't persist.": ""
|
||||
},
|
||||
"dock indicator style option": {
|
||||
"Circle": "",
|
||||
"Line": ""
|
||||
"Circle": "Círculo",
|
||||
"Line": "Linha"
|
||||
},
|
||||
"dock position option": {
|
||||
"Bottom": "",
|
||||
@@ -5662,15 +5667,15 @@
|
||||
"loginctl not available - lock integration requires DMS socket connection": "loginctl não disponível - integração com bloqueio requer conexão de socket DMS"
|
||||
},
|
||||
"matugen color scheme option": {
|
||||
"Content": "",
|
||||
"Expressive": "",
|
||||
"Fidelity": "",
|
||||
"Fruit Salad": "",
|
||||
"Monochrome": "",
|
||||
"Neutral": "",
|
||||
"Rainbow": "",
|
||||
"Tonal Spot": "",
|
||||
"Vibrant": ""
|
||||
"Content": "Conteúdo",
|
||||
"Expressive": "Expressivo",
|
||||
"Fidelity": "Fidelidade",
|
||||
"Fruit Salad": "Salada de frutas",
|
||||
"Monochrome": "Monocromático",
|
||||
"Neutral": "Neutro",
|
||||
"Rainbow": "Arco-íris",
|
||||
"Tonal Spot": "Ponto tonal",
|
||||
"Vibrant": "Vibrante"
|
||||
},
|
||||
"matugen error": {
|
||||
"matugen not found - install matugen package for dynamic theming": ""
|
||||
@@ -5682,9 +5687,9 @@
|
||||
"Matugen Missing": ""
|
||||
},
|
||||
"media scroll wheel option": {
|
||||
"Change Song": "",
|
||||
"Change Volume": "",
|
||||
"Nothing": ""
|
||||
"Change Song": "Trocar música",
|
||||
"Change Volume": "Alterar volume",
|
||||
"Nothing": "Nada"
|
||||
},
|
||||
"minutes": {
|
||||
"minutes": "minutos"
|
||||
@@ -5792,9 +5797,9 @@
|
||||
"Prioritize performance": ""
|
||||
},
|
||||
"power profile option": {
|
||||
"Balanced": "",
|
||||
"Performance": "",
|
||||
"Power Saver": ""
|
||||
"Balanced": "Equilibrado",
|
||||
"Performance": "Desempenho",
|
||||
"Power Saver": "Economia de energia"
|
||||
},
|
||||
"primary color": {
|
||||
"Primary": ""
|
||||
@@ -5818,14 +5823,14 @@
|
||||
"Color theme from DMS registry": ""
|
||||
},
|
||||
"screen position option": {
|
||||
"Bottom Center": "",
|
||||
"Bottom Left": "",
|
||||
"Bottom Right": "",
|
||||
"Left Center": "",
|
||||
"Right Center": "",
|
||||
"Top Center": "",
|
||||
"Top Left": "",
|
||||
"Top Right": ""
|
||||
"Bottom Center": "Inferior central",
|
||||
"Bottom Left": "Inferior esquerdo",
|
||||
"Bottom Right": "Inferior direito",
|
||||
"Left Center": "Centro esquerdo",
|
||||
"Right Center": "Centro direito",
|
||||
"Top Center": "Superior central",
|
||||
"Top Left": "Superior esquerdo",
|
||||
"Top Right": "Superior direito"
|
||||
},
|
||||
"secondary color": {
|
||||
"Secondary": ""
|
||||
@@ -5872,10 +5877,10 @@
|
||||
"Install color themes from the DMS theme registry": ""
|
||||
},
|
||||
"theme category option": {
|
||||
"Auto": "",
|
||||
"Browse": "",
|
||||
"Custom": "",
|
||||
"Generic": ""
|
||||
"Auto": "Automático",
|
||||
"Browse": "Navegar",
|
||||
"Custom": "Personalizado",
|
||||
"Generic": "Genérico"
|
||||
},
|
||||
"theme installation confirmation": {
|
||||
"Install theme '%1' from the DMS registry?": ""
|
||||
@@ -5924,13 +5929,13 @@
|
||||
"Wallpaper Error": ""
|
||||
},
|
||||
"wallpaper fill mode": {
|
||||
"Fill": "",
|
||||
"Fit": "",
|
||||
"Pad": "",
|
||||
"Stretch": "",
|
||||
"Tile": "",
|
||||
"Tile H": "",
|
||||
"Tile V": ""
|
||||
"Fill": "Preencher",
|
||||
"Fit": "Ajustar",
|
||||
"Pad": "Centralizar",
|
||||
"Stretch": "Esticar",
|
||||
"Tile": "Lado a lado",
|
||||
"Tile H": "Lado a lado (H)",
|
||||
"Tile V": "Lado a lado (V)"
|
||||
},
|
||||
"wallpaper processing error": {
|
||||
"Wallpaper processing failed": ""
|
||||
@@ -5945,15 +5950,15 @@
|
||||
"External Wallpaper Management": "Gerenciamento Externo de Papéis de Parede"
|
||||
},
|
||||
"wallpaper transition option": {
|
||||
"Disc": "",
|
||||
"Fade": "",
|
||||
"Iris Bloom": "",
|
||||
"None": "",
|
||||
"Pixelate": "",
|
||||
"Portal": "",
|
||||
"Random": "",
|
||||
"Stripes": "",
|
||||
"Wipe": ""
|
||||
"Disc": "Disco",
|
||||
"Fade": "Desvanecer",
|
||||
"Iris Bloom": "Íris em expansão",
|
||||
"None": "Nenhum",
|
||||
"Pixelate": "Pixelizar",
|
||||
"Portal": "Portal",
|
||||
"Random": "Aleatório",
|
||||
"Stripes": "Listras",
|
||||
"Wipe": "Deslizar"
|
||||
},
|
||||
"weather feels like temperature": {
|
||||
"Feels Like %1°": ""
|
||||
|
||||
@@ -7902,6 +7902,13 @@
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "No widgets added. Click \"Add Widget\" to get started.",
|
||||
"translation": "",
|
||||
"context": "",
|
||||
"reference": "",
|
||||
"comment": ""
|
||||
},
|
||||
{
|
||||
"term": "No widgets match your search",
|
||||
"translation": "",
|
||||
|
||||
Reference in New Issue
Block a user