mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 21:37:17 +01:00
Support multilang, update code
Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
parent
0e68fe4a57
commit
80b44fc9a9
|
@ -103,6 +103,9 @@ port = 7070
|
||||||
# auth = true
|
# auth = true
|
||||||
# user = i2pd
|
# user = i2pd
|
||||||
# pass = changeme
|
# pass = changeme
|
||||||
|
## Select webconsole language
|
||||||
|
## Currently supported only english (default) and russian languages
|
||||||
|
# lang = english
|
||||||
|
|
||||||
[httpproxy]
|
[httpproxy]
|
||||||
## Uncomment and set to 'false' to disable HTTP Proxy
|
## Uncomment and set to 'false' to disable HTTP Proxy
|
||||||
|
|
|
@ -343,6 +343,13 @@ namespace util
|
||||||
LogPrint(eLogInfo, "Daemon: using hidden mode");
|
LogPrint(eLogInfo, "Daemon: using hidden mode");
|
||||||
i2p::data::netdb.SetHidden(true);
|
i2p::data::netdb.SetHidden(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string httpLang; i2p::config::GetOption("http.lang", httpLang);
|
||||||
|
if (!httpLang.compare("russian"))
|
||||||
|
i2p::context.SetLanguage (eRussian);
|
||||||
|
else
|
||||||
|
i2p::context.SetLanguage (eEnglish);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,11 +32,6 @@
|
||||||
#include "ECIESX25519AEADRatchetSession.h"
|
#include "ECIESX25519AEADRatchetSession.h"
|
||||||
#include "I18N.h"
|
#include "I18N.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
#include <codecvt>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WIN32_APP
|
#ifdef WIN32_APP
|
||||||
#include "Win32App.h"
|
#include "Win32App.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -136,20 +131,6 @@ namespace http {
|
||||||
static std::string ConvertTime (uint64_t time);
|
static std::string ConvertTime (uint64_t time);
|
||||||
std::map<uint32_t, uint32_t> HTTPConnection::m_Tokens;
|
std::map<uint32_t, uint32_t> HTTPConnection::m_Tokens;
|
||||||
|
|
||||||
std::string DataPath;
|
|
||||||
|
|
||||||
static void SetDataDir ()
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
boost::filesystem::wpath path (i2p::fs::GetDataDir());
|
|
||||||
auto loc = boost::filesystem::path::imbue(std::locale( std::locale(), new std::codecvt_utf8_utf16<wchar_t>() ) );
|
|
||||||
i2p::http::DataPath = path.string();
|
|
||||||
boost::filesystem::path::imbue(loc); // Return it back
|
|
||||||
#else
|
|
||||||
i2p::http::DataPath = i2p::fs::GetDataDir();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ShowUptime (std::stringstream& s, int seconds)
|
static void ShowUptime (std::stringstream& s, int seconds)
|
||||||
{
|
{
|
||||||
int num;
|
int num;
|
||||||
|
@ -331,7 +312,7 @@ namespace http {
|
||||||
s << "<b>Transit:</b> ";
|
s << "<b>Transit:</b> ";
|
||||||
ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ());
|
ShowTraffic (s, i2p::transport::transports.GetTotalTransitTransmittedBytes ());
|
||||||
s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)<br>\r\n";
|
s << " (" << (double) i2p::transport::transports.GetTransitBandwidth () / 1024 << " KiB/s)<br>\r\n";
|
||||||
s << "<b>Data path:</b> " << i2p::http::DataPath << "<br>\r\n";
|
s << "<b>Data path:</b> " << i2p::fs::GetUTF8DataDir() << "<br>\r\n";
|
||||||
s << "<div class='slide'>";
|
s << "<div class='slide'>";
|
||||||
if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) {
|
if((outputFormat==OutputFormatEnum::forWebConsole)||!includeHiddenContent) {
|
||||||
s << "<label for=\"slide-info\">Hidden content. Press on text to see.</label>\r\n<input type=\"checkbox\" id=\"slide-info\" />\r\n<div class=\"slidecontent\">\r\n";
|
s << "<label for=\"slide-info\">Hidden content. Press on text to see.</label>\r\n<input type=\"checkbox\" id=\"slide-info\" />\r\n<div class=\"slidecontent\">\r\n";
|
||||||
|
@ -1390,8 +1371,6 @@ namespace http {
|
||||||
LogPrint(eLogInfo, "HTTPServer: password set to ", pass);
|
LogPrint(eLogInfo, "HTTPServer: password set to ", pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
i2p::http::SetDataDir();
|
|
||||||
|
|
||||||
m_IsRunning = true;
|
m_IsRunning = true;
|
||||||
m_Thread.reset (new std::thread (std::bind (&HTTPServer::Run, this)));
|
m_Thread.reset (new std::thread (std::bind (&HTTPServer::Run, this)));
|
||||||
m_Acceptor.listen ();
|
m_Acceptor.listen ();
|
||||||
|
|
56
i18n/English.cpp
Normal file
56
i18n/English.cpp
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Russian localization file
|
||||||
|
|
||||||
|
namespace i2p {
|
||||||
|
namespace i18n {
|
||||||
|
namespace english { // language
|
||||||
|
|
||||||
|
// See for language plural forms here:
|
||||||
|
// https://localization-guide.readthedocs.io/en/latest/l10n/pluralforms.html
|
||||||
|
int plural (int n) {
|
||||||
|
return n != 1 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::map<std::string, std::string> strings
|
||||||
|
{
|
||||||
|
{"Enabled", "Enabled"},
|
||||||
|
{"Disabled", "Disabled"}
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::map<std::string, std::vector<std::string>> plurals
|
||||||
|
{
|
||||||
|
{"days", {"day", "days"}},
|
||||||
|
{"hours", {"hour", "hours"}},
|
||||||
|
{"minutes", {"minute", "minutes"}},
|
||||||
|
{"seconds", {"second", "seconds"}}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string GetString (std::string arg)
|
||||||
|
{
|
||||||
|
auto it = strings.find(arg);
|
||||||
|
if (it == strings.end())
|
||||||
|
{
|
||||||
|
return arg;
|
||||||
|
} else {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetPlural (std::string arg, int n)
|
||||||
|
{
|
||||||
|
auto it = plurals.find(arg);
|
||||||
|
if (it == plurals.end())
|
||||||
|
{
|
||||||
|
return arg;
|
||||||
|
} else {
|
||||||
|
int form = plural(n);
|
||||||
|
return it->second[form];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // language
|
||||||
|
} // i18n
|
||||||
|
} // i2p
|
21
i18n/I18N.h
21
i18n/I18N.h
|
@ -9,9 +9,16 @@
|
||||||
#ifndef __I18N_H__
|
#ifndef __I18N_H__
|
||||||
#define __I18N_H__
|
#define __I18N_H__
|
||||||
|
|
||||||
|
#include "RouterContext.h"
|
||||||
|
|
||||||
namespace i2p {
|
namespace i2p {
|
||||||
namespace i18n {
|
namespace i18n {
|
||||||
|
|
||||||
|
namespace english {
|
||||||
|
std::string GetString (std::string arg);
|
||||||
|
std::string GetPlural (std::string arg, int n);
|
||||||
|
}
|
||||||
|
|
||||||
namespace russian {
|
namespace russian {
|
||||||
std::string GetString (std::string arg);
|
std::string GetString (std::string arg);
|
||||||
std::string GetPlural (std::string arg, int n);
|
std::string GetPlural (std::string arg, int n);
|
||||||
|
@ -19,13 +26,23 @@ namespace i18n {
|
||||||
|
|
||||||
std::string translate (std::string arg)
|
std::string translate (std::string arg)
|
||||||
{
|
{
|
||||||
return i2p::i18n::russian::GetString (arg);
|
switch (i2p::context.GetLanguage ())
|
||||||
|
{
|
||||||
|
case eEnglish: return i2p::i18n::english::GetString (arg);
|
||||||
|
case eRussian: return i2p::i18n::russian::GetString (arg);
|
||||||
|
default: return arg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename inttype>
|
template<typename inttype>
|
||||||
std::string translate (std::string arg, inttype&& n)
|
std::string translate (std::string arg, inttype&& n)
|
||||||
{
|
{
|
||||||
return i2p::i18n::russian::GetPlural (arg, (int) n);
|
switch (i2p::context.GetLanguage ())
|
||||||
|
{
|
||||||
|
case eEnglish: return i2p::i18n::english::GetPlural (arg, (int) n);
|
||||||
|
case eRussian: return i2p::i18n::russian::GetPlural (arg, (int) n);
|
||||||
|
default: return arg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // i18n
|
} // i18n
|
||||||
|
|
|
@ -93,6 +93,7 @@ namespace config {
|
||||||
("http.strictheaders", value<bool>()->default_value(true), "Enable strict host checking on WebUI")
|
("http.strictheaders", value<bool>()->default_value(true), "Enable strict host checking on WebUI")
|
||||||
("http.hostname", value<std::string>()->default_value("localhost"), "Expected hostname for WebUI")
|
("http.hostname", value<std::string>()->default_value("localhost"), "Expected hostname for WebUI")
|
||||||
("http.webroot", value<std::string>()->default_value("/"), "WebUI root path (default: / )")
|
("http.webroot", value<std::string>()->default_value("/"), "WebUI root path (default: / )")
|
||||||
|
("http.lang", value<std::string>()->default_value("english"), "WebUI language (default: english )")
|
||||||
;
|
;
|
||||||
|
|
||||||
options_description httpproxy("HTTP Proxy options");
|
options_description httpproxy("HTTP Proxy options");
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <codecvt>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
|
@ -41,6 +42,18 @@ namespace fs {
|
||||||
return dataDir;
|
return dataDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string GetUTF8DataDir () {
|
||||||
|
#ifdef _WIN32
|
||||||
|
boost::filesystem::wpath path (dataDir);
|
||||||
|
auto loc = boost::filesystem::path::imbue(std::locale( std::locale(), new std::codecvt_utf8_utf16<wchar_t>() ) ); // convert path to UTF-8
|
||||||
|
auto dataDirUTF8 = path.string();
|
||||||
|
boost::filesystem::path::imbue(loc); // Return locale settings back
|
||||||
|
return dataDirUTF8;
|
||||||
|
#else
|
||||||
|
return dataDir; // linux, osx, android uses UTF-8 by default
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void DetectDataDir(const std::string & cmdline_param, bool isService) {
|
void DetectDataDir(const std::string & cmdline_param, bool isService) {
|
||||||
if (cmdline_param != "") {
|
if (cmdline_param != "") {
|
||||||
dataDir = cmdline_param;
|
dataDir = cmdline_param;
|
||||||
|
|
|
@ -75,6 +75,9 @@ namespace fs {
|
||||||
/** @brief Returns datadir path */
|
/** @brief Returns datadir path */
|
||||||
const std::string & GetDataDir();
|
const std::string & GetDataDir();
|
||||||
|
|
||||||
|
/** @brief Returns datadir path in UTF-8 encoding */
|
||||||
|
const std::string GetUTF8DataDir();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set datadir either from cmdline option or using autodetection
|
* @brief Set datadir either from cmdline option or using autodetection
|
||||||
* @param cmdline_param Value of cmdline parameter --datadir=<something>
|
* @param cmdline_param Value of cmdline parameter --datadir=<something>
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace i2p
|
||||||
RouterContext::RouterContext ():
|
RouterContext::RouterContext ():
|
||||||
m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
|
m_LastUpdateTime (0), m_AcceptsTunnels (true), m_IsFloodfill (false),
|
||||||
m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown),
|
m_ShareRatio (100), m_Status (eRouterStatusUnknown), m_StatusV6 (eRouterStatusUnknown),
|
||||||
m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID)
|
m_Error (eRouterErrorNone), m_NetID (I2PD_NET_ID), m_Language (eEnglish)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -916,6 +916,11 @@ namespace i2p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RouterContext::SetLanguage (Lang language)
|
||||||
|
{
|
||||||
|
m_Language = language;
|
||||||
|
}
|
||||||
|
|
||||||
i2p::crypto::X25519Keys& RouterContext::GetStaticKeys ()
|
i2p::crypto::X25519Keys& RouterContext::GetStaticKeys ()
|
||||||
{
|
{
|
||||||
if (!m_StaticKeys)
|
if (!m_StaticKeys)
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace i2p
|
||||||
namespace garlic
|
namespace garlic
|
||||||
{
|
{
|
||||||
class RouterIncomingRatchetSession;
|
class RouterIncomingRatchetSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char ROUTER_INFO[] = "router.info";
|
const char ROUTER_INFO[] = "router.info";
|
||||||
const char ROUTER_KEYS[] = "router.keys";
|
const char ROUTER_KEYS[] = "router.keys";
|
||||||
|
@ -39,7 +39,7 @@ namespace garlic
|
||||||
eRouterStatusError = 3,
|
eRouterStatusError = 3,
|
||||||
eRouterStatusUnknown = 4,
|
eRouterStatusUnknown = 4,
|
||||||
eRouterStatusProxy = 5,
|
eRouterStatusProxy = 5,
|
||||||
eRouterStatusMesh = 6
|
eRouterStatusMesh = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RouterError
|
enum RouterError
|
||||||
|
@ -49,7 +49,12 @@ namespace garlic
|
||||||
eRouterErrorOffline = 2,
|
eRouterErrorOffline = 2,
|
||||||
eRouterErrorSymmetricNAT = 3
|
eRouterErrorSymmetricNAT = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Lang {
|
||||||
|
eEnglish = 0,
|
||||||
|
eRussian
|
||||||
|
};
|
||||||
|
|
||||||
class RouterContext: public i2p::garlic::GarlicDestination
|
class RouterContext: public i2p::garlic::GarlicDestination
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -144,6 +149,10 @@ namespace garlic
|
||||||
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
void ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
void ProcessDeliveryStatusMessage (std::shared_ptr<I2NPMessage> msg);
|
||||||
|
|
||||||
|
// i18n
|
||||||
|
Lang GetLanguage () const { return m_Language; };
|
||||||
|
void SetLanguage (Lang language);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// implements GarlicDestination
|
// implements GarlicDestination
|
||||||
|
@ -178,6 +187,9 @@ namespace garlic
|
||||||
std::unique_ptr<i2p::crypto::X25519Keys> m_StaticKeys;
|
std::unique_ptr<i2p::crypto::X25519Keys> m_StaticKeys;
|
||||||
// for ECIESx25519
|
// for ECIESx25519
|
||||||
std::unique_ptr<i2p::crypto::NoiseSymmetricState> m_InitialNoiseState, m_CurrentNoiseState;
|
std::unique_ptr<i2p::crypto::NoiseSymmetricState> m_InitialNoiseState, m_CurrentNoiseState;
|
||||||
|
|
||||||
|
// i18n
|
||||||
|
Lang m_Language;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RouterContext context;
|
extern RouterContext context;
|
||||||
|
|
Loading…
Reference in a new issue