From 61239ae8222561a296ff01a4d9d98b61944c47ee Mon Sep 17 00:00:00 2001 From: Xavier Jouslin de Noray <xavier.jouslindenoray@savoirfairelinux.com> Date: Thu, 17 Aug 2023 17:32:37 -0400 Subject: [PATCH] Manifest: add parser to get the good translation for plugin description Change-Id: Ice250eba3a638f8eae52a14edc7a68d7e08597cf --- src/plugin/jamipluginmanager.cpp | 4 +- src/plugin/pluginpreferencesutils.cpp | 90 +------------------ src/plugin/pluginpreferencesutils.h | 18 ---- src/plugin/pluginsutils.cpp | 125 +++++++++++++++++++++++++- src/plugin/pluginsutils.h | 34 ++++++- test/unitTest/plugins/TestSuite.jpl | Bin 423270 -> 422979 bytes test/unitTest/plugins/plugins.cpp | 4 +- 7 files changed, 163 insertions(+), 112 deletions(-) diff --git a/src/plugin/jamipluginmanager.cpp b/src/plugin/jamipluginmanager.cpp index f25c5e9bbc..73d3ac0e4c 100644 --- a/src/plugin/jamipluginmanager.cpp +++ b/src/plugin/jamipluginmanager.cpp @@ -76,7 +76,7 @@ JamiPluginManager::getPluginDetails(const std::string& rootPath) } std::map<std::string, std::string> details = PluginUtils::parseManifestFile( - PluginUtils::manifestPath(rootPath)); + PluginUtils::manifestPath(rootPath), rootPath); if (!details.empty()) { auto itIcon = details.find("iconPath"); itIcon->second.insert(0, rootPath + DIR_SEPARATOR_CH + "data" + DIR_SEPARATOR_CH); @@ -231,7 +231,7 @@ JamiPluginManager::installPlugin(const std::string& jplPath, bool force) + DIR_SEPARATOR_CH + name}; // Find if there is an existing version of this plugin const auto alreadyInstalledManifestMap = PluginUtils::parseManifestFile( - PluginUtils::manifestPath(destinationDir)); + PluginUtils::manifestPath(destinationDir), destinationDir); if (!alreadyInstalledManifestMap.empty()) { if (force) { diff --git a/src/plugin/pluginpreferencesutils.cpp b/src/plugin/pluginpreferencesutils.cpp index 237d0567d5..a60a9cef8b 100644 --- a/src/plugin/pluginpreferencesutils.cpp +++ b/src/plugin/pluginpreferencesutils.cpp @@ -20,6 +20,7 @@ */ #include "pluginpreferencesutils.h" +#include "pluginsutils.h" #include <msgpack.hpp> #include <sstream> @@ -60,51 +61,6 @@ PluginPreferencesUtils::getAllowDenyListsPath() + "allowdeny.msgpack"; } -std::map<std::string, std::string> -PluginPreferencesUtils::processLocaleFile(const std::string& preferenceLocaleFilePath) -{ - if (!fileutils::isFile(preferenceLocaleFilePath)) { - return {}; - } - std::ifstream file(preferenceLocaleFilePath); - Json::Value root; - Json::CharReaderBuilder rbuilder; - rbuilder["collectComments"] = false; - std::string errs; - std::map<std::string, std::string> locales {}; - if (file) { - // Read the file to a json format - if (Json::parseFromStream(rbuilder, file, &root, &errs)) { - auto keys = root.getMemberNames(); - for (const auto& key : keys) { - locales[key] = root.get(key, "").asString(); - } - } - } - return locales; -} - -std::map<std::string, std::string> -PluginPreferencesUtils::getLocales(const std::string& rootPath, const std::string& lang) -{ - auto pluginName = rootPath.substr(rootPath.find_last_of(DIR_SEPARATOR_CH) + 1); - auto basePath = fmt::format("{}/data/locale/{}", rootPath, pluginName + "_"); - - std::map<std::string, std::string> locales = {}; - - // Get language translations - if (!lang.empty()) { - locales = processLocaleFile(basePath + lang + ".json"); - } - - // Get default english values if no translations were found - if (locales.empty()) { - locales = processLocaleFile(basePath + "en.json"); - } - - return locales; -} - std::string PluginPreferencesUtils::convertArrayToString(const Json::Value& jsonArray) { @@ -159,48 +115,8 @@ PluginPreferencesUtils::getPreferences(const std::string& rootPath, const std::s std::vector<std::map<std::string, std::string>> preferences; if (file) { // Get preferences locale - std::string lang; - if (auto envLang = std::getenv("JAMI_LANG")) - lang = envLang; - else - JAMI_INFO() << "Error getting JAMI_LANG env, trying to get system language"; - // If language preference is empty, try to get from the system. - if (lang.empty()) { -#ifdef WIN32 - WCHAR localeBuffer[LOCALE_NAME_MAX_LENGTH]; - if (GetUserDefaultLocaleName(localeBuffer, LOCALE_NAME_MAX_LENGTH) != 0) { - char utf8Buffer[LOCALE_NAME_MAX_LENGTH] {}; - WideCharToMultiByte(CP_UTF8, - 0, - localeBuffer, - LOCALE_NAME_MAX_LENGTH, - utf8Buffer, - LOCALE_NAME_MAX_LENGTH, - nullptr, - nullptr); - - lang.append(utf8Buffer); - string_replace(lang, "-", "_"); - } - // Even though we default to the system variable in windows, technically this - // part of the code should not be reached because the client-qt must define that - // variable and we cannot run the client and the daemon in diferent processes in Windows. -#else - // The same way described in the comment just above, the android should not reach this - // part of the code given the client-android must define "JAMI_LANG" system variable. - // And even if this part is reached, it should not work since std::locale is not - // supported by the NDK. - - // LC_COLLATE is used to grab the locale for the case when the system user has set different - // values for the preferred Language and Format. - lang = setlocale(LC_COLLATE, ""); - // We set the environment to avoid checking from system everytime. - // This is the case when running daemon and client in different processes - // like with dbus. - setenv("JAMI_LANG", lang.c_str(), 1); -#endif // WIN32 - } - auto locales = getLocales(rootPath, std::string(string_remove_suffix(lang, '.'))); + const auto& lang = PluginUtils::getLanguage(); + auto locales = PluginUtils::getLocales(rootPath, std::string(string_remove_suffix(lang, '.'))); // Read the file to a json format bool ok = Json::parseFromStream(rbuilder, file, &root, &errs); diff --git a/src/plugin/pluginpreferencesutils.h b/src/plugin/pluginpreferencesutils.h index 559a3f0c9b..7980a1d7f1 100644 --- a/src/plugin/pluginpreferencesutils.h +++ b/src/plugin/pluginpreferencesutils.h @@ -67,24 +67,6 @@ public: */ static std::string getAllowDenyListsPath(); - /** - * @brief Returns the available keys and translations for a given file. - * If the locale is not available, return empty map. - * @param localeFilePath - * @return locales map - */ - static std::map<std::string, std::string> processLocaleFile(const std::string& localeFilePath); - - /** - * @brief Returns the available keys and translations for a given plugin. - * If the locale is not available, return the english default. - * @param rootPath - * @param lang - * @return locales map - */ - static std::map<std::string, std::string> getLocales(const std::string& rootPath, - const std::string& lang); - /** * @brief Returns a colon separated string with values from a json::Value containing an array. * @param jsonArray diff --git a/src/plugin/pluginsutils.cpp b/src/plugin/pluginsutils.cpp index b5eb85bc77..a40d21df44 100644 --- a/src/plugin/pluginsutils.cpp +++ b/src/plugin/pluginsutils.cpp @@ -142,13 +142,14 @@ checkManifestValidity(const std::vector<uint8_t>& vec) } std::map<std::string, std::string> -parseManifestFile(const std::string& manifestFilePath) +parseManifestFile(const std::string& manifestFilePath, const std::string& rootPath) { std::lock_guard<std::mutex> guard(fileutils::getFileLock(manifestFilePath)); std::ifstream file(manifestFilePath); if (file) { try { - return checkManifestValidity(file); + const auto& traduction = parseManifestTranslation(rootPath, file); + return checkManifestValidity(std::vector<uint8_t>(traduction.begin(), traduction.end())); } catch (const std::exception& e) { JAMI_ERR() << e.what(); } @@ -156,10 +157,36 @@ parseManifestFile(const std::string& manifestFilePath) return {}; } +std::string +parseManifestTranslation(const std::string& rootPath, std::ifstream& manifestFile) +{ + if (manifestFile) { + std::stringstream buffer; + buffer << manifestFile.rdbuf(); + std::string manifest = buffer.str(); + const auto& translation = getLocales(rootPath, getLanguage()); + std::regex pattern(R"(\{\{([^}]+)\}\})"); + std::smatch matches; + // replace the pattern to the correct translation + while (std::regex_search(manifest, matches, pattern)) { + if (matches.size() == 2) { + auto it = translation.find(matches[1].str()); + if (it == translation.end()) { + manifest = std::regex_replace(manifest, pattern, ""); + continue; + } + manifest = std::regex_replace(manifest, pattern, it->second, std::regex_constants::format_first_only); + } + } + return manifest; + } + return {}; +} + bool checkPluginValidity(const std::string& rootPath) { - return !parseManifestFile(manifestPath(rootPath)).empty(); + return !parseManifestFile(manifestPath(rootPath), rootPath).empty(); } std::map<std::string, std::string> @@ -240,5 +267,97 @@ uncompressJplFunction(std::string_view relativeFileName) } return std::make_pair(true, relativeFileName); } + +std::string +getLanguage() +{ + std::string lang; + if (auto envLang = std::getenv("JAMI_LANG")) + lang = envLang; + else + JAMI_INFO() << "Error getting JAMI_LANG env, trying to get system language"; + // If language preference is empty, try to get from the system. + if (lang.empty()) { +#ifdef WIN32 + WCHAR localeBuffer[LOCALE_NAME_MAX_LENGTH]; + if (GetUserDefaultLocaleName(localeBuffer, LOCALE_NAME_MAX_LENGTH) != 0) { + char utf8Buffer[LOCALE_NAME_MAX_LENGTH] {}; + WideCharToMultiByte(CP_UTF8, + 0, + localeBuffer, + LOCALE_NAME_MAX_LENGTH, + utf8Buffer, + LOCALE_NAME_MAX_LENGTH, + nullptr, + nullptr); + + lang.append(utf8Buffer); + string_replace(lang, "-", "_"); + } + // Even though we default to the system variable in windows, technically this + // part of the code should not be reached because the client-qt must define that + // variable and we cannot run the client and the daemon in diferent processes in Windows. +#else + // The same way described in the comment just above, the android should not reach this + // part of the code given the client-android must define "JAMI_LANG" system variable. + // And even if this part is reached, it should not work since std::locale is not + // supported by the NDK. + + // LC_COLLATE is used to grab the locale for the case when the system user has set different + // values for the preferred Language and Format. + lang = setlocale(LC_COLLATE, ""); + // We set the environment to avoid checking from system everytime. + // This is the case when running daemon and client in different processes + // like with dbus. + setenv("JAMI_LANG", lang.c_str(), 1); +#endif // WIN32 + } + return lang; +} + +std::map<std::string, std::string> +getLocales(const std::string& rootPath, const std::string& lang) +{ + auto pluginName = rootPath.substr(rootPath.find_last_of(DIR_SEPARATOR_CH) + 1); + auto basePath = fmt::format("{}/data/locale/{}", rootPath, pluginName + "_"); + + std::map<std::string, std::string> locales = {}; + + // Get language translations + if (!lang.empty()) { + locales = processLocaleFile(basePath + lang + ".json"); + } + + // Get default english values if no translations were found + if (locales.empty()) { + locales = processLocaleFile(basePath + "en.json"); + } + + return locales; +} + +std::map<std::string, std::string> +processLocaleFile(const std::string& preferenceLocaleFilePath) +{ + if (!fileutils::isFile(preferenceLocaleFilePath)) { + return {}; + } + std::ifstream file(preferenceLocaleFilePath); + Json::Value root; + Json::CharReaderBuilder rbuilder; + rbuilder["collectComments"] = false; + std::string errs; + std::map<std::string, std::string> locales {}; + if (file) { + // Read the file to a json format + if (Json::parseFromStream(rbuilder, file, &root, &errs)) { + auto keys = root.getMemberNames(); + for (const auto& key : keys) { + locales[key] = root.get(key, "").asString(); + } + } + } + return locales; +} } // namespace PluginUtils } // namespace jami diff --git a/src/plugin/pluginsutils.h b/src/plugin/pluginsutils.h index adccd201bd..f5df57757b 100644 --- a/src/plugin/pluginsutils.h +++ b/src/plugin/pluginsutils.h @@ -81,7 +81,15 @@ std::map<std::string, std::string> checkManifestValidity(const std::vector<uint8 * @param manifestFilePath * @return Map with manifest contents */ -std::map<std::string, std::string> parseManifestFile(const std::string& manifestFilePath); +std::map<std::string, std::string> parseManifestFile(const std::string& manifestFilePath, const std::string& rootPath); + +/** + * @brief Parses the manifest file of an installed plugin if it's valid. + * @param rootPath + * @param manifestFile + * @return Map with manifest contents + */ +std::string parseManifestTranslation(const std::string& rootPath, std::ifstream& manifestFile); /** * @brief Validates a plugin based on its manifest.json file. @@ -134,5 +142,29 @@ std::vector<uint8_t> readSignatureFileFromArchive(const std::string& jplPath); * @return Pair <bool, string> meaning if file should be extracted and where to. */ std::pair<bool, std::string_view> uncompressJplFunction(std::string_view relativeFileName); + +/** + * @brief Returns the language of the current locale. + * @return language + */ +std::string getLanguage(); + +/** + * @brief Returns the available keys and translations for a given plugin. + * If the locale is not available, return the english default. + * @param rootPath + * @param lang + * @return locales map + */ +std::map<std::string, std::string> getLocales(const std::string& rootPath, + const std::string& lang); + +/** + * @brief Returns the available keys and translations for a given file. + * If the locale is not available, return empty map. + * @param localeFilePath + * @return locales map + */ +std::map<std::string, std::string> processLocaleFile(const std::string& localeFilePath); } // namespace PluginUtils } // namespace jami diff --git a/test/unitTest/plugins/TestSuite.jpl b/test/unitTest/plugins/TestSuite.jpl index 18efdf05ed865b418e7ac3b76b23b619b0dbe697..477a6d683f9dd2bd14b3bf038a4493e887bcbc7f 100644 GIT binary patch delta 3271 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 b1nk>+6CO`@C}or3GG%69_));dz`y_iIN*xY delta 3557 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 Xo0gvGvL$RXTyL2e7?O+F7#J7;Z~4R6 diff --git a/test/unitTest/plugins/plugins.cpp b/test/unitTest/plugins/plugins.cpp index ece8f596db..8ccf47b448 100644 --- a/test/unitTest/plugins/plugins.cpp +++ b/test/unitTest/plugins/plugins.cpp @@ -507,18 +507,20 @@ PluginsTest::testTranslations() Manager::instance().pluginPreferences.setPluginsEnabled(true); setenv("JAMI_LANG", "en", true); Manager::instance().getJamiPluginManager().installPlugin(jplPath_, true); - auto preferences = Manager::instance().getJamiPluginManager().getPluginPreferences(installationPath_, ""); CPPUNIT_ASSERT(!preferences.empty()); auto preferencesValuesEN = Manager::instance().getJamiPluginManager().getPluginPreferencesValuesMap(installationPath_, ""); + auto detailsValuesEN = Manager::instance().getJamiPluginManager().getPluginDetails(installationPath_); setenv("JAMI_LANG", "fr", true); CPPUNIT_ASSERT(Manager::instance().getJamiPluginManager().getPluginPreferencesValuesMap(installationPath_, "") != preferencesValuesEN); + CPPUNIT_ASSERT(Manager::instance().getJamiPluginManager().getPluginDetails(installationPath_) != detailsValuesEN); setenv("JAMI_LANG", "en", true); CPPUNIT_ASSERT(Manager::instance().getJamiPluginManager().getPluginPreferencesValuesMap(installationPath_, "") == preferencesValuesEN); + CPPUNIT_ASSERT(Manager::instance().getJamiPluginManager().getPluginDetails(installationPath_) == detailsValuesEN); CPPUNIT_ASSERT(!Manager::instance().getJamiPluginManager().uninstallPlugin(installationPath_)); } -- GitLab