1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
#!/usr/bin/env python3
#
# This script checks for duplicate shortcut keys in all translation files.
#
import collections
import os
import sys
from typing import Optional
COLOR_WARNING = '\033[93m'
COLOR_ENDC = '\033[0m'
regex_patter = '(&[\w])' #"&[a-zA-Z0-9]" - Search char '&' and at least one character after it
# Directory where this python file resides
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
class ShortcutKeysChecker:
MSGCTXT = "msgctxt" # Scope of the text . Like : msgctxt "@action:inmenu menubar:help"
MSGID = "msgid" # The id tag, also English text version
MSGSTR = "msgstr" # The translation tag
def has_duplicates(self, filename: str) -> bool:
"""
Checks if the given file has duplicate shortcut keys.
"""
with open(filename, "r", encoding = "utf-8") as f:
all_lines = f.readlines()
all_lines = [l.strip() for l in all_lines]
shortcut_dict = collections.defaultdict(dict)
found_ctxt = False
current_data = dict()
current_field = None
start_line = None
for idx, line in enumerate(all_lines):
if line.startswith(self.MSGCTXT):
found_ctxt = True
current_data.clear()
current_field = self.MSGCTXT
current_data[current_field] = self._fetch_data(line)
start_line = idx
continue
elif found_ctxt and line.startswith(self.MSGID):
current_field = self.MSGID
current_data[current_field] = self._fetch_data(line)
continue
elif found_ctxt and line.startswith(self.MSGSTR):
current_field = self.MSGSTR
current_data[current_field] = self._fetch_data(line)
continue
elif found_ctxt and line.startswith('"'):
data = line[1:-1] # strip the beginning and ending double-quotes
current_data[current_field] += data
continue
if current_data:
self._process_translation(shortcut_dict, current_data, start_line)
current_data.clear()
current_field = None
found_ctxt = False
start_line = None
return self._show_all_duplicates(shortcut_dict, filename)
def _fetch_data(self, line: str) -> str:
return (line.split(" ", 1)[-1])[1:-1]
def _process_translation(self, shortcut_dict: dict, data_dict: dict, start_line: int) -> None:
# Only check the ones with shortcuts
msg = data_dict[self.MSGID]
if data_dict[self.MSGSTR]:
msg = data_dict[self.MSGSTR]
shortcut_key = self._get_shortcut_key(msg)
if shortcut_key is None:
return
msg_section = data_dict[self.MSGCTXT]
keys_dict = shortcut_dict[msg_section]
if shortcut_key not in keys_dict:
keys_dict[shortcut_key] = {"shortcut_key": shortcut_key,
"section": msg_section,
"existing_lines": dict(),
}
existing_data_dict = keys_dict[shortcut_key]["existing_lines"]
existing_data_dict[start_line] = {"message": msg,
}
def _get_shortcut_key(self, text: str) -> Optional[str]:
key = None
if text.count("&") == 1:
idx = text.find("&") + 1
if idx < len(text):
character = text[idx]
if not character.isspace():
key = character.lower()
return key
def _show_all_duplicates(self, shortcut_dict: dict, filename: str) -> bool:
has_duplicates = False
for keys_dict in shortcut_dict.values():
for shortcut_key, data_dict in keys_dict.items():
if len(data_dict["existing_lines"]) == 1:
continue
has_duplicates = True
print("")
print("The following messages have the same shortcut key '%s':" % shortcut_key)
print(" shortcut: '%s'" % data_dict["shortcut_key"])
print(" section : '%s'" % data_dict["section"])
for line, msg in data_dict["existing_lines"].items():
relative_filename = (filename.rsplit("..", 1)[-1])[1:]
print(" - [%s] L%7d : '%s'" % (relative_filename, line, msg["message"]))
return has_duplicates
if __name__ == "__main__":
checker = ShortcutKeysChecker()
all_dirnames = [""]
for _, dirnames, _ in os.walk(os.path.join(SCRIPT_DIR, "..", "resources", "i18n")):
all_dirnames += [dn for dn in dirnames]
break
found_duplicates = False
for dirname in all_dirnames:
file_name = "cura.pot" if not dirname else "cura.po"
file_path = os.path.join(SCRIPT_DIR, "..", "resources", "i18n", dirname, file_name)
found_duplicates = found_duplicates or checker.has_duplicates(file_path)
sys.exit(0 if not found_duplicates else 1)
|