Cura/scripts/check_shortcut_keys.py
2018-09-13 10:56:31 +02:00

140 lines
5.0 KiB
Python
Executable File

#!/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)