Offline Website Translation in real time, made by yingshaoxo

Javascript: 

import * as language_dict from './assets/language_dict.json';

let is_cn_broswer = ():boolean => {
    let language = window.navigator.language;
    if (language.startsWith("zh-")) {
        return true;
    }
    return false;
}

let translate_the_page = async () => {
    // console.log(language_dict)

    var all = document.getElementsByTagName("*");

    for (var i=0, max=all.length; i < max; i++) {
        let one_element = all[i]
        if (one_element?.textContent) {
            if (one_element.textContent in language_dict) {
                one_element.childNodes.forEach((node, index) => {
                    if (node.nodeValue == one_element.textContent) {
                        node.nodeValue = language_dict[one_element.textContent]['cn']
                    }
                })
            }
        }
    }
}

if (is_cn_broswer()) {
    translate_the_page()

    // do the translation when html change
    const config = { attributes: true, childList: true, subtree: true };

    // Callback function to execute when mutations are observed
    const callback = (mutationList, observer) => {
        translate_the_page()
    };

    // Create an observer instance linked to the callback function
    const observer = new MutationObserver(callback);

    // Start observing the target node for configured mutations
    observer.observe(document, config);
}

Python:

    def generate_translation_json_file(self):
        # pip install translators
        import translators as ts

        folders_for_string_search = [
            disk.join_paths(self.real_project_root_folder, "frontend/src"),
            disk.join_paths(self.real_project_root_folder, "backend/style_shop_backend")
        ]
        files = []
        for folder in folders_for_string_search:
            files += disk.get_files(folder=folder, type_limiter=[".vue", ".ts", ".py"])

        txt = ""
        for file in files:
            txt += io_.read(file) + "\n\n"

        result_list = []
        result_list += re.findall(r"'.*'", txt, re.DOTALL)
        result_list += re.findall(r'".*"', txt, re.DOTALL)
        result_list += re.findall(r'>.*<', txt, re.DOTALL)

        new_result_list = []
        for each in result_list:
            new_result_list += [one for one in re.findall(r"[\w ]+", each, re.DOTALL) if one.strip() != ""]

        new_result_list = [one.replace("_", " ").strip() for one in new_result_list if not one.strip().startswith('_')]
        new_result_list = [one for one in new_result_list if not all([char.isnumeric() for char in one])]
        new_result_list = [one for one in new_result_list if one.strip() != ""]
        new_result_list = list(set(new_result_list))

        target_json_file = disk.join_paths(self.real_project_root_folder, "frontend/src/assets", "language_dict.json")
        json_object = {
            "": {
                "en": "",
                "cn": "",
            },
            "Style Shop": {
                "en": "Style Shop",
                "cn": "多彩商城",
            }
        }
        try:
            source_json_text = io_.read(target_json_file)
            json_object.update(json.loads(source_json_text))
        except Exception as e:
            pass

        for old in new_result_list:
            if old not in json_object.keys():
                new = ts.translate_text(query_text=old, from_language="en", to_language="zh", translator="google")
                json_object[old] = {
                    "en": old,
                    "cn": new
                }
                io_.write(target_json_file, json.dumps(json_object, indent=4, sort_keys=True))
                sleep(1)