def load_lang(lang, apps=None): """Combine all translations from `.csv` files in all `apps`. For derivative languages (es-GT), take translations from the base language (es) and then update translations from the child (es-GT)""" if lang == 'en': return {} out = dataent.cache().hget("lang_full_dict", lang, shared=True) if not out: out = {} for app in (apps or dataent.get_all_apps(True)): path = os.path.join(dataent.get_pymodule_path(app), "translations", lang + ".csv") out.update(get_translation_dict_from_file(path, lang, app) or {}) if '-' in lang: parent = lang.split('-')[0] parent_out = load_lang(parent) parent_out.update(out) out = parent_out dataent.cache().hset("lang_full_dict", lang, out, shared=True) return out or {}
def update_translations(lang, untranslated_file, translated_file): """Update translations from a source and target file for a given language. :param lang: Language code (e.g. `en`). :param untranslated_file: File path with the messages in English. :param translated_file: File path with messages in language to be updated.""" clear_cache() full_dict = get_full_dict(lang) def restore_newlines(s): return (s.replace("|||||", "\\\n").replace("| | | | |", "\\\n").replace( "||||", "\\n").replace("| | | |", "\\n").replace( "|||", "\n").replace("| | |", "\n")) translation_dict = {} for key, value in zip( dataent.get_file_items(untranslated_file, ignore_empty_lines=False), dataent.get_file_items(translated_file, ignore_empty_lines=False)): # undo hack in get_untranslated translation_dict[restore_newlines(key)] = restore_newlines(value) full_dict.update(translation_dict) for app in dataent.get_all_apps(True): write_translations_file(app, lang, full_dict)
def make_asset_dirs(make_copy=False, restore=False): # don't even think of making assets_path absolute - rm -rf ahead. assets_path = os.path.join(dataent.local.sites_path, "assets") for dir_path in [ os.path.join(assets_path, 'js'), os.path.join(assets_path, 'css') ]: if not os.path.exists(dir_path): os.makedirs(dir_path) # symlink app/public > assets/app for app_name in dataent.get_all_apps(True): pymodule = dataent.get_module(app_name) app_base_path = os.path.abspath(os.path.dirname(pymodule.__file__)) symlinks = [] symlinks.append([ os.path.join(app_base_path, 'public'), os.path.join(assets_path, app_name) ]) app_doc_path = None if os.path.isdir(os.path.join(app_base_path, 'docs')): app_doc_path = os.path.join(app_base_path, 'docs') elif os.path.isdir(os.path.join(app_base_path, 'www', 'docs')): app_doc_path = os.path.join(app_base_path, 'www', 'docs') if app_doc_path: symlinks.append( [app_doc_path, os.path.join(assets_path, app_name + '_docs')]) for source, target in symlinks: source = os.path.abspath(source) if os.path.exists(source): if restore: if os.path.exists(target): if os.path.islink(target): os.unlink(target) else: shutil.rmtree(target) shutil.copytree(source, target) elif make_copy: if os.path.exists(target): warnings.warn('Target {target} already exists.'.format( target=target)) else: shutil.copytree(source, target) else: if os.path.exists(target): if os.path.islink(target): os.unlink(target) else: shutil.rmtree(target) os.symlink(source, target) else: # warnings.warn('Source {source} does not exist.'.format(source = source)) pass
def import_translations(lang, path): """Import translations from file in standard format""" clear_cache() full_dict = get_full_dict(lang) full_dict.update(get_translation_dict_from_file(path, lang, 'import')) for app in dataent.get_all_apps(True): write_translations_file(app, lang, full_dict)
def setup(): global app_paths pymodules = [] for app in dataent.get_all_apps(True): try: pymodules.append(dataent.get_module(app)) except ImportError: pass app_paths = [os.path.dirname(pymodule.__file__) for pymodule in pymodules]
def get_version(): "Show the versions of all the installed apps" from dataent.utils.change_log import get_app_branch dataent.init('') for m in sorted(dataent.get_all_apps()): branch_name = get_app_branch(m) module = dataent.get_module(m) app_hooks = dataent.get_module(m + ".hooks") if hasattr(app_hooks, '{0}_version'.format(branch_name)): print("{0} {1}".format( m, getattr(app_hooks, '{0}_version'.format(branch_name)))) elif hasattr(module, "__version__"): print("{0} {1}".format(m, module.__version__))
def export_translations(): # ssh -p 9999 [email protected] "cd /home/dataent/dataent-bench/apps/dataent && git diff" | patch -p1 for lang in get_all_languages(): if lang!="en": print("exporting " + lang) edited = dict(dataent.db.sql("""select source, translated from `tabTranslated Message` where language=%s""", lang)) for app in dataent.get_all_apps(True): path = os.path.join(dataent.get_app_path(app, "translations", lang + ".csv")) if os.path.exists(path): # only update existing strings current = dict(read_csv_file(path)) for key in current: current[key] = edited.get(key) or current[key] write_translations_file(app, lang, current, sorted(list(current)))
def get_untranslated(lang, untranslated_file, get_all=False): """Returns all untranslated strings for a language and writes in a file :param lang: Language code. :param untranslated_file: Output file path. :param get_all: Return all strings, translated or not.""" clear_cache() apps = dataent.get_all_apps(True) messages = [] untranslated = [] for app in apps: messages.extend(get_messages_for_app(app)) messages = deduplicate_messages(messages) def escape_newlines(s): return (s.replace("\\\n", "|||||").replace("\\n", "||||").replace("\n", "|||")) if get_all: print(str(len(messages)) + " messages") with open(untranslated_file, "w") as f: for m in messages: # replace \n with ||| so that internal linebreaks don't get split f.write((escape_newlines(m[1]) + os.linesep).encode("utf-8")) else: full_dict = get_full_dict(lang) for m in messages: if not full_dict.get(m[1]): untranslated.append(m[1]) if untranslated: print( str(len(untranslated)) + " missing translations of " + str(len(messages))) with open(untranslated_file, "w") as f: for m in untranslated: # replace \n with ||| so that internal linebreaks don't get split f.write((escape_newlines(m) + os.linesep).encode("utf-8")) else: print("all translated!")
def get_apps(): return dataent.get_all_apps(with_internal_apps=False, sites_path='.')
def install_app(name, verbose=False, set_as_patched=True): dataent.flags.in_install = name dataent.flags.ignore_in_install = False dataent.clear_cache() app_hooks = dataent.get_hooks(app_name=name) installed_apps = dataent.get_installed_apps() # install pre-requisites if app_hooks.required_apps: for app in app_hooks.required_apps: install_app(app) dataent.flags.in_install = name dataent.clear_cache() if name not in dataent.get_all_apps(): raise Exception("App not in apps.txt") if name in installed_apps: dataent.msgprint(_("App {0} already installed").format(name)) return print("\nInstalling {0}...".format(name)) if name != "dataent": dataent.only_for("System Manager") for before_install in app_hooks.before_install or []: out = dataent.get_attr(before_install)() if out == False: return if name != "dataent": add_module_defs(name) sync_for(name, force=True, sync_everything=True, verbose=verbose, reset_permissions=True) sync_from_app(name) add_to_installed_apps(name) dataent.get_doc('Portal Settings', 'Portal Settings').sync_menu() if set_as_patched: set_all_patches_as_completed(name) for after_install in app_hooks.after_install or []: dataent.get_attr(after_install)() sync_fixtures(name) sync_customizations(name) for after_sync in app_hooks.after_sync or []: dataent.get_attr(after_sync)() # dataent.flags.in_install = False
def rebuild_all_translation_files(): """Rebuild all translation files: `[app]/translations/[lang].csv`.""" for lang in get_all_languages(): for app in dataent.get_all_apps(): write_translations_file(app, lang)