added permission wrapper

This commit is contained in:
ctih1 2025-07-23 10:19:08 +03:00
parent f7042ed8a7
commit f186e079da
29 changed files with 860 additions and 788 deletions

View file

@ -30,6 +30,8 @@ import time
NOTICE = """
# This file was automatically created from localization JSON files.
# DO NOT EDIT THIS FILE DIRECTLY. If you want to edit a translation, please use the language's JSON file.
#fmt: off
"""
@ -42,10 +44,11 @@ logging.basicConfig(
logger = logging.getLogger("kaannos")
class LanguageCollector:
def __init__(self, language_dir: str) -> None:
self.path: str = language_dir
self.languages: Dict[str, Dict[str,str]] = {}
self.languages: Dict[str, Dict[str, str]] = {}
for file in os.listdir(self.path):
if not file.endswith(".json") or len(file) > 7:
@ -55,13 +58,12 @@ class LanguageCollector:
locale: str = file.split(".json")[0]
logger.info(f"Discovered {file}")
with open(os.path.join(self.path, file), "r", encoding="UTF-8") as f:
keys: Dict[str,str] = json.load(f)
keys: Dict[str, str] = json.load(f)
self.languages[locale] = keys
print(self.languages)
self.find_missing_keys()
def find_missing_keys(self) -> None:
primary_language_keys: Dict[str, str] = self.languages["en"]
@ -69,21 +71,24 @@ class LanguageCollector:
for language in self.languages:
if key not in self.languages[language]:
logger.warning(f"Key {key} missing from {language}")
for language in self.languages:
for key in self.languages[language]:
if key not in primary_language_keys:
logger.warning(f"Leftover key {key} found from {language}")
class Script:
def __init__(self) -> None:
self.script: str = ""
def add_line(self, content, indent: int=0, newline: bool = True) -> None:
def add_line(self, content, indent: int = 0, newline: bool = True) -> None:
self.script += f"{'\t' * indent}{content}{'\n' if newline else ''}"
def process_name(key: str) -> str:
return key.replace(" ", "_").replace(":","").lower()
return key.replace(" ", "_").replace(":", "").lower()
def find_args(string: str) -> List[str]:
variable_open: bool = False
@ -97,7 +102,7 @@ def find_args(string: str) -> List[str]:
variables.append(temp_content)
temp_content = ""
continue
if char == "{":
raise SyntaxError("Variable already open!")
@ -106,17 +111,17 @@ def find_args(string: str) -> List[str]:
else:
if char == "}":
raise SyntaxError("Trying to close a nonexistant variable")
if char == "{":
variable_open = True
return variables
def convert_args(inp: str, vars: List[str], mode: Literal["brackets", "none"] = "brackets") -> str:
replacements = {
".": "_",
",": "_"
}
def convert_args(
inp: str, vars: List[str], mode: Literal["brackets", "none"] = "brackets"
) -> str:
replacements = {".": "_", ",": "_"}
for var in vars:
cleaned_var = var
@ -131,9 +136,15 @@ def convert_args(inp: str, vars: List[str], mode: Literal["brackets", "none"] =
return inp
class GenerateScript:
def __init__(self, primary_lang:str, language_data: Dict[str, Dict[str,str]], use_typing: bool = True, output_path: str = "out.py", generate_comments: bool = True):
def __init__(
self,
primary_lang: str,
language_data: Dict[str, Dict[str, str]],
use_typing: bool = True,
output_path: str = "out.py",
generate_comments: bool = True,
):
self.data = language_data
self.primary = primary_lang
self.script = Script()
@ -142,31 +153,41 @@ class GenerateScript:
self.generate_comments = generate_comments
def create(self):
# I really don't like this implementation but also it works
# I really don't like this implementation but also it works
self.script.add_line(NOTICE)
if self.uses_typing:
self.script.add_line("from typing import Literal, List")
self.script.add_line(f"Language=Literal{list(self.data.keys())}")
self.script.add_line(f"languages: List[Language] = {list(self.data.keys())}")
self.script.add_line(
f"languages: List[Language] = {list(self.data.keys())}"
)
self.script.add_line(f"default_lang: Language | str='{self.primary}'")
self.script.add_line("def change_language(new_lang: Language | str) -> None: global default_lang; default_lang = new_lang")
self.script.add_line(
"def change_language(new_lang: Language | str) -> None: global default_lang; default_lang = new_lang"
)
else:
self.script.add_line(f"languages = {list(self.data.keys())}")
self.script.add_line(f"default_lang='{self.primary}'")
self.script.add_line("def change_language(new_lang): global default_lang; default_lang = new_lang")
self.script.add_line(
"def change_language(new_lang): global default_lang; default_lang = new_lang"
)
self.primary_data = self.data[self.primary]
for key in self.primary_data:
args = find_args(self.primary_data[key])
self.script.add_line(f"def {process_name(key)}({convert_args(','.join([*args, "lang:str|None=None" if self.uses_typing else "lang"]), args, "none")}):")
self.script.add_line(
f"def {process_name(key)}({convert_args(','.join([*args, "lang:str|None=None" if self.uses_typing else "lang"]), args, "none")}):"
)
if self.generate_comments:
self.script.add_line('"""', 1)
self.script.add_line("### Locales", 1)
for language in self.data:
self.script.add_line(f'- {language.capitalize()}: **{self.data[language].get(key, self.primary_data[key])}**', 1)
self.script.add_line(
f"- {language.capitalize()}: **{self.data[language].get(key, self.primary_data[key])}**",
1,
)
self.script.add_line('"""', 1)
self.script.add_line("if not lang: lang=default_lang", 1)
for language in self.data:
@ -174,18 +195,31 @@ class GenerateScript:
for arg in args:
formatted_map += f'"{convert_args(arg, args, "none")}": {convert_args(arg, args, "none")},'
formatted_map = formatted_map[:-1] + "}"
self.script.add_line(f"""if lang == '{language}': return {convert_args(json.dumps(
self.script.add_line(
f"""if lang == '{language}': return {convert_args(json.dumps(
self.data[language].get(key,self.primary_data[key]),
ensure_ascii=False
), args)}{f'.format_map({formatted_map})' if len(args) > 0 else ''}""", 1)
), args)}{f'.format_map({formatted_map})' if len(args) > 0 else ''}""",
1,
)
self.script.add_line("else: raise ValueError(f'Invalid language {lang}')", 1)
self.script.add_line(
"else: raise ValueError(f'Invalid language {lang}')", 1
)
with open(self.output, "w", encoding="UTF-8") as f:
f.write(self.script.script)
def build_result(primary_lang: str, locale_dir: str, types: bool, output_path: str, generate_comments: bool = True):
def build_result(
primary_lang: str,
locale_dir: str,
types: bool,
output_path: str,
generate_comments: bool = True,
):
start = time.time()
lc = LanguageCollector(locale_dir)
GenerateScript(primary_lang, lc.languages, types, output_path, generate_comments).create()
logger.info(f"Done in {time.time() - start}s")
GenerateScript(
primary_lang, lc.languages, types, output_path, generate_comments
).create()
logger.info(f"Done in {time.time() - start}s")