mirror of
https://github.com/Syping/dtranslatebot.git
synced 2024-11-22 13:50:22 +01:00
cache available languages and make translator shared
This commit is contained in:
parent
0e369f5a1d
commit
b1329aa961
8 changed files with 69 additions and 52 deletions
|
@ -220,23 +220,24 @@ void process_url(const std::string &url, translator &translator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool process_translator_settings(const dpp::json &json, translator &translator)
|
bool process_translator_settings(const dpp::json &json, std::shared_ptr<bot::translator::translator> &translator_instance)
|
||||||
{
|
{
|
||||||
if (!json.is_object()) {
|
if (!json.is_object()) {
|
||||||
std::cerr << "[Error] Value translator needs to be a object" << std::endl;
|
std::cerr << "[Error] Value translator needs to be a object" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string translator_type = "libretranslate";
|
bot::settings::translator translator;
|
||||||
auto json_translator_type = json.find("type");
|
auto json_translator_type = json.find("type");
|
||||||
if (json_translator_type != json.end()) {
|
if (json_translator_type != json.end()) {
|
||||||
translator_type = *json_translator_type;
|
translator.type = *json_translator_type;
|
||||||
std::transform(translator_type.begin(), translator_type.end(), translator_type.begin(), ::tolower);
|
std::transform(translator.type.begin(), translator.type.end(), translator.type.begin(), ::tolower);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
translator.type = "libretranslate";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (translator_type == "deepl") {
|
if (translator.type == "deepl") {
|
||||||
translator.type = TRANSLATOR_DEEPL;
|
|
||||||
|
|
||||||
auto json_deepl_hostname = json.find("hostname");
|
auto json_deepl_hostname = json.find("hostname");
|
||||||
if (json_deepl_hostname != json.end())
|
if (json_deepl_hostname != json.end())
|
||||||
translator.hostname = *json_deepl_hostname;
|
translator.hostname = *json_deepl_hostname;
|
||||||
|
@ -249,10 +250,10 @@ bool process_translator_settings(const dpp::json &json, translator &translator)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
translator.apiKey = *json_deepl_apiKey;
|
translator.apiKey = *json_deepl_apiKey;
|
||||||
}
|
|
||||||
else if (translator_type == "libretranslate") {
|
|
||||||
translator.type = TRANSLATOR_LIBRETRANSLATE;
|
|
||||||
|
|
||||||
|
translator_instance = std::make_shared<bot::translator::deepl>(translator.hostname, translator.apiKey);
|
||||||
|
}
|
||||||
|
else if (translator.type == "libretranslate") {
|
||||||
auto json_lt_hostname = json.find("hostname");
|
auto json_lt_hostname = json.find("hostname");
|
||||||
if (json_lt_hostname != json.end())
|
if (json_lt_hostname != json.end())
|
||||||
translator.hostname = *json_lt_hostname;
|
translator.hostname = *json_lt_hostname;
|
||||||
|
@ -288,9 +289,11 @@ bool process_translator_settings(const dpp::json &json, translator &translator)
|
||||||
translator.apiKey = *json_lt_apiKey;
|
translator.apiKey = *json_lt_apiKey;
|
||||||
else
|
else
|
||||||
translator.apiKey.clear();
|
translator.apiKey.clear();
|
||||||
|
|
||||||
|
translator_instance = std::make_shared<bot::translator::libretranslate>(translator.hostname, translator.port, translator.url, translator.tls, translator.apiKey);
|
||||||
}
|
}
|
||||||
else if (translator_type == "stub") {
|
else if (translator.type == "stub") {
|
||||||
translator.type = TRANSLATOR_STUB;
|
translator_instance = std::make_shared<bot::translator::stub>();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cerr << "[Error] Translator " << translator.type << " is unknown" << std::endl;
|
std::cerr << "[Error] Translator " << translator.type << " is unknown" << std::endl;
|
||||||
|
@ -471,20 +474,10 @@ std::shared_ptr<bot::database::database> settings::get_database() const
|
||||||
return m_database;
|
return m_database;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<bot::translator::translator> settings::get_translator() const
|
std::shared_ptr<bot::translator::translator> settings::get_translator() const
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
const std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
||||||
|
return m_translator;
|
||||||
switch (m_translator.type) {
|
|
||||||
case TRANSLATOR_DEEPL:
|
|
||||||
return std::make_unique<bot::translator::deepl>(m_translator.hostname, m_translator.apiKey);
|
|
||||||
case TRANSLATOR_LIBRETRANSLATE:
|
|
||||||
return std::make_unique<bot::translator::libretranslate>(m_translator.hostname, m_translator.port, m_translator.url, m_translator.tls, m_translator.apiKey);
|
|
||||||
case TRANSLATOR_STUB:
|
|
||||||
return std::make_unique<bot::translator::stub>();
|
|
||||||
default:
|
|
||||||
return std::make_unique<bot::translator::translator>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string settings::token() const
|
const std::string settings::token() const
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace bot {
|
||||||
static const target* get_target(const channel *channel, const std::string &target);
|
static const target* get_target(const channel *channel, const std::string &target);
|
||||||
const std::vector<std::string> preferred_languages() const;
|
const std::vector<std::string> preferred_languages() const;
|
||||||
std::shared_ptr<bot::database::database> get_database() const;
|
std::shared_ptr<bot::database::database> get_database() const;
|
||||||
std::unique_ptr<bot::translator::translator> get_translator() const;
|
std::shared_ptr<bot::translator::translator> get_translator() const;
|
||||||
const std::string token() const;
|
const std::string token() const;
|
||||||
|
|
||||||
/* is functions */
|
/* is functions */
|
||||||
|
@ -73,7 +73,7 @@ namespace bot {
|
||||||
std::shared_ptr<bot::database::database> m_database;
|
std::shared_ptr<bot::database::database> m_database;
|
||||||
std::vector<guild> m_guilds;
|
std::vector<guild> m_guilds;
|
||||||
std::vector<std::string> m_prefLangs;
|
std::vector<std::string> m_prefLangs;
|
||||||
bot::settings::translator m_translator;
|
std::shared_ptr<bot::translator::translator> m_translator;
|
||||||
std::string m_token;
|
std::string m_token;
|
||||||
std::vector<dpp::snowflake> m_webhookIds;
|
std::vector<dpp::snowflake> m_webhookIds;
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,13 +40,8 @@ namespace bot {
|
||||||
dpp::snowflake id;
|
dpp::snowflake id;
|
||||||
std::vector<bot::settings::channel> channel;
|
std::vector<bot::settings::channel> channel;
|
||||||
};
|
};
|
||||||
enum translator_type {
|
|
||||||
TRANSLATOR_DEEPL,
|
|
||||||
TRANSLATOR_LIBRETRANSLATE,
|
|
||||||
TRANSLATOR_STUB
|
|
||||||
};
|
|
||||||
struct translator {
|
struct translator {
|
||||||
translator_type type;
|
std::string type;
|
||||||
std::string hostname;
|
std::string hostname;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
std::string url;
|
std::string url;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#ifndef TRANSLATOR_H
|
#ifndef TRANSLATOR_H
|
||||||
#define TRANSLATOR_H
|
#define TRANSLATOR_H
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -29,6 +30,11 @@ namespace bot {
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct supported_languages {
|
||||||
|
std::vector<language> languages;
|
||||||
|
std::chrono::system_clock::time_point query_time;
|
||||||
|
};
|
||||||
|
|
||||||
class translator {
|
class translator {
|
||||||
public:
|
public:
|
||||||
explicit translator() = default;
|
explicit translator() = default;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <dpp/httpsclient.h>
|
#include <dpp/httpsclient.h>
|
||||||
#include "deepl.h"
|
#include "deepl.h"
|
||||||
using namespace bot::translator;
|
using namespace bot::translator;
|
||||||
|
using namespace std::chrono_literals;
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
|
||||||
deepl::deepl(const std::string &hostname, const std::string apiKey) :
|
deepl::deepl(const std::string &hostname, const std::string apiKey) :
|
||||||
|
@ -33,31 +34,41 @@ deepl::~deepl()
|
||||||
|
|
||||||
const std::vector<language> deepl::get_languages()
|
const std::vector<language> deepl::get_languages()
|
||||||
{
|
{
|
||||||
std::vector<language> languages;
|
if (!m_languages.languages.empty()) {
|
||||||
|
auto current_time = std::chrono::system_clock::now();
|
||||||
|
auto threshold_time = m_languages.query_time + 24h;
|
||||||
|
if (current_time <= threshold_time)
|
||||||
|
return m_languages.languages;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dpp::https_client http_request(m_hostname, 443, "/v2/languages?type=target", "GET", {}, { {"Authorization"s, "DeepL-Auth-Key " + m_apiKey} }, false);
|
dpp::https_client http_request(m_hostname, 443, "/v2/languages?type=target", "GET", {}, { {"Authorization"s, "DeepL-Auth-Key " + m_apiKey} }, false);
|
||||||
if (http_request.get_status() == 200) {
|
if (http_request.get_status() == 200) {
|
||||||
const dpp::json response = dpp::json::parse(http_request.get_content());
|
const dpp::json response = dpp::json::parse(http_request.get_content());
|
||||||
if (response.is_array()) {
|
if (response.is_array()) {
|
||||||
for (const auto &json_language : response) {
|
m_languages.languages.clear();
|
||||||
if (json_language.is_object()) {
|
for (auto json_language = response.begin(); json_language != response.end(); json_language++) {
|
||||||
|
if (json_language->is_object()) {
|
||||||
language language;
|
language language;
|
||||||
|
|
||||||
auto json_lang_code = json_language.find("language");
|
auto json_lang_code = json_language->find("language");
|
||||||
if (json_lang_code != json_language.end())
|
if (json_lang_code != json_language->end())
|
||||||
language.code = *json_lang_code;
|
language.code = *json_lang_code;
|
||||||
|
|
||||||
std::transform(language.code.begin(), language.code.end(), language.code.begin(), ::tolower);
|
if (language.code.size() > 2)
|
||||||
|
std::transform(language.code.begin(), language.code.begin() + 2, language.code.begin(), ::tolower);
|
||||||
|
else
|
||||||
|
std::transform(language.code.begin(), language.code.end(), language.code.begin(), ::tolower);
|
||||||
|
|
||||||
auto json_lang_name = json_language.find("name");
|
auto json_lang_name = json_language->find("name");
|
||||||
if (json_lang_name != json_language.end())
|
if (json_lang_name != json_language->end())
|
||||||
language.name = *json_lang_name;
|
language.name = *json_lang_name;
|
||||||
|
|
||||||
if (!language.code.empty() && !language.name.empty())
|
if (!language.code.empty() && !language.name.empty())
|
||||||
languages.push_back(std::move(language));
|
m_languages.languages.push_back(std::move(language));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_languages.query_time = std::chrono::system_clock::now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,18 +76,19 @@ const std::vector<language> deepl::get_languages()
|
||||||
std::cerr << "[Exception] " << exception.what() << std::endl;
|
std::cerr << "[Exception] " << exception.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return languages;
|
return m_languages.languages;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string deepl::translate(const std::string &text, const std::string &source, const std::string &target)
|
const std::string deepl::translate(const std::string &text, const std::string &source, const std::string &target)
|
||||||
{
|
{
|
||||||
const dpp::http_headers http_headers = {
|
const dpp::http_headers http_headers = {
|
||||||
{"Authorization"s, "DeepL-Auth-Key "s + m_apiKey},
|
{"Authorization"s, "DeepL-Auth-Key " + m_apiKey},
|
||||||
{"Content-Type"s, "application/json"s}
|
{"Content-Type"s, "application/json"s}
|
||||||
};
|
};
|
||||||
|
|
||||||
dpp::json json_body = {
|
dpp::json json_body = {
|
||||||
{"text"s, { text } },
|
{"text"s, { text } },
|
||||||
|
{"source_lang"s, source},
|
||||||
{"target_lang"s, target},
|
{"target_lang"s, target},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace bot {
|
||||||
private:
|
private:
|
||||||
std::string m_apiKey;
|
std::string m_apiKey;
|
||||||
std::string m_hostname;
|
std::string m_hostname;
|
||||||
|
supported_languages m_languages;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <dpp/httpsclient.h>
|
#include <dpp/httpsclient.h>
|
||||||
#include "libretranslate.h"
|
#include "libretranslate.h"
|
||||||
using namespace bot::translator;
|
using namespace bot::translator;
|
||||||
|
using namespace std::chrono_literals;
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
|
||||||
libretranslate::libretranslate(const std::string &hostname, uint16_t port, const std::string &url, bool tls, const std::string apiKey) :
|
libretranslate::libretranslate(const std::string &hostname, uint16_t port, const std::string &url, bool tls, const std::string apiKey) :
|
||||||
|
@ -33,29 +34,36 @@ libretranslate::~libretranslate()
|
||||||
|
|
||||||
const std::vector<language> libretranslate::get_languages()
|
const std::vector<language> libretranslate::get_languages()
|
||||||
{
|
{
|
||||||
std::vector<language> languages;
|
if (!m_languages.languages.empty()) {
|
||||||
|
auto current_time = std::chrono::system_clock::now();
|
||||||
|
auto threshold_time = m_languages.query_time + 24h;
|
||||||
|
if (current_time <= threshold_time)
|
||||||
|
return m_languages.languages;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dpp::https_client http_request(m_hostname, m_port, m_url + "languages", "GET", {}, {}, !m_tls);
|
dpp::https_client http_request(m_hostname, m_port, m_url + "languages", "GET", {}, {}, !m_tls);
|
||||||
if (http_request.get_status() == 200) {
|
if (http_request.get_status() == 200) {
|
||||||
const dpp::json response = dpp::json::parse(http_request.get_content());
|
const dpp::json response = dpp::json::parse(http_request.get_content());
|
||||||
if (response.is_array()) {
|
if (response.is_array()) {
|
||||||
for (const auto &json_language : response) {
|
m_languages.languages.clear();
|
||||||
if (json_language.is_object()) {
|
for (auto json_language = response.begin(); json_language != response.end(); json_language++) {
|
||||||
|
if (json_language->is_object()) {
|
||||||
language language;
|
language language;
|
||||||
|
|
||||||
auto json_lang_code = json_language.find("code");
|
auto json_lang_code = json_language->find("code");
|
||||||
if (json_lang_code != json_language.end())
|
if (json_lang_code != json_language->end())
|
||||||
language.code = *json_lang_code;
|
language.code = *json_lang_code;
|
||||||
|
|
||||||
auto json_lang_name = json_language.find("name");
|
auto json_lang_name = json_language->find("name");
|
||||||
if (json_lang_name != json_language.end())
|
if (json_lang_name != json_language->end())
|
||||||
language.name = *json_lang_name;
|
language.name = *json_lang_name;
|
||||||
|
|
||||||
if (!language.code.empty() && !language.name.empty())
|
if (!language.code.empty() && !language.name.empty())
|
||||||
languages.push_back(std::move(language));
|
m_languages.languages.push_back(std::move(language));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_languages.query_time = std::chrono::system_clock::now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +71,7 @@ const std::vector<language> libretranslate::get_languages()
|
||||||
std::cerr << "[Exception] " << exception.what() << std::endl;
|
std::cerr << "[Exception] " << exception.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return languages;
|
return m_languages.languages;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string libretranslate::translate(const std::string &text, const std::string &source, const std::string &target)
|
const std::string libretranslate::translate(const std::string &text, const std::string &source, const std::string &target)
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
namespace bot {
|
namespace bot {
|
||||||
namespace translator {
|
namespace translator {
|
||||||
class libretranslate : public translator {
|
class libretranslate : public translator {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit libretranslate(const std::string &hostname, uint16_t port, const std::string &url, bool tls, const std::string apiKey = {});
|
explicit libretranslate(const std::string &hostname, uint16_t port, const std::string &url, bool tls, const std::string apiKey = {});
|
||||||
~libretranslate() override;
|
~libretranslate() override;
|
||||||
|
@ -34,6 +35,7 @@ namespace bot {
|
||||||
private:
|
private:
|
||||||
std::string m_apiKey;
|
std::string m_apiKey;
|
||||||
std::string m_hostname;
|
std::string m_hostname;
|
||||||
|
supported_languages m_languages;
|
||||||
uint16_t m_port;
|
uint16_t m_port;
|
||||||
std::string m_url;
|
std::string m_url;
|
||||||
bool m_tls;
|
bool m_tls;
|
||||||
|
|
Loading…
Reference in a new issue