File size: 3,818 Bytes
056f521
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import inspect
import json
import os.path
from functools import partial, wraps
from glob import glob
from typing import Dict, List

from pyrogram.enums import ChatType
from pyrogram.types import CallbackQuery, InlineQuery, Message

from Database.mongodb.locale_db import get_db_lang

enabled_locales: List[str] = [
    # "en-GB",  # English (United Kingdom)
    "en-US",  # English (United States)
    # "pt-BR",  # Portuguese (Brazil)
    # "es-ES",  # Spanish
    # "fr-FR",  # French
    # "de-DE",  # German
    # "it-IT",  # Italian
    # "nl-NL",  # Dutch
    # "ar-SA",  # Arabic
    # "ckb-IR",  # Sorani (Kurdish)
    # "fi-FI",  # Finnish
    # "he-IL",  # Hebrew
    "id-ID",  # Indonesian
    "id-JW",  # Javanese
    # "ja-JP",  # Japanese
    # "no-NO",  # Norwegian
    # "pl-PL",  # Polish
    # "pt-BRe",  # Portuguese (Brazil, extended version)
    # "pt-BR2",  # Portuguese (Brazil, informal version)
    # "ro-RO",  # Romanian
    # "ru-RU",  # Russian
    # "sv-SE",  # Swedish
    # "tr-TR",  # Turkish
    # "uk-UA",  # Ukranian
    # "zh-CN",  # Chinese (Simplified)
    # "zh-TW",  # Chinese (Traditional)
]

default_language: str = "en-US"


def cache_localizations(files: List[str]) -> Dict[str, Dict[str, Dict[str, str]]]:
    ldict = {lang: {} for lang in enabled_locales}
    for file in files:
        _, lname, pname = file.split(os.path.sep)
        pname = pname.split(".")[0]
        dic = json.load(open(file, encoding="utf-8"))
        dic.update(ldict[lname].get(pname, {}))
        ldict[lname][pname] = dic
    return ldict


jsons: List[str] = []

for locale in enabled_locales:
    jsons += glob(os.path.join("locales", locale, "*.json"))

langdict = cache_localizations(jsons)


def get_locale_string(
    dic: dict, language: str, default_context: str, key: str, context: str = None
) -> str:
    if context:
        default_context = context
        dic = langdict[language].get(context, langdict[default_language][context])
    res: str = (
        dic.get(key) or langdict[default_language][default_context].get(key) or key
    )
    return res


async def get_lang(message) -> str:
    if isinstance(message, CallbackQuery):
        chat = message.message.chat
    elif isinstance(message, Message):
        chat = message.chat
    elif isinstance(message, InlineQuery):
        chat, chat.type = message.from_user, ChatType.PRIVATE
    else:
        raise TypeError(f"Update type '{message.__name__}' is not supported.")

    lang = await get_db_lang(chat.id)

    if chat.type == ChatType.PRIVATE:
        lang = lang or message.from_user.language_code or default_language
    else:
        lang = lang or default_language
    # User has a language_code without hyphen
    if len(lang.split("-")) == 1:
        # Try to find a language that starts with the provided language_code
        for locale_ in enabled_locales:
            if locale_.startswith(lang):
                lang = locale_
    elif lang.split("-")[1].islower():
        lang = lang.split("-")
        lang[1] = lang[1].upper()
        lang = "-".join(lang)
    return lang if lang in enabled_locales else default_language


def use_chat_lang(context: str = None):
    if not context:
        cwd = os.getcwd()
        frame = inspect.stack()[1]

        fname = frame.filename

        if fname.startswith(cwd):
            fname = fname[len(cwd) + 1 :]
        context = fname.split(os.path.sep)[2].split(".")[0]

    def decorator(func):
        @wraps(func)
        async def wrapper(client, message):
            lang = await get_lang(message)

            dic = langdict.get(lang, langdict[default_language])

            lfunc = partial(get_locale_string, dic.get(context, {}), lang, context)
            return await func(client, message, lfunc)

        return wrapper

    return decorator